Created
July 12, 2014 19:01
-
-
Save MikaAK/b8dd452959c487d7567b to your computer and use it in GitHub Desktop.
Sounds and conversions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Built from Mohit Cheppudira's sine wave generator - http://0xfe.blogspot.com | |
// Modified by Murat Ayfer - http://muratayfer.com | |
// Modified by Mika Kalathil | |
var ON = 450; | |
var OFF = 550; | |
var soundWave = function(context) { | |
// xs is a list of x (time) values, one per wave. | |
// time is not represented as synchronized clicks or milliseconds, its passing is freq dependent | |
// so that's why we keep a value per each wave. | |
this.frequency = 800; | |
this.nextFrequency = 0 | |
this.xs = []; | |
this.counter = 0; | |
this.fadeout_counter = 0; | |
this.context = context; | |
this.sampleRate = this.context.sampleRate; // 44100 by default | |
this.sampleRateMillisecond = this.sampleRate / 1000; | |
this.node = context.createJavaScriptNode(1024, 1, 2) | |
var self = this; | |
this.node.onaudioprocess = function(e) { self.process(e) }; | |
} | |
soundWave.prototype.process = function(e) { | |
// Get a reference to the output buffer and fill it up. | |
var channels = [ e.outputBuffer.getChannelData(0), e.outputBuffer.getChannelData(1) ]; | |
var data = e.outputBuffer.getChannelData(0); | |
var buffer_size = channels[0].length; | |
var num_channels = channels.length; | |
var amplitude = 0; | |
for (var i = 0; i < buffer_size; i++) { | |
y = Math.sin((this.counter) * Math.PI * 2 * this.frequency / this.sampleRate) | |
if(amplitude = 0) { | |
amplitude = 1; | |
} else { | |
amplitude = 0; | |
} | |
for(var k = 0; k < num_channels; k++) { | |
channels[k][i] = y; | |
} | |
this.counter += 1; | |
} | |
if(!this.playing) { | |
// fadeout to prevent popping during a pause/stop | |
var fadeout_length = 2; | |
this.frequency = 18000 | |
amplitude -= amplitude * (this.fadeout_counter++/fadeout_length) | |
if(this.fadeout_counter >= fadeout_length) { | |
this.fadeout_counter = 0; | |
this.node.disconnect(this.context.destination); | |
} | |
} | |
// Frequency shift normalization | |
if (this.nextFrequency != this.frequency) { | |
// Figure out what the next point is. | |
var nextData = this.amplitude * Math.sin( | |
this.x / (this.sampleRate / (this.frequency * 2 * Math.PI))); | |
debugger | |
// If the current point approximates 0, and the direction is positive, | |
// switch frequencies. | |
if (data[i] < 0.001 && data[i] > -0.001 && data[i] < nextData) { | |
this.frequency = this.nextFrequency; | |
this.x = 0; | |
} | |
} | |
} | |
soundWave.prototype.play = function() { | |
this.node.connect(this.context.destination) | |
this.playing = true | |
} | |
soundWave.prototype.stop = function() { | |
this.playing = false | |
} | |
soundWave.prototype.changeFrequency = function(value) { | |
this.nextFrequency = value | |
} | |
var BinaryConversion = { | |
toString: function(binary) { | |
return binary.replace(/\s*[01]{8}\s*/g, function(binary) { | |
return String.fromCharCode(parseInt(binary, 2)) | |
}) | |
}, | |
toBinary: function(string, spaceSeparatedOctets) { | |
return string.replace(/[\s\S]/g, function(string) { | |
string = BinaryConversion.removeSpaces(string.charCodeAt().toString(2)) | |
return !1 == spaceSeparatedOctets ? string : string + " " | |
}) | |
}, | |
removeSpaces: function(number) { | |
return "00000000".slice(String(number).length) + number | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment