Audio-2 overtones

by morkow

HTML

<small><pre>
Select frequency, number of overtones, volume factor and press "Test".
It should play the sound.

    
Tested only with Chrome 41.</pre></small>
<a href="#" onclick="main();return false;">[Test]</a>
freq=<input id="in-freq" type="number" value="80"/>
n_overtones=<input id="in-overtones" type="number" value="5"/>
volume_factor=<input id="in-vol" type="number" value="3"/>

JavaScript

"use strict";

function generateSine(buf, freq, rate, volume) {
    var phase = 0;
    var maxphase = 2 * Math.PI;
    //var maxval = 1.0;
    var step = maxphase * freq / rate;

    for (var i = 0; i < buf.length; i++) {
        buf[i] += Math.sin(phase) * volume;
        phase += step;
        if (phase >= maxphase) {
            phase -= maxphase;
        }
    }
}

var ID_INPUT_FREQ = "in-freq";
var ID_INPUT_N_OVERTONES = "in-overtones";
var ID_INPUT_VOLUME_FACTOR = "in-vol";

function generateAudio(buf, rate) {
    for (var i = 0; i < buf.length; i++) {
        buf[i] = 0; // TODO: Do we really need it??
    }
    
//    var f = 440.0;
    var f = document.getElementById(ID_INPUT_FREQ).value;
    var n = document.getElementById(ID_INPUT_N_OVERTONES).value;
    var VF = document.getElementById(ID_INPUT_VOLUME_FACTOR).value;
    
    for (var i = 0; i < n; i++) {
        var freq = f * (i + 1);
        var vol = 1.0 / (VF * i + 1);
        generateSine(buf, freq, rate, vol);
    }
}

function main() {
    var ac = new AudioContext();
    var soundSource = ac.createBufferSource();
    var rate = ac.sampleRate;
    var soundBuffer = ac.createBuffer(1, (rate / 1), rate);
    //                       Mono    -^   ^^^^^^^^
    //                       0.5 seconds _/

    generateAudio(soundBuffer.getChannelData(0), rate);

    soundSource.buffer = soundBuffer;
    soundSource.connect(ac.destination);
    soundSource.start(ac.currentTime);
    soundSource.onended = function () {
        console.log("soundSource ended");
        ac.close();
    }; 
    //console.log(ac);
    
}


try {
    //main();
    window.main = main;
} catch (e) {
    var d = document;
    var m = d.createElement('div');
    console.log(e);
    m.style.width = "100%";
    m.style.height = Math.max(d.body.scrollHeight, d.documentElement.scrollHeight) + 'px';
    m.style.position = 'absolute';
    m.style.left = '0';
    m.style.top = '0';
    m.style.background = '#2067b2';
    m.style.color =...