3

On a previous stack overflow question, I found this code:

<script>
// this is to store a reference to the input so we can kill it later 
var liveSource;
// creates an audiocontext and hooks up the audio input
function connectAudioInToSpeakers(){
  var context = new webkitAudioContext();  
  navigator.webkitGetUserMedia({audio: true}, function(stream) {
    console.log("Connected live audio input");
    liveSource = context.createMediaStreamSource(stream);
    liveSource.connect(context.destination);
    console.log(liveSource);
  });
 }
// disconnects the audio input
function makeItStop(){
   console.log("killing audio!");
   liveSource.disconnect();
 }
// run this when the page loads
connectAudioInToSpeakers();
</script>

which takes audio from the user's microphone and plays it back through the speakers. What I want is the level (amplitude) of the input (eg so I can display a red warning if clipping is occuring, or to tell the user they need to speak up). In the above code, how do I actually get hold of the raw data?

For example how can I log actual numbers to the console? I'm guessing it's all stored in liveSoure?

I don't need any clever canvas animations etc, just a number, that tells me how loud the input is. Is this relatively simple? And if so, how is it done?

Thanks

Lars
  • 7,908
  • 11
  • 52
  • 70

1 Answers1

6

Here's how I did it - you can see it live at http://labs.dinahmoe.com/dynamicmusicengine/ Just connect liveSource to this JavaScriptNode (there is also context.createScriptProcessor(4096, 1, 1) which is the new syntax, though both will be supported according to http://www.w3.org/2011/audio/wiki/F2F_Mar_2013)

var levelChecker = context.createJavaScriptNode(4096, 1 ,1);
liveSource.connect(levelChecker);
levelChecker.connect(context.destination);

levelChecker.onaudioprocess = function(e) {
        var buffer = e.inputBuffer.getChannelData(0);

        // Iterate through buffer to check if any of the values exceeds 1.
        for (var i = 0; i < buffer.length; i++) {
            if (1 =< buffer[i]) {
                console.log("Oh noes! We got a peak.", buffer[i]);
            }
        }
Oskar Eriksson
  • 2,591
  • 18
  • 32
  • Just going to add actually, it only seems to work for a few seconds, then stops working. Do you know why? I've put it in a separate question here: http://stackoverflow.com/questions/15900103/html5-audio-buffer-getting-stuck Thanks – Lars Apr 09 '13 at 11:32
  • For what it's worth, this method is very inefficient. However, it is required if you want to get the true peaks in a give chunk of samples. A faster method is to use the time domain data from the analyser node, but you may miss some peaks. This may not matter if you are simply doing a visualization. – Brad Jan 19 '14 at 17:44