I need to record audio stream with iPhone mic. I am using AVAudioRecorder from this thing.
I initialize AVAR in init:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [[paths objectAtIndex:0] retain];
NSError *error;
BOOL isDir = NO;
if (! [[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&isDir] && isDir == NO) {
[[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:NO attributes:nil error:&error];
}
pathNewFile= [cachePath stringByAppendingPathComponent:@"123.caf"];
NSLog(@"%@",pathNewFile);
NSDictionary *settings=[[NSDictionary alloc]initWithObjectsAndKeys:
[NSNumber numberWithFloat:44100.0f],AVSampleRateKey,
[NSNumber numberWithInt:kAudioFormatAppleLossless],AVFormatIDKey,
[NSNumber numberWithInt:1],AVNumberOfChannelsKey,
[NSNumber numberWithInt:AVAudioQualityMax],AVEncoderAudioQualityKey, nil];
recorder=[[AVAudioRecorder alloc] initWithURL:[NSURL URLWithString:pathNewFile] settings:settings error:nil];
[recorder prepareToRecord];
And I start recording when user presses the rec-button:
-(void)recButton:(id)sender{
NSLog(@"start rec");
[rootNotesButton setTitle:@"Stop" forState:UIControlStateNormal];
[rootNotesButton removeTarget:self action:@selector(recButton:) forControlEvents:UIControlEventTouchUpInside];
[rootNotesButton addTarget:self action:@selector(stopButton:) forControlEvents:UIControlEventTouchUpInside];
[recorder record];
}
-(void)stopButton:(id)sender{
NSLog(@"stop rec");
[rootNotesButton setTitle:@"Play" forState:UIControlStateNormal];
[rootNotesButton removeTarget:self action:@selector(stopButton:) forControlEvents:UIControlEventTouchUpInside];
[rootNotesButton addTarget:self action:@selector(playButton:) forControlEvents:UIControlEventTouchUpInside];
[recorder stop];
}
-(void)playButton:(id)sender{
NSLog(@"play rec");
[rootNotesButton setTitle:@"Stop" forState:UIControlStateNormal];
[rootNotesButton removeTarget:self action:@selector(playButton:) forControlEvents:UIControlEventTouchUpInside];
[rootNotesButton addTarget:self action:@selector(stopPButton:) forControlEvents:UIControlEventTouchUpInside];
player=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:pathNewFile] error:nil];
[player play];
}
-(void)stopPButton:(id)sender{
NSLog(@"Stop play");
[rootNotesButton setTitle:@"Play" forState:UIControlStateNormal];
[rootNotesButton removeTarget:self action:@selector(stopPButton:) forControlEvents:UIControlEventTouchUpInside];
[rootNotesButton addTarget:self action:@selector(playButton:) forControlEvents:UIControlEventTouchUpInside];
[player stop];
}
But when I try to run my project in simulator: My debugger stops on string: recorder=[[AVAudioRecorder alloc] initWithURL:[NSURL URLWithString:pathNewFile] settings:settings error:nil]; Without any signal or error.
The problem seems to be with writing to cachePath
in the Simulator. I tried this and it worked:
#if TARGET_IPHONE_SIMULATOR
NSString *cachePath = @"/tmp";
#else
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [[paths objectAtIndex:0] retain];
#endif
You have a couple memory leaks:
You are retaining cachePath
but not releasing it. There's actually no reason to retain it in the first place.
You are creating player
with +alloc/-init
in playButton
which means you own it but you are not releasing it (at least not in the posted code). If you are defining it as a property
you need to use self.player = …
in order for it to be properly retained and released.
You are creating settings
with +alloc/-init
but not releasing it. There's no reason to do that. You can create it like this instead:
NSDictionary *settings=[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:44100.0f],AVSampleRateKey,
[NSNumber numberWithInt:kAudioFormatAppleLossless],AVFormatIDKey,
[NSNumber numberWithInt:1],AVNumberOfChannelsKey,
[NSNumber numberWithInt:AVAudioQualityMax],AVEncoderAudioQualityKey, nil];
You need to retain pathNewFile
because stringByAppendingPathComponent
returns an autoreleased string and you are using it in other methods of your class.