Manipulating MP3 speed and direction
Here is one of those examples that I did just for the hell of it. I often wondered how hard it would be to play an MP3 in reverse. It turns out that it is really easy with Flash Player 10. Now my implementation of reverse is pretty weak and I’m sure guys like Andre Michelle could make something that sounded perfect. Click the button below to try it out. You can reverse direction and speed it up.
You surely heard the jerkiness and little glitches and that could surely be corrected with more work. All of this is possible thanks to the new Sound.extract() method. This allows you to grab the bytes from a loaded sound and then manipulate them before passing them to the sound card. You tell the method how many sound samples you want to extract and what position to start from in the file. It is this position property that allows you to move in any direction in the file. Subtracting a number makes it go in reverse and adding to it moves the music forward.
Now one thing that screwed me up at first is the fact that the extract method deals with samples, not bytes. A sample is 8 total bytes of audio data with 4 bytes being for each channel. Another thing that is tricky is getting the total number of samples in a file. I used the method of multiplying 44100 by the number of seconds in the file. Obviously it will only work on files set at that sample rate and it isn’t foolproof. But this method could be useful to allow people to scrub back and forth through an audio file.
The code is shown below and you can also download the FLA. I created in Flash but you could easily dump this into Flash Builder as well. I’d be interested to hear if someone gets it sounding totally smooth. The real trick would be extract a chunk of samples and then reverse the bytes of the samples. I tried that but couldn’t figure it out.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | var ex:Sound; var ns:Sound; var position:int; var max:int; var speed:int = 4096; c.b1.addEventListener(MouseEvent.CLICK, function(){speed=-8192;}); c.b2.addEventListener(MouseEvent.CLICK, function(){speed=-4096;}); c.b3.addEventListener(MouseEvent.CLICK, function(){speed=4096;}); c.b4.addEventListener(MouseEvent.CLICK, function(){speed=8192;}); lclip.visible = false; c.visible = false; loadmusic.addEventListener(MouseEvent.CLICK, init); function init(e:Event):void { position = 0; loadmusic.visible = false; lclip.visible = true; ex = new Sound(new URLRequest("col.mp3")); ex.addEventListener(Event.COMPLETE, onComplete); ns = new Sound(); ns.addEventListener(SampleDataEvent.SAMPLE_DATA, onData); } function onComplete(e:Event):void { lclip.visible = false; c.visible = true; max = 44100 * (ex.length/1000) - 4096; position = max; ns.play(); } function onData(e:SampleDataEvent):void { var bytes:ByteArray = new ByteArray(); ex.extract(bytes, 4096, position); e.data.writeBytes(bytes); position += speed; if(position < 0) position = max; else if(position > max) position = 0; } |




Awesome! Wondering…is there any way to change the actual pitch of a sample using Actionscript?
Hmmm…sounds like John Coltrane from around 1960 on Atlantic. Who’s the artist and tune?
Very good @whizzle! It’s John Coltrane – Traening in.
@mark yes you can. It’s not as easy as setting a pitch property, but if you understand the code above, it’s pretty easy. In fact, in the docs, there’s a good example. http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/media/Sound.html#extract()
Wonderful
Initially I tough that that you made “reverse” playing too but it seems you made just rewinding. How about playing music signal backwards when rewinding?
I mean reversing byte(rather Number) order when playing in reverse?
May be I will play with it my self little bit later trying what I have said + making speed adjustments kind of differently. Thanks for inspiration
Getting it to sound smooth is not that difficult.
There : http://herrmuttlobby.com/scratch/
and the source (not cleaned up
:
http://herrmuttlobby.com/scratch/source.as
I smell a flash dj turntable app that changes playback speed and direction based on mouse movement.
How about lowering the actual pitch of a sample? I believe this involves time-stretching but so far I haven’t been able to find any examples.
@boblemarin awesome example. I was wondering if somebody had made a scratch app yet.
@boblemarin ahh so you extracted the whole file first to a ByteArray. Much better idea than what I had
.
@lee : but it requires more RAM, and it slightly freezes the flash player while extracting a whole song.
in the case of a TraktorDJ-style application (extracting a file while pitch-playing another), it might be a better idea to extract smaller parts of the file when needed, though i haven’t been benchmarking that solution.
I actually managed to somehow get a BoD on Vista SP2.. :] When I tried to play the sound backwards, it froze on one particular beat-hit, and kept looping that, until I saw a BoD… But I think, there’s smth wrong with my configuration of the system, not that the flash player caused it…
exemplary sir.
[...] 1.) Manipulating Mp3’s: Learn how to reverse mp3’s with AS3, pretty neat. 2.) The Art of Debugging: Learn the ins and outs of debugging with this expansive explanation. 3.) Improve Your Game Over Screen: Learn how to keep players from leaving your game upon game over with a few simple additions. 4.) Introduction to OOP: A nice introduction to explaining the basics of Object Oriented Programming. 5.) Pre-loaders with AS3: One developers take on how to implement a pre-loader using AS3 (often an annoying task) [...]
Wow, that’s awesome boblemarin, very cool.
Kelvin Luck did a nice audio speed test a while ago – http://www.kelvinluck.com/2009/03/second-steps-with-flash-10-audio-programming/
This is especially cool to display the soundspectrum before it plays :]
[...] for good! Some things don’t change as Lee tinkers with audio in his latest blog post called Manipulating mp3 Speed and Direction and explores various ways to manipulate audio using Flash Player [...]
Awesome
Thanks
@boblemarin awesome example of use! thank you for sharing the code.
cheers
carrrramba
Very good Lee. But please, add the \Stop\ button. Thanks!