Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate object by sound amplitude?

I know it's possible to animate an object with sound via Actionscript. I am really hoping it is also possible to animate an object with JavaScript since they are very similar.

Maybe it could be done with jQuery or HTML5. I am just hoping to find a way to do it outside of flash.

Does anyone know if this is possible in any of these formats? I have done lots of research and can't seem to find any forms or tutorials that say it is possible or not.

BASICALLY, I am trying to achieve this same effect that I coded in Actionscript but I want code it using another language so no flash views can also see.

Here is the flash example: http://beaubird.com/presentation.php

Here is an example of animating amplitude with actionscript: http://www.developphp.com/view.php?tid=22

like image 288
Papa De Beau Avatar asked Nov 19 '12 21:11

Papa De Beau


1 Answers

I've created an example that changes the radius and color of an svg circle element based on audio amplitude.

This will work in WebKit browsers, but nothing else. Webkit browsers are the only browsers that come even close to implementing the W3C Web Audio API Spec, as far as I know, but the Mozilla Audio Data API Documentation seems to indicate that Mozilla has abandoned that spec and will be implementing the Web Audio API too. I'm blissfully unaware of the state of Internet Explorer's implementation (or lack thereof) of the the spec.

Unfortunately, the answer right now is that there's no great cross-browser solution for this other than Flash, but if you go that route, you're screwed on mobile devices.

Here's the full, working JSBin example.

And here's the code:

HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8 />
        <title>Drums</title>
    </head>
    <body>
        <svg width="200" height="200">
            <circle id="circle" r="10" cx="100" cy="100" />
        </svg>
    </body>
</html>

Javascript:

var context = new webkitAudioContext();

// Here's where most of the work happens
function processAudio(e) {
  var buffer = e.inputBuffer.getChannelData(0);
  var out = e.outputBuffer.getChannelData(0);
  var amp = 0;

  // Iterate through buffer to get the max amplitude for this frame
  for (var i = 0; i < buffer.length; i++) {
    var loud = Math.abs(buffer[i]);
    if(loud > amp) {
      amp = loud;
    }
    // write input samples to output unchanged
    out[i] = buffer[i];
  }

  // set the svg circle's radius according to the audio's amplitude
  circle.setAttribute('r',20 + (amp * 15));

  // set the circle's color according to the audio's amplitude
  var color = Math.round(amp * 255);
  color = 'rgb(' + color + ',' + 0 + ',' + color + ')';
  circle.setAttribute('fill',color);
}

window.addEventListener('load',function() {
  var circle = document.getElementById('circle');

  // Add an audio element
  var audio = new Audio();
  audio.src = 'http://www.mhat.com/phatdrumloops/audio/acm/mole_on_the_dole.wav';
  audio.controls = true;
  audio.preload = true;
  document.body.appendChild(audio);


  audio.addEventListener('canplaythrough',function() {
    var node = context.createMediaElementSource(audio);

    // create a node that will handle the animation, but won't alter the audio
    // in any way        
    var processor = context.createJavaScriptNode(2048,1,1);
    processor.onaudioprocess = processAudio;

    // connect the audio element to the node responsible for the animation
    node.connect(processor);

    // connect the "animation" node to the output
    processor.connect(context.destination);

    // play the sound
    audio.play();
  });
});
like image 146
John Vinyard Avatar answered Sep 17 '22 08:09

John Vinyard