LoginSignup
7
7

More than 5 years have passed since last update.

WebAudioで適当に何か鳴らす

Last updated at Posted at 2014-08-13

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今時点で全く役に立たないわ。さすがドラフト。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7