For Manual Mode...
For BPM Mode...
Ever since I saw those first DJ P0N-3 videos on YouTube (like this one) I've been wanting to make a DJ P0N-3 beat visualizer. You could submit an mp3, and DJ P0N-3 would bob to the beat. I experimented for a whole weekend, and got the basic idea working. Two problems prevented it from becoming what I wanted though...
It turns out that while detecting how loud music is at a given point in time is relatively easy, detecting when a beat occurs within a song is very very difficult. I implemented the most basic form of beat detection which simply finds spikes in the average raw sound power over time. However, this made DJ P0N-3 look like she was having a seizure. For high quality beat detection, digital signal processing and some relatively advanced maths are involved. People have managed to do it too, but it was a lot more work than I had time for.
It only occured to me after I was almost done that, oh yeah, there's no good way to get audio onto this site. I don't think there's a way to pipe YouTube audio into the sound manager on this page, and allowing users to upload their own mp3's to my server was a security issue waiting to happen.
I also wanted to implement some kind of WebGL fragment shader that would render DJ P0N-3's frames with a real vector implementation, tweening smoothly over the whole animation, but that would be a project unto itself.
DJ P0N-3's head bobbing appearance is made up of about 70 frames. I got them from my iTunes copy of Friendship is Magic to avoid the watermark while retaining high resolution. There are about 11 unique frames of DJ P0N-3 moving her head, and about 4 unique frames of the discs spinning. The animating parts were cropped into a series of frames that I stored within a single image for each animation. That way, animation can be implemented using CSS Sprite Animation. Any parts of the shot that were stationary were stored as a static background and a static overlay.
I made two renderers: one for the discs and one for DJ P0N-3. While the discs only have to keep animating between the 4 frames, DJ P0N-3 had to animate based on key presses (or beat amounts, as it was originally designed). To do this, I used the idea of a 'pulse'. When a pulse was registered, DJ P0N-3 would bob her head down very rapidly. If there was no pulse going on, she would raise her head back up at a much slower speed. Thats how head bobbing works: rapid head down on beat, slower head raise on off-beat. I tracked the enter key's state. Every render loop, if the enter key was held down, I signaled a pulse. If the key was up, no pulse would occur. Since the render loop always tried to animate her head going slowly back up, the pulses resist that movement to create a pretty realistic head bob. And since the pulse signals are fired every render loop, not every button push, how long you hold the enter key can determine how far down she bobs her head.
In version 2, I made the head bob command work with almost all keys that weren't the spacebar and made the mouse cause the head bob too, at the request of others. I also added a new mode: BPM Mode. This allows the animation to run at a set rate.
I had fun making this page. I hope you have fun using it!
And you know what would be about 20% cooler? If somepony would take what I've done and make it SO AWESOME! by expanding upon it. This javascript file contains all of the original code for the site, including the stuff I took out (sound manager, beat detection, etc). Later bronies!