AVAudioUnitTimePitch Algorithm

I don't see a way to change the algorithm that AVAudioUnitTimePitch uses? It appears to be directly equivalent to the AVAudioTimePitchAlgorithmSpectral one available in AVPlayer. The problem is that's only suitable for music, for voice you want AVAudioTimePitchAlgorithmTimeDomain instead.


I don't see a way to change this in the API. Has anyone written their own Unit that does this for AVAudioEngine or know of a way to change it?

Accepted Reply

There is a subtle "trick" going on under the covers here. When you create a AVAudioUnitTimePitch AU, what you get back is the kAudioUnitSubType_NewTimePitch audio unit, this is the same AU that is used when someone selects the kAudioQueueTimePitchAlgorithm_Spectral TimePitchAlgorithm property in the AudioQueue and as you correctly point out, equates to AVAudioTimePitchAlgorithmSpectral for AVPlayer.


If you would like to use a different time effect, for example the kAudioUnitSubType_AUiPodTimeOther or if you're on iOS the kAudioUnitSubType_AUiPodTime -- you can do so by creating an AVAudioUnitTimeEffect using the initWithAudioComponentDescription:(AudioComponentDescription)audioComponentDescription method.


Just pass in a AudioComponentDescription for the kAudioUnitType_FormatConverter type + SubType etc. and you have an object that can be used with AVAudioEngine wrapping the Audio Unit of your choice underneath. See AUComponents.h for a list of SubTypes.

Replies

There is a subtle "trick" going on under the covers here. When you create a AVAudioUnitTimePitch AU, what you get back is the kAudioUnitSubType_NewTimePitch audio unit, this is the same AU that is used when someone selects the kAudioQueueTimePitchAlgorithm_Spectral TimePitchAlgorithm property in the AudioQueue and as you correctly point out, equates to AVAudioTimePitchAlgorithmSpectral for AVPlayer.


If you would like to use a different time effect, for example the kAudioUnitSubType_AUiPodTimeOther or if you're on iOS the kAudioUnitSubType_AUiPodTime -- you can do so by creating an AVAudioUnitTimeEffect using the initWithAudioComponentDescription:(AudioComponentDescription)audioComponentDescription method.


Just pass in a AudioComponentDescription for the kAudioUnitType_FormatConverter type + SubType etc. and you have an object that can be used with AVAudioEngine wrapping the Audio Unit of your choice underneath. See AUComponents.h for a list of SubTypes.

Thanks! That seems to work great. Just to confirm it would look something like this, right?


var componentDescription = AudioComponentDescription()
componentDescription.componentType = kAudioUnitType_FormatConverter
componentDescription.componentSubType = kAudioUnitSubType_AUiPodTime
let timePitch = AVAudioUnitTimePitch(audioComponentDescription: componentDescription)
timePitch.rate = 1.5

Looks good. One thing, I would also fill in the componentManufacturer of the AudioComponentDescription with kAudioUnitManufacturer_Apple.