Pitch MP3

Pitching MP3 (Not PitchShift!) is possible since Flash10s new Sound API. Today I saw Lee Brimelow’s post about doing so, providing some source code. Cause we spend a lot of time to keep things running more smoothly in the AudioTool, I created another version which has some advantages.

  • No objects are created in runtime (memory usage)
  • The SampleDataEvent is receiving a static blocksize (steady latency)
  • Linear interpolation (sound quality)
  • Speed can go down to zero

{source code}

Get Adobe Flash player

(no preloader – music by basic channel) – Thanks Lee for pointing me!

93 thoughts on “Pitch MP3”

  1. Seriously cool! Can’t believe the source code is so small and easy to follow.
    Already looking forward to your FOTB talk. Hope they put you in the room with the decent soundsystem ;-)

  2. Very nice use of Basic Channel…
    Been meaning to do some audio work, something like pitching is a great place to start.

  3. wow nett – basic channel rockt und das script auch.

    wann programmierst du traktor dj studio in actionscript nach? ;)

    grüße aus berlin

  4. Nicely done! Now we just need to figure out how to get the music pitch changed but with the music playing at a constant speed …

  5. bekomm leider den folgenden fehler?!

    TypeError: Error #2007: Parameter type darf nicht ‘null’ sein.
    at flash.events::EventDispatcher/addEventListener()
    at components::MP3Pitch()[/Users/aM/Documents/workspace/audiotool/team/andre.michelle/fdt/session/Audio2009/src/components/MP3Pitch.as:36]
    at ExampleMP3Pitch()[/Users/aM/Documents/workspace/audiotool/team/andre.michelle/fdt/session/Audio2009/src/ExampleMP3Pitch.as:29]

  6. @dVyper
    you just estimate the pitch and slice the sample accordingly and then overlap+add

    @andre
    not sure if it matters in AS3, but you could save a multiplication in
    ( 1.0 – alpha ) * l0 + alpha * l1 )
    ->
    l0 – alpha* l0 + alpha * l1
    ->
    l0+alpha*(l1-l0)

    but maybe the compiler does already these kind of optimizations.. do you happen to know if this is the case?

  7. Andre you rock! Your implentation of mp3 speed shifting is very elegant.

    I’m wondering, is it possible to use sound.extract() and then manipulate the raw sound data without waiting that the song is completely loaded ?

  8. > you just estimate the pitch and slice the sample accordingly and then overlap+add

    Could you perhaps elaborate on how to time shift without shifting pitch? Or better yet, update this example so that pitch is not effected? :)

    @Adrien W. – yes, it seems you can start extracting before the file completely loads.

  9. In addition to the Speed control, would it be possible to create a second slider to control the pitch? I suppoe it would be similar to what E.G. suggested, but I’m not sure how to code the second slider. Has anyone done both rate and pitch sliders using the Sound API and SampleDataEvent?

  10. @Doug, @jazzairwaves, @dVyper

    I’ve started porting a C++ library (SoundTouch) that does the overlap+add for time-stretching/pitch shifting. It’s pretty rough, but it works and is promising:

    Here’s a demo http://static.ryanberdeen.com/projects/soundtouch-as3/demo/player/stretch.swf

    You can adjust the tempo by dragging the slider. It sounds OK when the tempo is increased. Decreasing the tempo could use some work.

    The source is here: http://github.com/also/soundtouch-as3

    Ryan

  11. @Ryan – that’s exceedingly cool! And even without decreasing tempo, it’s a lot further along than my attempted port of this FFT based routine:

    http://downloads.dspdimension.com/smbPitchShift.cpp

    I seem to be having trouble with very basic AS Number issues – the output has some relation to the input, but there are many artifacts… Will post if I figure it out. Please update if you get lower tempos working. Wouldn’t it be a matter of overlapping copies of each frame?

  12. @Ryan
    Major respect, that’s the most impressive thing I’ve seen in audio with AS3 !
    Looks very promising indeed :)

  13. Hi,

    Anyone know how can i put the buffer when i play dynamic sound(it’s generate from raw sound(mp3 file))

    Thanks
    Bechar

  14. Pingback: Sound Pitch
  15. hey Andre,

    great stuff as always!

    any chance you could point me in the direction to do BPM (Beats Per Minute) analysis for a batch of MP3 files?

    FP 10 is fine too.

    Thanks in advance

  16. Just in case anyone is looking to extend this example to do note based pitch shifting, this formula might be handy:

    _playbackSpeed = Math.exp((Math.log(2)* SEMITONE_SHIFT)/12);

    Hope that helps,

    atom

  17. @Ryan – Superb example of the type of audio control we’ve been struggling to create in Flash for a long time. Thank you for providing the source! Excellent work!

  18. Maybe this will help someone else, the _position variable is the Byte position, not millisecond = \ sometimes I spent way to much time not noticing that

  19. Really great work!

    Im not good at this soundstuff. Is there a way to use this on soundfiles with lower samplerate or any samplerate?

    //Olof

  20. if anybody else would like to play the sound from a certain start position you have to set the position to something like this:

    _position = startTime * 44.1;

    note that the startTime will be the time the mp3 should start playing in milliseconds.

    hope that helps.

  21. Awesome!
    Does anyone know how to play the mp3 in reverse smoothly? Right now I have changed the startposition:

    _position = startTime*44.1;

    and the sound position:

    _position -= scaledBlockSize;

    But it doesn’t play smoothly…

    Thanks

Comments are closed.