Hypergater
Hypergater

Reputation: 649

Changing Voice Pitch using AVAudioPlayer

I have an app that repeats back what you say, however, rather than just repeat your own voice, I was hoping I could get it to pitch it lower or higher, is this possible?

Method is here;

-(void)playOnMainThread:(id)param
{
    if (!outUrl) {
        return;
    }
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:&error];
    if (error)
        NSLog(@"AVAudioPlayer error %@, %@", error, [error userInfo]);

    player.delegate = self;
    [player setVolume:10.0];
    [player play];
}

Upvotes: 2

Views: 1497

Answers (2)

Rahul Patel
Rahul Patel

Reputation: 1832

So this is how it will be done. You will be needing a couple of things to start off

First import <AVFoundation/AVFoundation.h>

Then in .h file

AVAudioEngine *audioEngine;
AVAudioPlayerNode *playerNode;
AVAudioFile *avAudioFile;
AVAudioUnitTimePitch *pitch;
AVAudioMixerNode *mixer;

You will be needing these things.

Then in .m file

-(void)allocInitRecorders
{
    audioEngine = [[AVAudioEngine alloc] init];
    playerNode = [[AVAudioPlayerNode alloc] init];
    pitch = [[AVAudioUnitTimePitch alloc] init];
    mixer = [[AVAudioMixerNode alloc] init];

    [audioEngine stop];
    [playerNode stop];
    [audioEngine reset];

}


-(void)emptytheRecorders
{
    audioEngine = nil;
    playerNode = nil;

}


-(void)attachingNodes
{

[audioEngine attachNode:playerNode];

[audioEngine attachNode:pitch];
mixer = [audioEngine mainMixerNode];
[audioEngine connect:playerNode to:pitch format:[avAudioFile processingFormat]];
[audioEngine connect:pitch to:mixer format:[avAudioFile processingFormat]];

}


-(NSString *)filePathOfCollaboratedAudio
{


NSString* filePath = [[NSBundle mainBundle] pathForResource:@"Recording"
                                                     ofType:@"m4a"];

return filePath;
}

-(void)playAudio
{

NSError *err = nil;



[self emptytheRecorders];
[self allocInitRecorders];
[self attachingNodes];




BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[self filePathOfCollaboratedAudio]];



if (fileExists)
{
    avAudioFile = [[AVAudioFile alloc] initForReading:[NSURL URLWithString:[self filePathOfCollaboratedAudio]] error:&err];
}


pitch.pitch = 1000;

[audioEngine prepare];
[audioEngine startAndReturnError:&err];

NSError *error;

AVAudioPCMBuffer *buffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:avAudioFile.processingFormat frameCapacity:(AVAudioFrameCount)avAudioFile.length];

[avAudioFile readIntoBuffer:buffer error:&error];



[playerNode scheduleBuffer:buffer atTime:nil options:AVAudioPlayerNodeBufferInterruptsAtLoop completionHandler:^{


}];


if (err != nil) {
    NSLog(@"An error occured");
}
else
{

    [playerNode play];


}
}

Then just call the method

[self playAudio];

and its done

Upvotes: 2

Duncan C
Duncan C

Reputation: 131398

I don't know of a way to do that using AVAudioPlayer. You'll need to use a lower level framework like audio units. What you describe (changing the pitch without speeding up the audio) is actually quite complex mathematically.

Upvotes: 0

Related Questions