Here's a suitable AudioStreamBasicDescription for mono SInt16:
mSampleRate 44100.000000
mFormatFlags kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved
mFormatID kAudioFormatLinearPCM
mFramesPerPacket 1
mBytesPerFrame 2
mChannelsPerFrame 1
mBitsPerChannel 16
mBytesPerPacket 2
But, I think (not 0 sure) that the effect units want stereo floats:
One way to get the right format is to do an AudioUnitGetProperty on the input of the "downstream" unit and then set the output of the upstream unit to that format;
But here is a stere float one anyway:
mSampleRate 44100.000000
mFormatFlags kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsPacked
mFormatID kAudioFormatLinearPCM
mFramesPerPacket 1
mBytesPerFrame 4
mChannelsPerFrame 2
mBitsPerChannel 32
mBytesPerPacket 4
I was able to get an offline render going, I wasn't quite there in my current project but knew I would be soon so I'm in the same boat. I found a really good answer that sums it up on Stack Overflow:
http://stackoverflow.com/questions/15297990/core-audio-offline-rendering-genericoutput
but I'll paste in the most relevant section here in case the link dies:
AudioUnitRenderActionFlags flags = 0;
AudioTimeStamp inTimeStamp;
memset(&inTimeStamp, 0, sizeof(AudioTimeStamp));
inTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
UInt32 busNumber = 0;
UInt32 numberFrames = 512;
inTimeStamp.mSampleTime = 0;
int channelCount = 2;
int totFrms = MaxSampleTime;
while (totFrms > 0)
{
if (totFrms < numberFrames)
{
numberFrames = totFrms;
NSLog(@"Final numberFrames :%li",numberFrames);
}
else
{
totFrms -= numberFrames;
}
AudioBufferList *bufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList)+sizeof(AudioBuffer)*(channelCount-1));
bufferList->mNumberBuffers = channelCount;
for (int j=0; j<channelCount; j++)
{
AudioBuffer buffer = {0};
buffer.mNumberChannels = 1;
buffer.mDataByteSize = numberFrames*sizeof(AudioUnitSampleType);
buffer.mData = calloc(numberFrames, sizeof(AudioUnitSampleType));
bufferList->mBuffers[j] = buffer;
}
CheckError(AudioUnitRender(mGIO,
&flags,
&inTimeStamp,
busNumber,
numberFrames,
bufferList),
"AudioUnitRender mGIO");
}
In my test demo I tried looping through some audio in multiple passes, if you are going to do this you must increment the mSampleTime of the AudioTimeStamp each render as per the documentation.
Dave