JSFiddle - React, Tailwind, and code Playground

by mohayonao

HTML

<script src="http://mohayonao.github.io/neume.js/build/neume.min.js"></script>
<button id="start">start</button>
<canvas id="canvas"></canvas>

CSS

canvas { width:100% }

JavaScript

var Neume = neume(new AudioContext());

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

canvas.width = 1024;
canvas.height = 512;
context.lineWidth = 0.05;
context.strokeStyle = "#2c3e50";
context.fillStyle = "#fff";

function makeReverbBuffer(data, spec) {
    for (var i = 0; i < data.length; i++) {
        data[i] = Math.random() < 0.9975 ? 0 : 0.5;
    }
    data[0] = 0.5;
    return data;
}

function draw(data) {
    context.fillRect(0, 0, canvas.width, canvas.height);
    
    context.beginPath();
    context.moveTo(0, canvas.height * 0.5);
    for (var i = 0; i < data.length; i++) {
        var x = (i / data.length) * canvas.width;
        var y = canvas.height * 0.5 - (canvas.height) * data[i] * 0.5;
        context.lineTo(x, y);
    }
    context.stroke();
}

var reverb = new Float32Array(65536);
makeReverbBuffer(reverb, { coef: 0.9999, room: 2048 });
draw(reverb);

var Synth = new Neume(function($) {
    var out;
    
    out = $("tri", { freq: 1760 });
    out = $("xline", { dur: 0.5 }, out).on("end", function(e) {
        this.stop(e.playbackTime);
    });
    
    return $("out", { bus: 1 }, out);
});

var Efx = new Neume(function($, reverb) {
    var out;
    
    out = $("in", 1);
    out = $("conv", { buf: reverb }, out);
    
    return out;
});

var synth = null;
var timer = null;

$("#start").on("click", function() {
    if (synth) {
        synth.fadeOut("+0", 0.5);
        synth = null;
        timer.stop();
        $(this).css("color", "black");
    } else {
        synth = new Efx(Neume.Buffer.from(reverb)).start();
        timer = new Neume.Interval(1, function() {
            new Synth().start();
        }).start();
        $(this).css("color", "red");
    }
    
});