Reputation: 649
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
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
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