-
-
Save MikaAK/1da6c7cf4e9fa2401f09 to your computer and use it in GitHub Desktop.
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 = 0; | |
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 fadeoutLength = 2; | |
this.frequency = 18800 | |
amplitude -= amplitude * (this.fadeoutCounter++/fadeoutLength) | |
if(this.fadeout_counter >= fadeoutLength) { | |
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))); | |
// 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