JavaScript
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
function writeString(view, offset, string){
for (var i = 0; i < string.length; i++){
view.setUint8(offset + i, string.charCodeAt(i));
}
}
function floatTo16BitPCM(output, offset, input){
for (var i = 0; i < input.length; i++, offset+=2){
var s = Math.max(-1, Math.min(1, input[i]));
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
}
}
function encodeWAV(samples, sampleRate){
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer);
writeString(view, 0, 'RIFF');
view.setUint32(4, 32 + samples.length * 2, true);
writeString(view, 8, 'WAVE');
writeString(view, 12, 'fmt ');
view.setUint32(16, 16, true);
view.setUint16(20, 1, true);
view.setUint16(22, 2, true);
view.setUint32(24, sampleRate, true);
view.setUint32(28, sampleRate * 4, true);
view.setUint16(32, 4, true);
view.setUint16(34, 16, true);
writeString(view, 36, 'data');
view.setUint32(40, samples.length * 2, true);
floatTo16BitPCM(view, 44, samples);
return view;
}
var FREQUENCIES = {
"C0": 16.35,
"C#0": 17.32,
"Db0": 17.32,
"D0": 18.35,
"D#0": 19.45,
"Eb0": 19.45,
"E0": 20.60,
"F0": 21.83,
"F#0": 23.12,
"Gb0": 23.12,
"G0": 24.50,
"G#0": 25.96,
"Ab0": 25.96,
"A0": 27.50,
"A#0": 29.14,
"Bb0": 29.14,
"B0": 30.87,
"C1": 32.70,
"C#1": 34.65,
"Db1": 34.65,
"D1": 36.71,
"D#1": 38.89,
"Eb1": 38.89,
"E1": 41.20,
"F1": 43.65,
"F#1": 46.25,
"Gb1": 46.25,
"G1": 49.00,
"G#1": 51.91,
"Ab1": 51.91,
"A1": 55.00,
"A#1": 58.27,
"Bb1": 58.27,
"B1": 61.74,
"C2": 65.41,
"C#2": 69.30,
"Db2": 69.30,
"D2": 73.42,
"D#2": 77.78,
"Eb2": 77.78,
"E2": 82.41,
"F2": 87.31,
"F#2": 92.50,
"Gb2": 92.50,
"G2": 98.00,
"G#2": 103.83,
"Ab2": 103.83,
"A2": 110.00,
"A#2": 116.54,
"Bb2": 116.54,
"B2": 123.47,
"C3": 130.81,
"C#3": 138.59,
"Db3": 138.59,
"D3": 146.83,
"D#3": 155.56,
"Eb3": 155.56,
"E3": 164.81,
"F3":...