Reordering channels without copying data?


#1

I’ve been trying to reorder the channels within a multichannel plugin i’ve been developing recently, in a manner exemplified by this little snippet:

http://coliru.stacked-crooked.com/a/80efa85621007dfb
(ignore the reference in the method signature, i was just testing if it makes any difference …)

So i’ve been trying to re-organise the pointers to get around the copying operation. Only now i’ve read that you shouldn’t modify the pointers returned by AudioBuffer::getArrayOfWritePointers() .

In my snippet, it works, but within the plugin it doesn’t have any effect at all.

So, i assume there’s no other way to re-order channels than copying them ?

Best,
n


#2

The buffer passed to your plugin in processBlock is provided by the DAW, the AudioBuffer object containing it is just a JUCE-style wrapper around that raw memory location which contains some more information about the content and some handy functions for manipulating the data. However, afaik a plugin has no ability to tell the host where it should look up the output data for each channel filled by the plugin. The host just expects the plugin to place the output samples right where the input samples were located to re-map them into the hosts channel-system after the plugin has processed the channel. So I think there is no way around copying the samples twice if you’d build a simple channel-remap plugin, first to a temporary buffer and then from there back in a rearranged order to the original buffer.

But, there are a lot of more CPU-consuming tasks plugins out there do, so the performance impact of this solution might be really acceptable :wink:


#3

If you’re talking about reordering the data for a host instead of internally, you need to swap the data, not the pointers. This kind of highlights what a host could be doing behind the scenes:

    void swap_channels (float** buffer, int num_samples) {
        std::swap (buffer[0], buffer[1]);
    }

    int main() {
        const int num_channels = 2;
        const int num_samples = 3;

        float buffer [6] = {0, 0, 0, 1, 1, 1}; // 0s for left channel, 1s for right
        float* ptrs [2]= {buffer, buffer + num_samples};

        swap_channels (ptrs, num_samples);

        for (int ch = 0; ch < num_channels; ch++) {
            for (int sm = 0; sm < num_samples; sm++ {
                std::cout << buffer[ch * num_samples + sm] << std::endl;
            }
        }
    }

#4

Use FloatVectorOperations for this, or the methods from the AudioBuffer class.
Why iterate over samples?


#5

i was fearing it was something like this, yes … opted for a solution copying around the actual data, which works fine …


#6

Could be wrong about this, but I think that getArrayOfWritePointers should return T* const* and not T** to reinforce this at compile time. But I understand, pointer const-ness syntax is gross.


#7

but less tempting, definitely …