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.

[kml_flashembed publishmethod="dynamic" fversion="10.0.0" movie="flash/reverse.swf" width="450" height="50" targetclass="flashmovie" bgcolor="#f1f1f1"]

Get Adobe Flash player

[/kml_flashembed]

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;
}
Lee

Commentary

  1. mark says:

    Awesome! Wondering…is there any way to change the actual pitch of a sample using Actionscript?

  2. whizzle says:

    Hmmm…sounds like John Coltrane from around 1960 on Atlantic. Who’s the artist and tune?

  3. lee says:

    Very good @whizzle! It’s John Coltrane – Traening in.

  4. Subb says:

    @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()

  5. wonderwhy-er says:

    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? :D I mean reversing byte(rather Number) order when playing in reverse? :D

    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 :)

  6. boblemarin says:

    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

  7. Wes says:

    I smell a flash dj turntable app that changes playback speed and direction based on mouse movement.

  8. ed says:

    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.

  9. lee says:

    @boblemarin awesome example. I was wondering if somebody had made a scratch app yet.

  10. lee says:

    @boblemarin ahh so you extracted the whole file first to a ByteArray. Much better idea than what I had :) .

  11. boblemarin says:

    @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.

  12. Simonas says:

    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…

  13. Lawrie says:

    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/

  14. vi54 says:

    This is especially cool to display the soundspectrum before it plays :]

  15. Truffle says:

    Awesome

    Thanks

  16. carrrramba says:

    @boblemarin awesome example of use! thank you for sharing the code.

    cheers
    carrrramba

  17. progressiveOne says:

    Very good Lee. But please, add the \Stop\ button. Thanks!

  18. Php Coder says:

    I have a question. What code do I add the stop button?

    Help me theflashblog user and LEE :(

  19. Justin "SumWunGye" says:

    Oh, how I wish things like this were available in AS2… TT_TT

    (I mean, everything AS3 gets AS2 should get, right? Just add some functions that do these cool things..)

  1. [... 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 ...]

  2. [... 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 ...]

Leave a Comment