WebAudioで適当に何か鳴らす


WebAudioそこそこ良い感じになってきたのでメモ。あと入用で。
リアルタイムで自前で波形生成して突っ込むのを実験。なるべく小さく書いてみた。
当初もっと小さく書けたけど分かりやすさ重視。
buffer_sizeを大きくするとレイテンシがしょぼくなる。

xe.jp
<script>

var buffer_size  = 16384; //power 2
var divide       = 10;
var finetune     = 512.0;
var gain         = 0.01;
var cutoff       = 1000; //hz

//https://www.youtube.com/watch?v=oFXMxIvZeMk
var score =
[
    0, 12, 11 - 0, 12, 16, 12, 11 - 0, 12,
    0, 12, 11 - 1, 12, 16, 12, 11 - 1, 12,
    0, 12, 11 - 2, 12, 16, 12, 11 - 2, 12,
    0, 12, 11 - 3, 12, 16, 12, 11 - 3, 12,
];

//webaudio.
var audio        = new (window.webkitAudioContext || window.AudioContext);
var scriptproc   = audio.createScriptProcessor(buffer_size);
var filter       = audio.createBiquadFilter();
var sample_pnote = audio.sampleRate / divide;
var basepitch    = finetune / audio.sampleRate;

scriptproc.onaudioprocess = audiohandler;
scriptproc.connect(filter);

filter.type      = 0;
filter.frequency.value = cutoff;
filter.connect(audio.destination);

console.log(audio.sampleRate, sample_pnote, finetune);

var voice = function() {
    this.ph = 0;
    this.acc = 0;
    this.on = function(note) {
        //http://ja.wikipedia.org/wiki/%E5%B9%B3%E5%9D%87%E5%BE%8B
        this.acc = Math.pow(2.0, note / 12.0) * basepitch;
    }

    this.get = function() {
        this.ph += this.acc;
        var g0 = Math.sin(this.ph * 3.141592 * 2);
        return g0 > 0.0 ? -1 : 1;
    }
};
vo = new voice();

var remain = 0;
var index  = 0;
function audiohandler(event) {
    var outL = event.outputBuffer.getChannelData(0);
    var outR = event.outputBuffer.getChannelData(1);
    for(var i = 0 ; i < outL.length; i++) {
        remain--;
        if(remain <= 0) {
            var note = (score[index % score.length]);
            vo.on(note);
            remain = sample_pnote;
            index++;
            console.log(note);
        }
        var out  = vo.get()
        outL[i]  = out * gain;
        outR[i]  = outL[i];
    }
}

</script>

↑のサンプル。

https://dl.dropboxusercontent.com/u/27656232/scsnd.html
※こいつHTL21でも音鳴った!やるな!

もうちょっと凝ったの。
https://dl.dropboxusercontent.com/u/27656232/scsndseq.html

フィルタとかは適当(耳触りだったので)

voiceを適当に増やせばポリな感じにできる。
createOscillator使う手もあるけど適当にグライド発生するし、FireFoxだとグライド無いしまだダメ(デフォの場合)
※調べたけどcreateOscillator今時点で全く役に立たないわ。さすがドラフト。