How to use AVAudioTimePitchAlgorithmSpectral?

2.2k views Asked by At

My app includes an audio player that uses AVAudio to play audio files from the iPod music library. I'd like to add a pitch-shifting feature to the player, and the pitch-shifting libraries I've looked at would require writing a new player using a different audio framework.

I'm currently using an AVAudioMix to change the volume in my player, and I noticed that one of the audio input parameters is audioTimePitchAlgorithm, with a constant AVAudioTimePitchAlgorithmSpectral that looks like what I need. The documentation says it supports a variable rate from 1/32 to 32. But I can't figure out how to set that rate.

Here's the code I have so far (based on this SO answer) with an indication of the missing piece:

AVPlayer *player = self.audioPlayer;
NSArray *audioTracks = [player.currentItem.asset tracksWithMediaType:AVMediaTypeAudio];
NSMutableArray *allAudioParams = [NSMutableArray array];
for (AVAssetTrack *track in audioTracks) {
    AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters];
    audioInputParams.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmSpectral;
    audioInputParams.audioTimePitchRate = 0.5; <-- NEED SOMETHING LIKE THIS
    audioInputParams.trackID = [track trackID];
    [allAudioParams addObject:audioInputParams];
}
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
[audioMix setInputParameters:allAudioParams];
[player.currentItem setAudioMix:audioMix];

I've searched Google, the dev forums, the AVFoundation Programming Guide and the framework header files but found nothing more about this. Does anyone know how this is supposed to work?

3

There are 3 answers

2
matt On BEST ANSWER

I'm afraid you may have misapprehended the documentation (due to the infamous "hope springs eternal" effect). AVAudioTimePitchAlgorithmSpectral merely means "when you keep the pitch despite a change in rate, do a really good job of it when this is music". There are two algorithms for keeping pitch while changing rate - one better for voice, one better music. This means "use the music one". It doesn't mean "change the pitch without changing the rate", which is what you are evidently after. AFAICT no such feature is supplied by any built-in Cocoa touch framework.

0
Opiyum On

for AVPlayer:

set audioTimePitchAlgorithm on the player item and adjust the player rate.

player.playerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmSpectral;

Now changes to your players rate will adjust audio pitch.

This should also work for AVAssetExportSession

scale the audio to a new duration and audio will retain the original pitch.

myAVAssetExportSession.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmSpectral; // (AVAssetExportSession's default algorithm)
0
ucangetit On

Actually, I think what you want to look at is the AVAudioTimePitchAlgorithmVarispeed which would change the pitch.

As mentioned in AV Foundation Audio Settings Constants under the section Time Pitch Algorithm Settings

High quality, no pitch correction. Pitch varies with rate. Variable rate from 1/32 to 32.

Also, you only need to do something like this

AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
playerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmVarispeed;
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
[player play];

As referenced in this SO article