Done. Sound is completely garbled from the speakers now, so I changed the sample generation code from this, which was working fine although you make me suspect that was more luck than judgement:
- (OSStatus) stereoGenerateSamples:(AudioBufferList *) buffers frames:(int) numFrames
{
AudioBuffer *leftAudioBuffer = &buffers->mBuffers[0];
AudioBuffer *rightAudioBuffer = &buffers->mBuffers[1];
SInt32 *leftData = (SInt32 *) leftAudioBuffer->mData;
SInt32 *rightData = (SInt32 *) rightAudioBuffer->mData;
engine->getStereoSamples(_tmpBuf, numFrames);
for (int i = 0; i < numFrames; ++i) {
leftData[i] = _tmpBuf[i].left * 16777216L; // _tmpBuf contains structs { float left; float right; }
rightData[i] = _tmpBuf[i].right * 16777216L;
}
return noErr;
}
- (OSStatus) stereoGenerateSamples:(AudioBufferList *) buffers frames:(int) numFrames
{
AudioBuffer *leftAudioBuffer = &buffers->mBuffers[0];
AudioBuffer *rightAudioBuffer = &buffers->mBuffers[1];
SInt16 *leftData = (SInt16 *) leftAudioBuffer->mData;
SInt16 *rightData = (SInt16 *) rightAudioBuffer->mData;
engine->getStereoSamples(_tmpBuf, numFrames);
for (int i = 0; i < numFrames; ++i) {
leftData[i] = _tmpBuf[i].left * INT16_MAX;
rightData[i] = _tmpBuf[i].right * INT16_MAX;
}
return noErr;
}
It sounds very cool, but not the actual simple waveforms it should be.
This method here (stereoGenerateSamples) is called by the callback you've been looking at. For context:
OSStatus auRenderCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
TKCoreAudioBridge * output = (__bridge TKCoreAudioBridge *) inRefCon;
return [output getGeneratedSamples:ioData frames:inNumberFrames];
}
- (OSStatus) getGeneratedSamples:(AudioBufferList *) ioData frames:(UInt32) numFrames
{
OSStatus result = [self.delegate generateSamples:ioData frames:numFrames]; // This is the first method I posted
if (_isRecording) {
SInt16 *intlvData = (SInt16 *) _tmpBuf.mData;
SInt16 *leftSrcData = (SInt16 *) ioData->mBuffers[0].mData;
SInt16 *rightSrcData = (SInt16 *) ioData->mBuffers[1].mData;
_tmpBuf.mDataByteSize = sizeof(AudioSampleType) * numFrames * 2;
// Interleave
int l = 0;
int r = 1;
for (int i = 0; i < numFrames; i++) {
intlvData[l] = leftSrcData[i];
intlvData[r] = rightSrcData[i];
l += 2;
r += 2;
}
checkError(ExtAudioFileWriteAsync(_recFileRef,
numFrames,
&_tmpABL),
"ExtAudioFileWriteAsync failed", false);
}
return result;
}