audioaiff

How do I swap stereo channels in raw PCM audio data on OS X?


I'm writing audio from an external decoding library on OS X to an AIFF file, and I am able to swap the endianness of the data with OSSwapInt32().

The resulting AIFF file (16-bit PCM stereo) does play, but the left and right channels are swapped.

Would there be any way to swap the channels as I am writing each buffer?

Here is the relevant loop:

do
    {
        xmp_get_frame_info(writer_context, &writer_info);
        if (writer_info.loop_count > 0)
        break;


    writeModBuffer.mBuffers[0].mDataByteSize = writer_info.buffer_size;
    writeModBuffer.mBuffers[0].mNumberChannels = inputFormat.mChannelsPerFrame;

    // Set up our buffer to do the endianness swap
    void *new_buffer;
    new_buffer = malloc((writer_info.buffer_size) * inputFormat.mBytesPerFrame);
    int *ourBuffer = writer_info.buffer;
    int *ourNewBuffer = new_buffer;
    memset(new_buffer, 0, writer_info.buffer_size);
    int i;

    for (i = 0; i <= writer_info.buffer_size; i++)
    {
        ourNewBuffer[i] = OSSwapInt32(ourBuffer[i]);
    };

    writeModBuffer.mBuffers[0].mData = ourNewBuffer;
    frame_size = writer_info.buffer_size / inputFormat.mBytesPerFrame;

    err = ExtAudioFileWrite(writeModRef, frame_size, &writeModBuffer);

} while (xmp_play_frame(writer_context) == 0);

Solution

  • This solution is very specific to 2 channel audio. I chose to do it at the same time you're looping to change the byte ordering to avoid an extra loop. I'm going through the loop 1/2 the number and processing two samples per iteration. The samples are interleaved so I copy from odd sample indexes into even sample indexes and vis-a-versa.

    for (i = 0; i <= writer_info.buffer_size/2; i++)
    {
        ourNewBuffer[i*2] = OSSwapInt32(ourBuffer[i*2 + 1]);
        ourNewBuffer[i*2 + 1] = OSSwapInt32(ourBuffer[i*2]);
    };
    

    An alternative is to use a table lookup for channel mapping.