I have been unable to get any of the Core Audio write functions to write data to a sound file. I can read files, view the samples (they are correct), and create a new file with the correct format settings. The write functions do not return any errors, but they fail to write data to the file. I have been struggling with this for a few days and am hoping someone can help. Below is a very simple example. I'm just opening a 16-bit/44.1kHz aiff file and writing it to a new file (no conversions, no processing). What am I doing wrong here?
- (void)saveAudioFileToPath: (NSString*)str
{
ExtAudioFileRef infile, outfile;
OSStatus theErr = noErr;
CFStringRef inPath = CFStringCreateWithCString(NULL,
[str cStringUsingEncoding:NSUTF8StringEncoding],
kCFStringEncodingMacRoman );
CFURLRef inFileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
inPath,
kCFURLPOSIXPathStyle,
false );
CFStringRef outPath = CFStringCreateWithCString(NULL,
"/Users/home/soundfile.aif", /
kCFStringEncodingMacRoman );
CFURLRef outFileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
outPath,
kCFURLPOSIXPathStyle,
false );
theErr = ExtAudioFileOpenURL (inFileURL, &infile);
CheckError(theErr,"Error in saveAudioFileToPath: calling ExtAudioFileOpenURL()");
AudioStreamBasicDescription inFormat = {0};
UInt32 size = sizeof(inFormat);
theErr = ExtAudioFileGetProperty(infile,
kExtAudioFileProperty_FileDataFormat,
&size,
&inFormat);
CheckError(theErr,"Error in saveAudioFileToPath: calling ExtAudioFileGetProperty()");
SInt64 totalNumFrames = 0;
size = sizeof(totalNumFrames);
theErr = ExtAudioFileGetProperty(infile,
kExtAudioFileProperty_FileLengthFrames,
&size,
&totalNumFrames);
CheckError(theErr,"Error in saveAudioFileToPath: calling ExtAudioFileGetProperty()");
SInt16 *audioData = calloc(totalNumFrames, sizeof(SInt16));
AudioBufferList fillBufList;
UInt32 numFrames = (UInt32)totalNumFrames;
while (1) {
fillBufList.mNumberBuffers = 1;
fillBufList.mBuffers[0].mNumberChannels = inFormat.mChannelsPerFrame;
fillBufList.mBuffers[0].mDataByteSize = (UInt32)totalNumFrames * sizeof(SInt16);
fillBufList.mBuffers[0].mData = audioData;
theErr = ExtAudioFileRead (infile, &numFrames, &fillBufList);
CheckError(theErr,"Error in saveAudioFileToPath: calling ExtAudioFileRead()");
if (!numFrames) {
break;
}
}
SInt16 *ptr = fillBufList.mBuffers[0].mData;
SInt16 s;
for(int k = 0; k < numFrames; k++) {
s = CFSwapInt16BigToHost(*ptr);
ptr++;
}
AudioStreamBasicDescription outFormat = {0};
outFormat = inFormat;
outFormat.mReserved = 0;
theErr = ExtAudioFileCreateWithURL (outFileURL,
kAudioFileAIFFType,
&outFormat, NULL,
kAudioFileFlags_EraseFile,
&outfile);
CheckError(theErr,"Error in saveAudioFileToPath: calling ExtAudioFileCreateWithURL()");
size = sizeof(outFormat);
theErr = ExtAudioFileSetProperty(infile,
kExtAudioFileProperty_ClientDataFormat,
size,
&outFormat); /
CheckError(theErr,"Error in saveAudioFileToPath: calling ExtAudioFileSetProperty()");
while(1) {
theErr = ExtAudioFileWrite(outfile, numFrames, &fillBufList);
CheckError(theErr,"Error in saveAudioFileToPath: calling ExtAudioFileWrite()");
if (!numFrames) {
/
break;
}
}
ExtAudioFileDispose(infile);
ExtAudioFileDispose(outfile);
free(audioData);
return;
}