UPDATE: I have figured this out and posted my solution as an answer to my own question (below)
I am trying to write a simple buffer of audio samples to a file using ExtAudioFileWrite in AAC format.
I have achieved this with the code below to write a mono buffer to a .wav file - however, I cannot do this for stereo or for AAC files which is what I want to do.
Here is what I have so far...
CFStringRef fPath;
fPath = CFStringCreateWithCString(kCFAllocatorDefault,
"/path/to/my/audiofile/audiofile.wav",
kCFStringEncodingMacRoman);
OSStatus err;
int mChannels = 1;
UInt32 totalFramesInFile = 100000;
Float32 *outputBuffer = (Float32 *)malloc(sizeof(Float32) * (totalFramesInFile*mChannels));
////////////// Set up Audio Buffer List ////////////
AudioBufferList outputData;
outputData.mNumberBuffers = 1;
outputData.mBuffers[0].mNumberChannels = mChannels;
outputData.mBuffers[0].mDataByteSize = 4 * totalFramesInFile * mChannels;
outputData.mBuffers[0].mData = outputBuffer;
Float32 audioFile[totalFramesInFile*mChannels];
for (int i = 0;i < totalFramesInFile*mChannels;i++)
{
audioFile[i] = ((Float32)(rand() % 100))/100.0;
audioFile[i] = audioFile[i]*0.2;
}
outputData.mBuffers[0].mData = &audioFile;
CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,fPath,kCFURLPOSIXPathStyle,false);
ExtAudioFileRef audiofileRef;
// WAVE FILES
AudioFileTypeID fileType = kAudioFileWAVEType;
AudioStreamBasicDescription clientFormat;
clientFormat.mSampleRate = 44100.0;
clientFormat.mFormatID = kAudioFormatLinearPCM;
clientFormat.mFormatFlags = 12;
clientFormat.mBitsPerChannel = 16;
clientFormat.mChannelsPerFrame = mChannels;
clientFormat.mBytesPerFrame = 2*clientFormat.mChannelsPerFrame;
clientFormat.mFramesPerPacket = 1;
clientFormat.mBytesPerPacket = 2*clientFormat.mChannelsPerFrame;
// open the file for writing
err = ExtAudioFileCreateWithURL((CFURLRef)fileURL, fileType, &clientFormat, NULL, kAudioFileFlags_EraseFile, &audiofileRef);
if (err != noErr)
{
cout << "Problem when creating audio file: " << err << "\n";
}
// tell the ExtAudioFile API what format we'll be sending samples in
err = ExtAudioFileSetProperty(audiofileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(clientFormat), &clientFormat);
if (err != noErr)
{
cout << "Problem setting audio format: " << err << "\n";
}
UInt32 rFrames = (UInt32)totalFramesInFile;
// write the data
err = ExtAudioFileWrite(audiofileRef, rFrames, &outputData);
if (err != noErr)
{
cout << "Problem writing audio file: " << err << "\n";
}
// close the file
ExtAudioFileDispose(audiofileRef);
NSLog(@"Done!");
My specific questions are:
- How do I set up the AudioStreamBasicDescription for AAC?
- Why can't I get stereo to work properly here? If I set the number of channels ('mChannels') to 2 then I get the left channel correctly and distortion in the right channel.
I'd very much appreciate any help - I think I've read almost every page I can find on this and am none the wiser as, while there are similar questions, they usually derive the AudioStreamBasicDescription parameters from some input audio file, which I cannot see the result of. The Apple documentation is no help either.
Many thanks in advance,
Adam