I do this in my AUGraph's input callback, maybe someone else has a better/cleaner approach:
void MultiplyFirstChannelInAudioBufferList(AudioBufferList *audioBufferList,
UInt32 bytesPerFrame)
{
UInt32 numberOfBuffers = audioBufferList->mNumberBuffers;
if (numberOfBuffers == 1) {
AudioBuffer *audioBuffer = &audioBufferList->mBuffers[0];
UInt32 numberOfChannels = audioBuffer->mNumberChannels;
if (numberOfChannels > 1) {
UInt32 bytesPerMultiChannelFrame = numberOfChannels * bytesPerFrame;
UInt32 numberOfMultiChannelFrames = audioBuffer->mDataByteSize / bytesPerMultiChannelFrame;
// get the offset for the current frame
for (NSUInteger multiChannelFrameIndex = 0; multiChannelFrameIndex < numberOfMultiChannelFrames; multiChannelFrameIndex++) {
NSUInteger frameFirstChannelByteOffset = multiChannelFrameIndex * bytesPerMultiChannelFrame;
// get the offset for the current channel within the current frame
for (NSUInteger channelIndex = 1; channelIndex < numberOfChannels; channelIndex++) {
NSUInteger frameChannelByteOffset = frameFirstChannelByteOffset + channelIndex * bytesPerFrame;
// copy the data
memcpy((UInt8 *)audioBuffer->mData + frameChannelByteOffset,
(UInt8 *)audioBuffer->mData + frameFirstChannelByteOffset,
bytesPerFrame);
}
}
}
} else if (numberOfBuffers > 0) {
UInt32 dataByteSize = audioBufferList->mBuffers[0].mDataByteSize;
for (NSUInteger bufferIndex = 1; bufferIndex < numberOfBuffers; bufferIndex++) {
if (audioBufferList->mBuffers[bufferIndex].mDataByteSize == dataByteSize) {
memcpy(audioBufferList->mBuffers[bufferIndex].mData,
audioBufferList->mBuffers[0].mData,
dataByteSize);
}
}
}
}