Created
September 3, 2010 02:56
-
-
Save jonbro/563338 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
<script type="text/javascript"> | |
function clone(obj) { | |
// A clone of an object is an empty object with a prototype reference to the original. | |
// As such, you can access the current properties of the original through the clone. | |
// If you set a clone's property, it will override the orignal's property, and | |
// not affect the orignal. You can use the delete operator on the clone's overridden | |
// property to return to the earlier lookup behavior. | |
function Clone() { } // a private constructor, used only by this one clone. | |
Clone.prototype = obj; | |
var c = new Clone(); | |
c.constructor = Clone; | |
return c; | |
} | |
var lerp = function(start, target, amt){ | |
return start + (target-start) * amt; | |
}; | |
var synth = { | |
start: 0, | |
ampEnv: [[400, 1],[20, 0]], | |
ampEnvStep: 0, | |
ampEnvAmt: 0, | |
lastAmp: 0, | |
freq: 0, | |
audioRequest: function(count){ | |
//sample = dx.algo14(count); | |
sample = Math.sin( count * this.freq ); // tone | |
if(this.ampEnvStep < this.ampEnv.length){ | |
if ((1+count-this.start)/audioRate*this.ampEnv[this.ampEnvStep][0] > 1) { | |
this.lastAmp = this.ampEnvAmt; | |
this.ampEnvStep++; | |
this.start = count; | |
}else{ | |
this.ampEnvAmt = lerp(this.lastAmp, this.ampEnv[this.ampEnvStep][1], (1+count-this.start)/audioRate*this.ampEnv[this.ampEnvStep][0]); | |
} | |
} | |
sample *= this.ampEnvAmt;// vol | |
return sample; | |
}, | |
trigger: function(count, pitch, volume){ | |
this.start = count; | |
this.lastAmp = volume; | |
this.ampEnvStep = 0; | |
this.freq = 440.0*Math.pow(2.0, (pitch-60)/12); | |
this.freq *= 2*Math.PI/audioRate; | |
dx.rf = this.freq; | |
} | |
}; | |
var m = Math; | |
var dx = { | |
f: [1,0.5,0.5,0.5,0,0], | |
g: function(c,f){ | |
return this.f[f]*this.rf*c; | |
}, | |
rf: 0, | |
algo14: function(c){ | |
return m.sin(m.sin(this.g(c, 1))*this.g(c, 0))+m.sin(m.sin((m.sin(this.g(c, 4)+m.sin(this.g(c, 5)*m.sin(this.g(c, 5)))))*this.g(c, 3))*this.g(c, 2)); | |
} | |
} | |
// Create an Audio interface | |
var output = new Audio(); | |
var audioRate = 44100.0; | |
// Set up a mono channel at 44.1Khz | |
output.mozSetup( 1, audioRate ); | |
// samples/second * 120/1 * 60/1 | |
var beatLength = 60*audioRate/(120.0*16); | |
var beat = 0; | |
var triggers1 = [ | |
[1, 36], [1, 36], [1, 36], [0], | |
[1, 36], [0], [1, 36], [0], | |
[1, 36], [0], [1, 36], [0], | |
[1, 36], [0], [1, 36], [1, 36], | |
[1, 36], [0], [1, 36], [0], | |
[1, 36], [0], [1, 36], [0], | |
[1, 36], [1, 36], [0], [1, 36], | |
[1, 36], [1, 36], [1, 36], [1, 36] | |
]; | |
var triggers2 = [ | |
[0], [1, 56], [0], [1, 56], | |
[0], [1, 56], [0], [1, 56], | |
[0], [1, 56], [0], [1, 56], | |
[1, 56], [1, 53], [1, 51], [1, 50] | |
]; | |
synth2 = clone(synth); | |
synth2.ampEnv = [[2, 1],[500, 0]]; | |
// Create a sample buffer array | |
//num triggers, trigger size | |
var samples; | |
function writeLong(){ | |
samples = new Float32Array( Math.ceil(32 * 16 * beatLength) ); | |
for(var i=0, l=samples.length; i<l; i++){ | |
remainder = i%beatLength; | |
if(remainder == 0){ | |
if (triggers1[beat%triggers1.length][0] == 1) { | |
synth.trigger(i, triggers1[beat%triggers1.length][1], 0); | |
}; | |
if (triggers2[beat%triggers2.length][0] == 1) { | |
synth2.trigger(i, triggers2[beat%triggers2.length][1], 0); | |
}; | |
beat++; | |
} | |
samples[i] = synth.audioRequest(i)+synth2.audioRequest(i)*0.45; | |
} | |
return samples; | |
} | |
function writeShort(){ | |
samples = new Float32Array( Math.ceil(beatLength*30) ); | |
synth.ampEnv = [[2, 1],[500, 0]]; | |
synth.trigger(0, 36, 0); | |
for(var i=0, l=samples.length; i<l; i++){ | |
samples[i] = synth.audioRequest(i); | |
} | |
return samples; | |
} | |
</script> | |
<button onclick="output.mozWriteAudio( writeLong() );">Play</button> | |
<button onclick="output.mozWriteAudio( writeShort() );">Play Short</button> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment