UNPKG

dspjs

Version:

DSP.js is a comprehensive digital signal processing library for javascript

230 lines (195 loc) 7.5 kB
<!DOCTYPE html> <html> <head> <!-- Load JQuery and JQuery-UI --> <link type="text/css" href="css/hot-sneaks/jquery-ui-1.8.custom.css" rel="stylesheet" /> <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="js/jquery-ui-1.8.custom.min.js"></script> <!-- Load Processing.js --> <script language="javascript" src="js/processing.js"></script> <script language="javascript" src="js/init.js"></script> <!-- Load DSP.js --> <script src="../dsp.js"></script> <script> $(function() { $('#freq').slider({ orientation: 'vertical', range: 'min', min: 60, max: 10000, step: 1, value: 880, slide: changeF0 }); $('#q').slider({ orientation: 'vertical', range: 'min', min: 0.01, max: 115.0, value: 1.0, step: 0.001, slide: changeQ }); $('#bw').slider({ orientation: 'vertical', range: 'min', min: 0.01, max: 10.0, value: 1.0, step: 0.001, slide: changeBW }); $('#s').slider({ orientation: 'vertical', range: 'min', min: 0.0, max: 5.0, value: 1.0, step: 0.001, slide: changeS }); $('#dbgain').slider({ orientation: 'vertical', range: 'min', min: -30.0, max: 30.0, value: 12.0, step: 1, slide: changeDbGain }); $('#filtertype').buttonset(); $('#filtertype > input').each(function() { $(this).button().click( changeFilterType ); }); $('#input').attr('volume', 0); var input = document.getElementById('input'); input.addEventListener('MozAudioAvailable', audioWritten, false); }); </script> <style type="text/css"> body, * { font-family: Arial, sans-serif; } .control { padding: 5px; border: 1px outset #CCC; background-color: #EEE; float: left; margin-right: 5px; } .control table td { padding: 10px; width: 20px; color: #999; font-size: 12px; } .control h3 { margin: 0; padding:0; font-size: 12px; margin-bottom: 10px; } .control #debug { border: 1px inset #ccc; background-color: #FFF; font-size: 12px; width: 300px; padding: 10px; } .slider { margin-bottom: 16px; width: 8px; } .ui-button { font-size: xx-small; } .ui-slider .ui-slider-handle { width: 8px; margin-left: 3px; } </style> </head> <body> <script> // Setup shared variables var sampleRate = 44100; var response = []; var writeCount = 0; var signal = new Float32Array(2048); var biquad; var output = new Audio(); if ( typeof output.mozSetup === 'function' ) { output.mozSetup(2, sampleRate); } var plotCoeffs = function() { var b = [biquad.b0, biquad.b1, biquad.b2]; var a = [biquad.a0, biquad.a1, biquad.a2]; w = Array(200); for (var i=0;i<w.length; i++) { w[i] = Math.PI/w.length * i; } response = DSP.mag2db(DSP.freqz(b, a, w)); //response = DSP.freqz(b, a); } var changeFilterType = function() { biquad.setFilterType(DSP[$('#filtertype>input:checked').next().text()]); plotCoeffs(); } var changeF0 = function() { biquad.setF0($('#freq').slider('option', 'value')); plotCoeffs(); } var changeBW = function() { biquad.setBW($('#bw').slider('option', 'value')); plotCoeffs(); } var changeS = function() { biquad.setS($('#s').slider('option', 'value')); plotCoeffs(); } var changeQ = function() { biquad.setQ($('#q').slider('option', 'value')); plotCoeffs(); } var changeDbGain = function() { biquad.setDbGain($('#dbgain').slider('option', 'value')); plotCoeffs(); } function audioWritten(event) { signal = event.frameBuffer; // Apply the filter to the signal signal = biquad.processStereo(signal); output.mozWriteAudio(signal); writeCount++; } </script> <script type="application/processing" target="#signal"> void setup() { size(300, 200); biquad = new Biquad(DSP.BPF_CONSTANT_PEAK, sampleRate); changeFilterType(); changeF0(); changeQ(); changeDbGain(); stroke(255); strokeWeight(1); frameRate(20); } void draw() { background(255); // Draw axes float yMin = -120; float yMax = 60; float yCenter = 0; float xMin = 0; float xMax = PI; float xCenter = 0; stroke(0); line(map(xCenter, xMin, xMax, 0, width), map(yMin, yMin, yMax, height, 0), map(xCenter, xMin, xMax, 0, width), map(yMax, yMin, yMax, height, 0)); line(map(xMin, xMin, xMax, 0, width), map(yCenter, yMin, yMax, height, 0), map(xMax, xMin, xMax, 0, width), map(yCenter, yMin, yMax, height, 0)); // Draw the response noFill(); stroke(10, 40, 200); beginShape(); for (int i = 0; i < response.length; i++) { vertex(map(i, 0, response.length, 0, width), map(response[i], yMin, yMax, height, 0)); } endShape(); } </script> <h1>Biquad Filter</h1> <h3>by <a href="http://www.ricardmarxer.com/blog">Ricard Marxer</a></h3> <p>Applies a Biquad filter to an audio stream. Remember to <b>Mute</b> the audio to hear the pure filtered sound.</p> <p>The filter implementation will become part of the <a href="https://wiki.mozilla.org/Audio_Data_API_JS_Library">dsp.js</a> library.</p> <p>You will need a recent build of Mozilla Firefox with the Audio API to hear the filtered version.</p> <audio id='input' tabindex="0" src="audio/corban-peddle.ogg" controls="true" style="width: 100%;"></audio><br> <div style="width: 100%;"> <div><canvas id="signal" width="50%" height="200px" style="float: left;"></canvas></div> <div class="control" style="float: right; height: 188px"> <h3>Biquad Filter</h3> <form> <span id="filtertype"> <input type="radio" id="lpf" name="filtertype" checked="checked" /><label for="lpf">LPF</label> <input type="radio" id="hpf" name="filtertype" /><label for="hpf">HPF</label> <input type="radio" id="bpf_constant_skirt" name="filtertype" /><label for="bpf_constant_skirt">BPF_CONSTANT_SKIRT</label> <input type="radio" id="bpf_constant_peak" name="filtertype" /><label for="bpf_constant_peak">BPF_CONSTANT_PEAK</label> <input type="radio" id="notch" name="filtertype" /><label for="notch">NOTCH</label> <input type="radio" id="apf" name="filtertype" /><label for="apf">APF</label> <input type="radio" id="peaking_eq" name="filtertype" /><label for="peaking_eq">PEAKING_EQ</label> <input type="radio" id="low_shelf" name="filtertype" /><label for="low_shelf">LOW_SHELF</label> <input type="radio" id="high_shelf" name="filtertype" /><label for="high_shelf">HIGH_SHELF</label> </span> </form> <table> <tr> <td><div id="freq" class="slider"></div>freq</td> <td><div id="q" class="slider"></div>Q</td> <td><div id="bw" class="slider"></div>BW</td> <!--<td><div id="s" class="slider"></div>S</td>--> <td><div id="dbgain" class="slider"></div>dBgain</td> </tr> </table> </div> </div> </body> </html>