Audio quality on custom rate

hi, i have a simple avaudioplayer, wich runs with a custom rate from -16% to +16%.

If the rate is not exactly 1.0 the Sound quality is really bad.

i tried 48khz aiff and wav format And set a 48khz sample rate To my Audio Session as well.


quality is still bad...

can anyone help me?

Accepted Reply

There's been a couple of posts recently regarding "Time" units for audio playback and how they affect overall sound quality.


http://forums.developer.apple.com/message/16043 & http://forums.developer.apple.com/message/13026


In your case an AVAudioPlayer is being used - that's great - what this really means is that you're using Audio Queue Services for playback because AVAudioPlayer is using Audio Queue Services on your behalf.


What AVAudioPlayer is doing is setting the kAudioQueueProperty_TimePitchAlgorithm property of the playback queue object to kAudioQueueTimePitchAlgorithm_TimeDomain and because it doesn't expose this property to you, you can't change it -- you get what you get.


The header comment for this setting indicates the following hint about quality "Modest quality, less expensive. Suitable for voice" and messing around with sample rates isn't really going to get you anywhere in this context. If you want to higest quality available you'll need a different way to ask for that.


Ok great so where does it leave you? Well, there's a couple of solutions:

  1. Use the Audio Toolbox Audio Queue C API for playback - allows you full control, and set the algorithm of your choice like kAudioQueueTimePitchAlgorithm_Spectral which will sound better (see previously mentioned forum posts). Cons include requiring way more code since you are on the hook to manage all the playback setup/buffering and so on. On the positive side, we do have a Programming Guide for this API, yay! http://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/Introduction/Introduction.html
  2. Use AVPlayer (not to be confused with the AVAudioPlayer) - AVFoundation provides the AVPlayer and AVPlayerItem. Some quick poking around in the reference and headers shows that a property of an AVPlayer is
    rate
    , allowing for that playback rate change, and there's a property of AVPlayerItem called
    audioTimePitchAlgorithm
    allowing a change of the items
    Time Pitch Algorithm Settings
    giving you access to the same settings discussed in the previous forum posts. For example, you can use AVAudioTimePitchAlgorithmSpectral for the highest quality playback instead of sticking with the default or what AVAudioPlayer is using (the "modest quality" setting). Modifying the AVPlayerDemo sample and quickly messing around with these settings and varying the rate around produces a huge difference in audio quality between the default AVAudioTimePitchAlgorithmLowQualityZeroLatency and AVAudioTimePitchAlgorithmSpectral as you would expect. Pros, less code than the C API, gives you access to settings that may help you, detailed sample code available so should be easy to incorporate into your existing project that uses AVAudioPlayer. Cons, a little more code that AVAudioPlayer, not quite as easy to use but easier that the AudioQueue (AVAudioPlayer is dead simple), so you would expect a little more work for greater flexibility.


Here's the URL to the AVPlayerDemo http://developer.apple.com/library/ios/samplecode/AVPlayerDemo/Introduction/Intro.html and code changes to test this were trivial:


In AVPlayerDemoPlaybackViewController.m add to the AVPlayerItemStatusReadyToPlay case...

AVPlayerItem *playerItem = (AVPlayerItem *)object;
playerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmSpectral;


Then set the rate to some test value in the play IBAction in the same .m file...

[self.mPlayer play];
[self showStopButton];
[self.mPlayer setRate:4.0f]; // or 2x or 6x or...


Listen...hear what you get.

Replies

There's been a couple of posts recently regarding "Time" units for audio playback and how they affect overall sound quality.


http://forums.developer.apple.com/message/16043 & http://forums.developer.apple.com/message/13026


In your case an AVAudioPlayer is being used - that's great - what this really means is that you're using Audio Queue Services for playback because AVAudioPlayer is using Audio Queue Services on your behalf.


What AVAudioPlayer is doing is setting the kAudioQueueProperty_TimePitchAlgorithm property of the playback queue object to kAudioQueueTimePitchAlgorithm_TimeDomain and because it doesn't expose this property to you, you can't change it -- you get what you get.


The header comment for this setting indicates the following hint about quality "Modest quality, less expensive. Suitable for voice" and messing around with sample rates isn't really going to get you anywhere in this context. If you want to higest quality available you'll need a different way to ask for that.


Ok great so where does it leave you? Well, there's a couple of solutions:

  1. Use the Audio Toolbox Audio Queue C API for playback - allows you full control, and set the algorithm of your choice like kAudioQueueTimePitchAlgorithm_Spectral which will sound better (see previously mentioned forum posts). Cons include requiring way more code since you are on the hook to manage all the playback setup/buffering and so on. On the positive side, we do have a Programming Guide for this API, yay! http://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/Introduction/Introduction.html
  2. Use AVPlayer (not to be confused with the AVAudioPlayer) - AVFoundation provides the AVPlayer and AVPlayerItem. Some quick poking around in the reference and headers shows that a property of an AVPlayer is
    rate
    , allowing for that playback rate change, and there's a property of AVPlayerItem called
    audioTimePitchAlgorithm
    allowing a change of the items
    Time Pitch Algorithm Settings
    giving you access to the same settings discussed in the previous forum posts. For example, you can use AVAudioTimePitchAlgorithmSpectral for the highest quality playback instead of sticking with the default or what AVAudioPlayer is using (the "modest quality" setting). Modifying the AVPlayerDemo sample and quickly messing around with these settings and varying the rate around produces a huge difference in audio quality between the default AVAudioTimePitchAlgorithmLowQualityZeroLatency and AVAudioTimePitchAlgorithmSpectral as you would expect. Pros, less code than the C API, gives you access to settings that may help you, detailed sample code available so should be easy to incorporate into your existing project that uses AVAudioPlayer. Cons, a little more code that AVAudioPlayer, not quite as easy to use but easier that the AudioQueue (AVAudioPlayer is dead simple), so you would expect a little more work for greater flexibility.


Here's the URL to the AVPlayerDemo http://developer.apple.com/library/ios/samplecode/AVPlayerDemo/Introduction/Intro.html and code changes to test this were trivial:


In AVPlayerDemoPlaybackViewController.m add to the AVPlayerItemStatusReadyToPlay case...

AVPlayerItem *playerItem = (AVPlayerItem *)object;
playerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmSpectral;


Then set the rate to some test value in the play IBAction in the same .m file...

[self.mPlayer play];
[self showStopButton];
[self.mPlayer setRate:4.0f]; // or 2x or 6x or...


Listen...hear what you get.

thank you, this was exactly what i was searching for.


it works Fine but now ive got a rreally Bad performance if i change for example the rate While the avplayer is Playing.

is there a way to preload the complete playeritem for Beter performance or does this depends on the recalculation of the rate?