views:

683

answers:

2

What are the different ways to change the playback speed of audio on the iPhone, when using Audio Units? What are the advantages / disadvantages of each solution?

I have a mixer unit and an IO unit. Do I need to add another unit (eg. converter unit)? What audio unit parameters should I set, on which (input or output) bus on which audio unit(s)?

My current setup:

       -------------------------              -------------------------
       |      mixer unit       | -----------> |        IO unit        |
       -------------------------              -------------------------
+1  A: 

All of the below solutions will alter the pitch of your audio (along with the playback speed). To correct the pitch of your audio after the playback speed has been changed you'll need to use a 3rd party audio library (such as SoundTouch, which has an LGPL license, so you can use it in your app, without making it open-source). There is an audio unit (AUPitch), that can change the pitch of your audio, but it's not available for iPhone; only for Mac.

All of the solutions below are tested, and work...

Solution #1 [Best solution]

3D Mixer Unit: Instead of a Multichannel Mixer unit use a 3D Mixer unit and set the k3DMixerParam_PlaybackRate on the input scope.

Advantages: k3DMixerParam_PlaybackRate can be set real-time, while you are playing audio, without any clipping sounds or other side effects. It's also easy to implement once you have audio units going.

Disadvantages: Affects the pitch of your audio, but the difference in pitch is not really noticeable if you only need to alter the playback rate by +/- 8%.

Solution #2

Changing sample rate: Change the sample rate on the output bus of the mixer unit. Changing the sample rate works very similarly to adding and removing samples.

Advantages: Works well if you want to multiply the playback speed by a fraction of an integer (1.2x for example).

Disadvantages: Changing the sample rate of the mixer output can't be set on the fly; only when initializing the mixer unit. Affects the pitch of your audio, but the difference in pitch is not really noticeable if you only need to alter the playback rate by +/- 8%.

audioDescriptionMixerOutput.mSampleRate = 1.2*kGraphSampleRate;

Solution #3

Add/remove samples: Only pass every second, third, ... audio sample to the input of your audio unit (mixer unit in my case) in your render callback function.

Advantages: Works well if you want to speed up or slow down your audio playback by 2x, 3x, 4x, etc. It's also easy to implement.

Disadvantages: You can only multiply the playback speed by an integer factor. Speeding up audio playback by 1.2x for example is not possible by adding or removing samples. Affects the pitch of your audio.

Tom Ilsinszki
A: 

Has anyone actually got Solution #1 working on an iPhone? I can't find any examples of this working or anyone else who claims to have it working. I have audio units working to some degree, but I have not been able to use 3dMixer to change playback pitch successfully.

Paul Slocum
I think this should be a comment on the answer and not an answer, anyways... I'm not sure what you are trying to do, but you can only use Solution #1 to change the playback speed of your audio, but this will also alter the pitch of your audio. (As an example: if you speed up the track the pitch will get really high.) So you would need a way to correct the pitch after speeding up or slowing down your audio.
Tom Ilsinszki
It doesn't give me the option to add a comment to other posts, which is why I posted it as a new solution. Yes, I understand that this is a basic linear resampling and the pitch will be affected, however I can't get it to work. I just want to find someone else who has confirmed this is possible on the IPHONE (I know that it works on MacOS) so that I'm not spending all my time trying to do something that isn't possible. ...and sample code would be greatly appreciated too if possible.
Paul Slocum
I confirmed that it does work.
Paul Slocum