JavaScriptで音を鳴らしてみよう
id:Voluntasのおかげで自分的に再燃したブックマークレット熱。まあブックマークレットというと実用的な感があるけど、まったくそんなことはなく、要はワンライナーのこと。
いろいろ作ってみた中で、ちょっと汎用化できそうなものがあったので若干体裁を整えてみたのがこれ。仕組みは単純で、16KHz 8bitのwavファイルをオンザフライで生成して、それをdata:スキーム化した上で隠しiframeのsrcに突っ込んでいるだけ。なので、ブラウザ側にaudio/wavを再生できて、しかも自動再生してくれるプラグインが必須というところに注意。
追記1: undefinedとNaNの扱いでバグがあったので修正。
追記2: generateして余った分を切り取るspliceで符号が逆になっていたのを修正。ほんとすみません。
var SoundPlayer = { HEADER: "WAVEfmt\x20\x10\x00\x00\x00\x01\x00\x01\x00\x80\x3e\x00\x00\x80\x3e\x00\x00\x01\x00\x08\x00data", packToUInt32LE: function(l) { var f = String.fromCharCode; return f(l & 255) + f((l >> 8) & 255) + f((l >> 16) & 255) + f((l >> 24) & 255); }, packToBytes: function(a, len) { var tmp = new Array(len); for (var i = len; --i >= 0;) { var v = 0; for (var j = a.length, d; --j >= 0;) d = a[j][i] + 0, v = Math.max(v, isNaN(d) ? 0: d); tmp[i] = String.fromCharCode(v); } return tmp.join(''); }, generateWavURI: function(a) { var len = 0; for (var i = a.length; --i >= 0;) len = Math.max(len, a[i].length); return "data:audio/wav," + escape( "RIFF" + this.packToUInt32LE(len + this.HEADER.length + 4) + this.HEADER + this.packToUInt32LE(len) + this.packToBytes(a, len)); }, play: function() { var n = document.createElement('iframe'); n.style.visibility = "hidden"; n.setAttribute("src", this.generateWavURI(arguments)); document.body.appendChild(n); } }; var SoundGenerator = function() { this.initialize.apply(this, arguments); }; SoundGenerator.prototype = { initialize: function() { this.data = []; this.volume = 0xcf; this.duty = 0.5; this.waveForm = false; this.envelopeGenerator = function(t) { return Math.max((9000 - t) / 9000, 0); }; }, generatePulseWave: function(pitch, duration) { var on, off; on = Math.max(Math.floor(pitch * this.duty), 1); off = pitch - on; var t = 0, d = this.data, v = this.volume, eg = this.envelopeGenerator; while (t < duration) { for (var j = on; (j -= 32) > 0; ) { d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); } j += 32; switch (j) { case 0: break; case 1: d.push(v * eg(t++)); break; case 2: d.push(v * eg(t++), v * eg(t++)); break; case 3: d.push(v * eg(t++), v * eg(t++), v * eg(t++)); break; case 4: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 5: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 6: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 7: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 8: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 9: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 10: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 11: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 12: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 13: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 14: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 15: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 16: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 17: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 18: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 19: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 20: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 21: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 22: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 23: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 24: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 25: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 26: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 27: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 28: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 29: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 30: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; case 31: d.push(v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++), v * eg(t++)); break; } for (var j = off; (j -= 32) > 0; ) { d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); } j += 32; switch (j) { case 0: break; case 1: d.push(0x00); break; case 2: d.push(0x00, 0x00); break; case 3: d.push(0x00, 0x00, 0x00); break; case 4: d.push(0x00, 0x00, 0x00, 0x00); break; case 5: d.push(0x00, 0x00, 0x00, 0x00, 0x00); break; case 6: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 7: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 8: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 9: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 10: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 11: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 12: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 13: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 14: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 15: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 16: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 17: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 18: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 19: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 20: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 21: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 22: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 23: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 24: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 25: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 26: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 27: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 28: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 29: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 30: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; case 31: d.push(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); break; } t += off; } var j = t - duration; d.splice(d.length - j, j); }, generateSawWave: function(pitch, duration) { var t = 0, d = this.data, vol = this.volume, eg = this.envelopeGenerator, v = function() { return vol * (t % pitch) * eg(t++) / pitch; }; while (t < duration) { for (var j = pitch; (j -= 32) > 0; ) { d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); } j += 32; switch (j) { case 0: break; case 1: d.push(v()); break; case 2: d.push(v(), v()); break; case 3: d.push(v(), v(), v()); break; case 4: d.push(v(), v(), v(), v()); break; case 5: d.push(v(), v(), v(), v(), v()); break; case 6: d.push(v(), v(), v(), v(), v(), v()); break; case 7: d.push(v(), v(), v(), v(), v(), v(), v()); break; case 8: d.push(v(), v(), v(), v(), v(), v(), v(), v()); break; case 9: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 10: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 11: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 12: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 13: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 14: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 15: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 16: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 17: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 18: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 19: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 20: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 21: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 22: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 23: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 24: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 25: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 26: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 27: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 28: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 29: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 30: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; case 31: d.push(v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v(), v()); break; } } var j = t - duration; d.splice(d.length - j, j); } };
使い方は、
1. SoundGeneratorクラスをインスタンス化し、音量やエンベロープジェネレータを設定する。
var sg = new SoundGenerator(); sg.volume = 100; sg.envelopeGenerator = function(t) { return Math.min(t, 1000) / 1000; }
2. generatePulseWave() もしくは generateSawWave() で音を合成する。
// 第1引数は音の高低 (周波数=16000 / n) で、第2引数は持続時間 (サンプル数)
sg.generatePulseWave(28, 3000);
3. SoundPlayerクラスの静的メソッドplay()で音を出す。
SoundPlayer.play(sg.data);
サンプルコード:
<html> <head> <script type="text/javascript" src="sound.js"></script> <script type="text/javascript"> window.onload = function() { var sg1 = new SoundGenerator(); sg1.generatePulseWave(15, 50000); var sg2 = new SoundGenerator(); sg2.generatePulseWave(20, 50000); SoundPlayer.play(sg1.data, sg2.data); }; </script> </head> <body> </body> </html>