sS hjs_createAudioMeter() { ret hjs([[ var audioMeterDebug = false; function createAudioMeter(audioContext,clipLevel,averaging,clipLag) { var processor = audioContext.createScriptProcessor(512); processor.onaudioprocess = volumeAudioProcess; processor.clipping = false; processor.lastClip = 0; processor.volume = 0; processor.clipLevel = clipLevel || 0.98; processor.averaging = averaging || 0.95; processor.clipLag = clipLag || 750; processor.absLevel = 0; // this will have no effect, since we don't copy the input to the output, // but works around a current Chrome bug. processor.connect(audioContext.destination); processor.checkClipping = function(){ if (!this.clipping) return false; if ((this.lastClip + this.clipLag) < window.performance.now()) this.clipping = false; return this.clipping; }; processor.shutdown = function(){ this.disconnect(); this.onaudioprocess = null; }; return processor; } function volumeAudioProcess( event ) { var buf = event.inputBuffer.getChannelData(0); var bufLength = buf.length; var sum = 0; var x; // Do a root-mean-square on the samples: sum up the squares... var absLevel = 0; for (var i=0; i= this.clipLevel) { console.log("Got clipping: " + x); this.clipping = true; this.lastClip = window.performance.now(); } sum += x * x; } // ... then take the square root of the sum. var rms = Math.sqrt(sum / bufLength); this.absLevel = absLevel; if (audioMeterDebug) console.log("absLevel: " + absLevel); // Now smooth this out with the averaging factor applied // to the previous sample - take the max here because we // want "fast attack, slow release." this.volume = Math.max(rms, this.volume*this.averaging); } ]]); }