dspjs
Version:
DSP.js is a comprehensive digital signal processing library for javascript
230 lines (195 loc) • 7.5 kB
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>