Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

AudioFileWriter.m now has mutex around file writing to avoid crashes …

…when starting/stopping recording quickly/repeatedly. AudioFileReader.mm also contains the fix for memory exception when stopping (dispatch_suspend was called 3 times), as well as the auto-stop functionality. AudioFileReader.mm can be ignored since it is also in another pull request.
  • Loading branch information...
commit f79b0637b7e903db8175e40387483fc24fe68639 1 parent a4febac
@casbreuk casbreuk authored
Showing with 63 additions and 45 deletions.
  1. +37 −37 Novocaine iOS Example/ViewController.mm
  2. +26 −8 Novocaine/AudioFileWriter.m
View
74 Novocaine iOS Example/ViewController.mm
@@ -167,47 +167,47 @@ - (void)viewWillAppear:(BOOL)animated
// AUDIO FILE READING OHHH YEAHHHH
// ========================================
-// NSURL *inputFileURL = [[NSBundle mainBundle] URLForResource:@"TLC" withExtension:@"mp3"];
-//
-// fileReader = [[AudioFileReader alloc]
-// initWithAudioFileURL:inputFileURL
-// samplingRate:audioManager.samplingRate
-// numChannels:audioManager.numOutputChannels];
-//
-// [fileReader play];
-// fileReader.currentTime = 30.0;
-//
-// [audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels)
-// {
-// [fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels];
-// NSLog(@"Time: %f", fileReader.currentTime);
-// }];
+ NSURL *inputFileURL = [[NSBundle mainBundle] URLForResource:@"TLC" withExtension:@"mp3"];
+
+ fileReader = [[AudioFileReader alloc]
+ initWithAudioFileURL:inputFileURL
+ samplingRate:audioManager.samplingRate
+ numChannels:audioManager.numOutputChannels];
+
+ [fileReader play];
+ fileReader.currentTime = 30.0;
+
+ [audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels)
+ {
+ [fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels];
+ NSLog(@"Time: %f", fileReader.currentTime);
+ }];
// AUDIO FILE WRITING YEAH!
// ========================================
- NSArray *pathComponents = [NSArray arrayWithObjects:
- [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
- @"My Recording.m4a",
- nil];
- NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
- NSLog(@"URL: %@", outputFileURL);
-
- fileWriter = [[AudioFileWriter alloc]
- initWithAudioFileURL:outputFileURL
- samplingRate:audioManager.samplingRate
- numChannels:audioManager.numInputChannels];
-
-
- __block int counter = 0;
- audioManager.inputBlock = ^(float *data, UInt32 numFrames, UInt32 numChannels) {
- [fileWriter writeNewAudio:data numFrames:numFrames numChannels:numChannels];
- counter += 1;
- if (counter > 400) { // roughly 5 seconds of audio
- audioManager.inputBlock = nil;
- [fileWriter release];
- }
- };
+// NSArray *pathComponents = [NSArray arrayWithObjects:
+// [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
+// @"My Recording.m4a",
+// nil];
+// NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
+// NSLog(@"URL: %@", outputFileURL);
+//
+// fileWriter = [[AudioFileWriter alloc]
+// initWithAudioFileURL:outputFileURL
+// samplingRate:audioManager.samplingRate
+// numChannels:audioManager.numInputChannels];
+//
+//
+// __block int counter = 0;
+// audioManager.inputBlock = ^(float *data, UInt32 numFrames, UInt32 numChannels) {
+// [fileWriter writeNewAudio:data numFrames:numFrames numChannels:numChannels];
+// counter += 1;
+// if (counter > 400) { // roughly 5 seconds of audio
+// audioManager.inputBlock = nil;
+// [fileWriter release];
+// }
+// };
}
View
34 Novocaine/AudioFileWriter.m
@@ -25,6 +25,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#import "AudioFileWriter.h"
+#import <pthread.h>
@interface AudioFileWriter()
@@ -43,6 +44,8 @@ @interface AudioFileWriter()
@implementation AudioFileWriter
+static pthread_mutex_t outputAudioFileLock;
+
@synthesize outputFormat = _outputFormat;
@synthesize outputFile = _outputFile;
@synthesize outputBuffer = _outputBuffer;
@@ -79,11 +82,11 @@ - (id)initWithAudioFileURL:(NSURL *)urlToAudioFile samplingRate:(float)thisSampl
// Zero-out our timer, so we know we're not using our callback yet
self.callbackTimer = nil;
-
+
// Open a reference to the audio file
self.audioFileURL = urlToAudioFile;
CFURLRef audioFileRef = (CFURLRef)self.audioFileURL;
-
+
AudioStreamBasicDescription outputFileDesc = {44100.0, kAudioFormatMPEG4AAC, 0, 0, 1024, 0, thisNumChannels, 0, 0};
CheckError(ExtAudioFileCreateWithURL(audioFileRef, kAudioFileM4AType, &outputFileDesc, NULL, kAudioFileFlags_EraseFile, &_outputFile), "Creating file");
@@ -115,8 +118,15 @@ - (id)initWithAudioFileURL:(NSURL *)urlToAudioFile samplingRate:(float)thisSampl
self.outputBuffer = (float *)calloc(2*self.samplingRate, sizeof(float));
self.holdingBuffer = (float *)calloc(2*self.samplingRate, sizeof(float));
- CheckError( ExtAudioFileWriteAsync(self.outputFile, 0, NULL), "Initializing audio file");
-
+ pthread_mutex_init(&outputAudioFileLock, NULL);
+
+ // mutex here //
+ if( 0 == pthread_mutex_trylock( &outputAudioFileLock ) )
+ {
+ CheckError( ExtAudioFileWriteAsync(self.outputFile, 0, NULL), "Initializing audio file");
+ }
+ pthread_mutex_unlock( &outputAudioFileLock );
+
}
return self;
}
@@ -132,13 +142,17 @@ - (void)writeNewAudio:(float *)newData numFrames:(UInt32)thisNumFrames numChanne
outgoingAudio.mBuffers[0].mDataByteSize = numIncomingBytes;
outgoingAudio.mBuffers[0].mData = self.outputBuffer;
- ExtAudioFileWriteAsync(self.outputFile, thisNumFrames, &outgoingAudio);
+ if( 0 == pthread_mutex_trylock( &outputAudioFileLock ) )
+ {
+ ExtAudioFileWriteAsync(self.outputFile, thisNumFrames, &outgoingAudio);
+ }
+ pthread_mutex_unlock( &outputAudioFileLock );
// Figure out where we are in the file
SInt64 frameOffset = 0;
ExtAudioFileTell(self.outputFile, &frameOffset);
self.currentTime = (float)frameOffset / self.samplingRate;
-
+
}
@@ -180,9 +194,9 @@ - (void)configureWriterCallback
// Get audio from the block supplier
[self writeNewAudio:self.outputBuffer numFrames:numSamplesPerCallback numChannels:self.numChannels];
-
+
}
-
+
});
}
@@ -208,7 +222,10 @@ - (void)record;
- (void)stop
{
// Close the
+ pthread_mutex_lock( &outputAudioFileLock );
ExtAudioFileDispose(self.outputFile);
+ pthread_mutex_unlock( &outputAudioFileLock );
+ self.recording = FALSE;
}
- (void)pause
@@ -223,3 +240,4 @@ - (void)pause
@end
+
Please sign in to comment.
Something went wrong with that request. Please try again.