This is a demonstration of playing an mp3 file completely in script. Decoding is done directly in JavaScript without any help from the engine, using the Aurora.js library. Playback is facilitated by a Sphere v2 SoundStream object. miniSphere 5.0b2+ is recommended; while the demo will work in 4.8.8, the audio might stutter due to Duktape not really being up to the task.
Update 2017-09-22: Updated for API changes in miniSphere 5.0b2/4.8.8
Update 2017-09-17: Added a cool visualization effect.
Get the demo:
https://drive.google.com/open?id=0BxPKLRqQOUSNTlBwU1dwSnU4REk
I updated the demo and added a nice visualization that I won't spoil here. ;) Try it out!
In the process of making this demo I discovered a few deficiencies in the Sphere v2 API, so I've fixed those for the next mS 5 beta :D
- I noticed that I needed to call RequireScript to load Aurora, since it was built with browserify. Since there's still a use case for loading old-style JS even in a fully modular codebase like this and RequireScript is not SphereFS compliant, I added FS.evaluateScript to fill the gap.
- SoundStream#bufferSize is in bytes and therefore requires the caller to know the sample rate, channel count, etc. to know how much audio is buffered. As the main use case is just to monitor to stream to prevent underrun, I replaced it with SoundStream#length which is in seconds.
Hmm very interesting concept, linked sound and music - I feel like that should have a game related application.
Yeah, now we can code something like Audiosurf if need be.
This has some great applications and possibilities. :)
If anyone's curious, two
from() queries are used to drive the visualization:
// calculate the current VU for this frame (for visualization)
let amplitudeL = from(samples)
.where((v, index) => index % 2 == 0)
.reduce((a, v) => Math.max(Math.abs(v), a), 0.0);
let amplitudeR = from(samples)
.where((v, index) => index % 2 == 1)
.reduce((a, v) => Math.max(Math.abs(v), a), 0.0);
this.vu1 = (amplitudeL + this.vu1 * 4) / 5;
this.vu2 = (amplitudeR + this.vu2 * 4) / 5;
(The code for this in the demo is a bit different; I've refactored it locally since posting it)
I updated the demo with code changes to support to most recent beta (5.0b2).
I was thinking last night, I should probably move the actual mp3 player functionality out into a class that can be used in other games. At least once I fix the bug where it crashes the game at the end of playback...