RemoteIO recorded audio file is either silent or 4KB
-
24-06-2021 - |
Domanda
I'm using RemoteIO successfully to perform analysis on the incoming audio stream from the mic. I can't seem to get a file written to disk, though. I've read around a number of questions:
- Example of saving audio from RemoteIO?,
- AudioBufferList contents in remoteIO audio unit playback callback,
- Recording to AAC from RemoteIO: data is getting written but file unplayable
- Recording from RemoteIO: resulting .caf is pitch shifted slower + distorted
And tried to implement the suggestions there: Except they're not working. Where's the correct place to call ExtAudioFileWriteAsync, and how do I set it up?
Soluzione
Aside from the (fairly arduous but better covered by Apple's example code) setup process of RemoteIO itself, the key points of insight were:
- Using the same
AudioStreamBasicDescription
(*audioFormat
) that I used to set up the stream in the first place. I don't know how long I spent trying to set up a new one with slightly different parameters, based on other questions and posts. Just referencing the stream attributes from my ivar was sufficient. - Set an "isRecording" bool so that you can turn on and off write-to-file without having to tear down and re-set-up your RemoteIO session
- It is ok to write to a file in the
recordingCallback
, um, callback, but do it asynchronously. Lots of info talks about doing it in the playbackCallback or setting up some third audioFileWriteCallback. This resulted in silent files or 4KB (i.e. empty) files. Don't do it. - Also, be sure to use a copy of the ioData that got passed into the callback
in recordingCallback
after AudioUnitRender
into bufferList
:
AudioDeviceManager* THIS = (__bridge AudioDeviceManager *)inRefCon;
if (THIS->isRecording) {
ExtAudioFileWriteAsync(THIS->extAudioFileRef, inNumberFrames, bufferList);
}
- Start and stop recording functions, for reference:
-(void)startRecording {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *destinationFilePath = [documentsDirectory stringByAppendingPathComponent:kAudioFileName];
CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false);
OSStatus status;
// create the capture file
status = ExtAudioFileCreateWithURL(destinationURL, kAudioFileWAVEType, &audioFormat, NULL, kAudioFileFlags_EraseFile, &extAudioFileRef);
if (status) NSLog(@"Error creating file with URL: %ld", status);
// use the same "audioFormat" AudioStreamBasicDescription we used to set up RemoteIO in the first place
status = ExtAudioFileSetProperty(extAudioFileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &audioFormat);
ExtAudioFileSeek(extAudioFileRef, 0);
ExtAudioFileWrite(extAudioFileRef, 0, NULL);
isRecording = YES;
}
- (void)stopRecording {
isRecording = NO;
OSStatus status = ExtAudioFileDispose(extAudioFileRef);
if (status) printf("ExtAudioFileDispose %ld \n", status);
}
That's it!
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow