blocklyでobjectを動かす。 その5


概要

blocklyでobjectを動かして見る。
audiocontextで、メロディ奏でてみた。

ステージを作る

var audioContext = new AudioContext();

ブロックを書く。

Blockly.Blocks.mml = {
    init: function() {
        this.jsonInit({
        message0: "mml %1",
        args0: [{
            type: "input_value",
            name: "TEXT"
        }],
        previousStatement: null,
        nextStatement: null,
        style: "text_blocks",
        tooltip: Blockly.Msg.TEXT_PRINT_TOOLTIP,
        helpUrl: Blockly.Msg.TEXT_PRINT_HELPURL
    })
}};

フローを書く。

objectを書く。

Blockly.JavaScript.mml = function(a) {
    return "mml(" + (Blockly.JavaScript.valueToCode(a, "TEXT", Blockly.JavaScript.ORDER_NONE) || "''") + ");\n"
};

function oto(key) {
    var osciillatorNode = audioContext.createOscillator();
    var envelopeGen = audioContext.createGain();
    var freq = 440.0 * Math.pow(2.0, (key - 69.0) / 12.0);
    osciillatorNode.frequency.value = freq;
    osciillatorNode.connect(envelopeGen);
    envelopeGen.connect(audioContext.destination);
    var t1 = audioContext.currentTime;
    envelopeGen.gain.cancelScheduledValues(t1);
    envelopeGen.gain.setValueAtTime(1, t1);
    osciillatorNode.start();
    var release = 0.2;
    var keyUpTime = audioContext.currentTime;
    envelopeGen.gain.setValueAtTime(envelopeGen.gain.value, keyUpTime);
    envelopeGen.gain.linearRampToValueAtTime(0, keyUpTime + release);
    osciillatorNode.stop(keyUpTime + release);
};

function sleep(milliseconds) {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++)
    {
        if ((new Date().getTime() - start) > 100 * milliseconds)
        {
            break;
        }
    }
}

function mml(src) {
    for (var i = 0; i < src.length; i++)
    {
        var a = src[i];
        switch (a)
        {
        case 'a':
            oto('69');
        break;
        case 'b':
            oto('71');
        break;
        case 'c':
            oto('72');
        break;
        case 'd':
            oto('74');
        break;
        case 'e':
            oto('76');
        break;
        case 'f':
            oto('77');
        break;
        case 'g':
            oto('79');
        break;
        case 'A':
            oto('81');
        break;
        case 'B':
            oto('83');
        break;
        default:
        break;
        }
        sleep(4);
    }
}

成果物

以上。