UNPKG

dspjs

Version:

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

210 lines (182 loc) 6.15 kB
<!DOCTYPE html> <html> <head> <!-- Load JQuery and JQuery-UI --> <script type="text/javascript" src="js/jquery-1.4.2.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> <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-slider .ui-slider-handle { width: 8px; margin-left: 3px; } </style> </head> <body> <script> // Setup shared variables var sampleRate = 44100; var frameSize = 4096; var signal = new Float32Array(frameSize/2); var lp12; var buffer = []; // Setup experimental audio out var output = new Audio(); if ( typeof output.mozSetup === 'function' ) { output.mozSetup(1, sampleRate); } var changeFilter = function() { lp12.set($('#cutoff').slider('option', 'value'), $('#res').slider('option', 'value')); } function loadedMetaData(event) { var audio = document.getElementById('input'); audio.mozFrameBufferLength = frameSize; audio.addEventListener("MozAudioAvailable", audioAvailable, false); } function audioAvailable(event) { signal = DSP.getChannel(DSP.MIX, event.frameBuffer); lp12.process(signal); output.mozWriteAudio(signal); } </script> <script type="application/processing" target="#signal"> Knob cut; Knob res; void setup() { size(512, 200); cut = new Knob("", 60, 6000, 2500, 70, 20, 50, 50); res = new Knob("", 1, 20, 7, 0.3, 20, 100, 50); lp12 = new IIRFilter(DSP.LOWPASS, 22050, 0, sampleRate); // mute the input document.getElementById('input').muted = true; stroke(255, 0, 0); } void draw() { background(255); lp12.set(cut.value, res.value); for (int i = 0; i < width; i+=2) { line(i, height/2 - signal[4*i]/2 * 200, i, height/2 + signal[4*i]/2 * 200); } fill(255, 0, 0); text("F", 30, 30); text("Q", 75, 30); ellipse(52, 52, 40, 40); ellipse(102, 52, 40, 40); fill(255); cut.draw(); res.draw(); } class Knob { float radius; float x; float y; boolean active; float mouseYInit; float value; float min; float max; float step; float percent; float angle; String label; Knob(label, min, max, value, step, radius, x, y) { this.radius = radius; this.x = x; this.y = y; this.active = false; this.value = value; this.min = min; this.max = max; this.step = step; this.label = label; } void draw() { textSize(12); ellipseMode(CENTER); if (mousePressed) { if (this.isOver() && !this.active && !Knob.active) { this.active = true; this.mouseYInit = mouseY; Knob.active = true; } else if (this.active) { this.value += (this.mouseYInit - mouseY) * this.step; this.value = constrain(this.value, min, max); this.mouseYInit = mouseY; } } else { this.active = false; Knob.active = false; } this.percent = (this.value - this.min) / (this.max - this.min); this.angle = map(this.value, this.min, this.max, radians(-130), radians(130)); pushMatrix(); translate(this.x, this.y); rotate(this.angle); ellipse(0, 0, 2*this.radius, 2*this.radius); line(0, 0, 0, -this.radius); popMatrix(); /* text(this.label, this.x - this.radius -5, this.y - this.radius - 5); text(this.value, this.x+this.radius+5, this.y); text(round(this.percent * 100) + "%", this.x+this.radius+5, this.y+20); */ } boolean isOver() { if (mouseX > this.x - this.radius && mouseX < this.x + this.radius && mouseY > this.y - this.radius && mouseY < this.y + this.radius) { return true; } return false; } } </script> <h1>Audio Filter</h1> <p>Applies a Low pass filter to an audio stream. Remember to <b>Mute</b> the audio to hear the pure filtered sound.</p> <p>The low pass filter acts as a gate, only letting frequencies below the cut off value through.</p> <audio id='input' tabindex="0" src="audio/megaman.ogg" controls="true" onloadedmetadata="loadedMetaData(event);" style="width: 512px;"></audio><br> <div><canvas id="signal" width="512px" height="200px"></canvas></div> <p>The <b>F</b> knob controls the cut off frequency, between 0 and 22050 Hz.</p> <p>The <b>Q</b> knob controls the resonance drive.</p> <p>A low frequency cutoff and strong resonance can give an acidy or dampened underwater effect.</p> <p>(Be careful! Adjust your volume! Certain knob combinations can give off loud undesired schreeching noises!)</p> <p>Music: Delv-X: Megaman theme (cover)</p> </body> </html>