Skip to content

Instantly share code, notes, and snippets.

@kindohm
Created May 1, 2012 20:50

Revisions

  1. Mike Hodnick revised this gist May 2, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion fft.js
    Original file line number Diff line number Diff line change
    @@ -121,7 +121,7 @@ MIT License
    // call drawFFT at the given frame rate.
    Sink.doInterval(function(){

    drawFFT();
    drawFFT();

    }, 1000/fps);

  2. Mike Hodnick revised this gist May 2, 2012. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion fft.js
    Original file line number Diff line number Diff line change
    @@ -80,8 +80,9 @@ MIT License
    context = canvas.getContext('2d');
    width = canvas.width;
    height = canvas.height;
    gradient = context.createLinearGradient(0, 0, 0, height / 2);
    gradient = context.createLinearGradient(0, 0, 0, height);
    gradient.addColorStop(0, "#ff0000");
    gradient.addColorStop(0.6, "#ff0000");
    gradient.addColorStop(1, "#0000ff");
    context.fillStyle = gradient;
    context.lineWidth = 1;
  3. Mike Hodnick revised this gist May 2, 2012. 1 changed file with 23 additions and 4 deletions.
    27 changes: 23 additions & 4 deletions fft.js
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,16 @@
    /*
    This code demonstrates how to use a Fast Fourier Transform
    with audiolib.js. It pushes samples to an FFT and draws
    the FFT spectrum on an HTML5 canvas.
    Author: Mike Hodnick
    MIT License
    */

    (function () {

    // vars
    var device,
    osc1,
    lfo1,
    @@ -14,13 +25,18 @@
    context,
    playing = false;

    // This is the function that actually fills the
    // audio buffer with samples. In this case it
    // does crazy stuff with LFO's to produce
    // some interesting samples for the FFT.
    function audioCallback (buffer, channels) {

    if (!playing) return;

    var i, sample, bufferLength = buffer.length;

    for (i = 0; i < bufferLength; i += channels) {

    lfo1.generate();
    lfo2.generate();
    lfo3.generate();
    @@ -47,20 +63,19 @@

    var canvas, button;

    // set up audio stuff
    // set up audio device and oscillators
    device = audioLib.AudioDevice(audioCallback, channelCount);

    osc1 = audioLib.Oscillator(device.sampleRate, 600);
    osc1.waveShape = 'triangle';

    lfo1 = audioLib.Oscillator(device.sampleRate, 0.1);
    lfo2 = audioLib.Oscillator(device.sampleRate, 10.3);
    lfo3 = audioLib.Oscillator(device.sampleRate, 0.7);
    lfo4 = audioLib.Oscillator(device.sampleRate, 6.2);

    // create the FFT
    fft = audioLib.FFT(device.sampleRate, 4096);

    // set up UI display stuff
    // set up UI and FFT canvas
    canvas = document.getElementById('canvas');
    context = canvas.getContext('2d');
    width = canvas.width;
    @@ -79,6 +94,8 @@

    });

    // This function actually draws the FFT spectrum
    // on the HTML5 canvas.
    function drawFFT () {

    var length, count;
    @@ -99,6 +116,8 @@
    context.stroke();
    }

    // Use sink.js (built in to audiolib.js) to
    // call drawFFT at the given frame rate.
    Sink.doInterval(function(){

    drawFFT();
  4. Mike Hodnick revised this gist May 2, 2012. 1 changed file with 17 additions and 5 deletions.
    22 changes: 17 additions & 5 deletions fft.js
    Original file line number Diff line number Diff line change
    @@ -4,6 +4,8 @@
    osc1,
    lfo1,
    lfo2,
    lfo3,
    lfo4,
    fft,
    fps = 30,
    channelCount = 2,
    @@ -21,10 +23,16 @@
    for (i = 0; i < bufferLength; i += channels) {
    lfo1.generate();
    lfo2.generate();
    lfo3.generate();
    lfo4.generate();

    lfo2.fm = lfo1.getMix();
    osc1.fm = lfo2.getMix();
    lfo3.fm = lfo2.getMix();
    lfo4.fm = lfo3.getMix();

    osc1.fm = lfo4.getMix();
    osc1.generate();

    sample = osc1.getMix();

    fft.pushSample(sample);
    @@ -41,11 +49,15 @@

    // set up audio stuff
    device = audioLib.AudioDevice(audioCallback, channelCount);

    osc1 = audioLib.Oscillator(device.sampleRate, 600);
    osc1.waveShape = 'square';
    lfo1 = audioLib.Oscillator(device.sampleRate, .1);
    lfo2 = audioLib.Oscillator(device.sampleRate, 30);
    lfo2.waveShape = 'sawtooth';
    osc1.waveShape = 'triangle';

    lfo1 = audioLib.Oscillator(device.sampleRate, 0.1);
    lfo2 = audioLib.Oscillator(device.sampleRate, 10.3);
    lfo3 = audioLib.Oscillator(device.sampleRate, 0.7);
    lfo4 = audioLib.Oscillator(device.sampleRate, 6.2);

    fft = audioLib.FFT(device.sampleRate, 4096);

    // set up UI display stuff
  5. Mike Hodnick revised this gist May 1, 2012. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions fft.js
    Original file line number Diff line number Diff line change
    @@ -5,12 +5,12 @@
    lfo1,
    lfo2,
    fft,
    fps = 30,
    channelCount = 2,
    fps = 30,
    channelCount = 2,
    width,
    height,
    context,
    playing = false;
    playing = false;

    function audioCallback (buffer, channels) {

  6. Mike Hodnick created this gist May 1, 2012.
    96 changes: 96 additions & 0 deletions fft.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@
    (function () {

    var device,
    osc1,
    lfo1,
    lfo2,
    fft,
    fps = 30,
    channelCount = 2,
    width,
    height,
    context,
    playing = false;

    function audioCallback (buffer, channels) {

    if (!playing) return;

    var i, sample, bufferLength = buffer.length;

    for (i = 0; i < bufferLength; i += channels) {
    lfo1.generate();
    lfo2.generate();

    lfo2.fm = lfo1.getMix();
    osc1.fm = lfo2.getMix();
    osc1.generate();
    sample = osc1.getMix();

    fft.pushSample(sample);

    for (n = 0; n < channelCount; n++){
    buffer[i + n] = sample;
    }
    }
    }

    window.addEventListener('load', function() {

    var canvas, button;

    // set up audio stuff
    device = audioLib.AudioDevice(audioCallback, channelCount);
    osc1 = audioLib.Oscillator(device.sampleRate, 600);
    osc1.waveShape = 'square';
    lfo1 = audioLib.Oscillator(device.sampleRate, .1);
    lfo2 = audioLib.Oscillator(device.sampleRate, 30);
    lfo2.waveShape = 'sawtooth';
    fft = audioLib.FFT(device.sampleRate, 4096);

    // set up UI display stuff
    canvas = document.getElementById('canvas');
    context = canvas.getContext('2d');
    width = canvas.width;
    height = canvas.height;
    gradient = context.createLinearGradient(0, 0, 0, height / 2);
    gradient.addColorStop(0, "#ff0000");
    gradient.addColorStop(1, "#0000ff");
    context.fillStyle = gradient;
    context.lineWidth = 1;

    button = document.getElementById('playButton');
    button.onclick = function () {
    playing = !playing;
    button.innerHTML = playing ? 'pause' : 'play';
    };

    });

    function drawFFT () {

    var length, count;
    length = fft.spectrum.length / 8;

    context.clearRect(0, 0, width, height);
    context.beginPath();
    context.moveTo(0, height);

    for (count = 0; count < length; count++) {
    context.lineTo(count / length * width,
    fft.spectrum[count] * -height * 2 + height);
    }

    context.moveTo(width,0);
    context.closePath();
    context.fill();
    context.stroke();
    }

    Sink.doInterval(function(){

    drawFFT();

    }, 1000/fps);

    })();
    14 changes: 14 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    <!DOCTYPE html>
    <html>
    <head>
    <title>audiolib.js FFT demo</title>
    <script type="text/javascript" src="audiolib.min.js"></script>
    <script type="text/javascript" src="fft.js"></script>
    </head>
    <body>

    <p><button id="playButton">play</button></p>
    <canvas id="canvas" width="600" height="200" style="background: #eee;"></canvas>

    </body>
    </html>