Unable to get Core Audio to write data to file

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;

}

Accepted Reply

Just to clarify, despite the method name, the string being passed into the method is actually the path to the input file. The path to the output file is hard-coded in the method itself. This is a result of me ripping the code apart as I try to get this working. I also want to add that I'm trying to read very short files so this is why the buffer size is the entire length of the file. I have also tried using a smaller buffer and reading the file in fragments with code copied directly from the AudioToolboxConverter sample code... same issue. I have also tried using Audio File Services functions instead of Extended Audio File Services... same issue. I'm wondering if the problem could be something other than Core Audio. I have App Sandboxing off in xCode and so I'm not doing anything with entitlements. Those aren't necessary with Sandboxing off, right? Plus, I am able to create a file and write to it using standard C file io from this same application.

Replies

Just to clarify, despite the method name, the string being passed into the method is actually the path to the input file. The path to the output file is hard-coded in the method itself. This is a result of me ripping the code apart as I try to get this working. I also want to add that I'm trying to read very short files so this is why the buffer size is the entire length of the file. I have also tried using a smaller buffer and reading the file in fragments with code copied directly from the AudioToolboxConverter sample code... same issue. I have also tried using Audio File Services functions instead of Extended Audio File Services... same issue. I'm wondering if the problem could be something other than Core Audio. I have App Sandboxing off in xCode and so I'm not doing anything with entitlements. Those aren't necessary with Sandboxing off, right? Plus, I am able to create a file and write to it using standard C file io from this same application.