AudioData::Pointer and conversion between NonInterleaved and Interleaved audio buffers


#1

Hi Folks,

I know at least one similar question has been posted in the past, with regards to an easy way to convert between NonInterleaved and Interleaved buffers and Jules’ response directed towards the AudioData::Pointer class.

My specific use case actually requires converting from Float to Int16 as well as NonInterleaved and Interleaved. I’ve been just playing around, and the type conversion works as expected using the AudioData::Pointer class, and I can convert between NonInterleaved and Interleaved by using the AudioDataConverters::convertFloatToFormat call, but my understanding is that the AudioDataConverters functions will be deprecated. So I’ve been trying to figure out how to use the AudioData::Pointer class to do the same.

Here is some test code, just trying to get this to work:

 DBG("======= INTERLEAVE VIA AUDIO DATA =======");
AudioBuffer<float> floatAudioBuffer (2,3);
// write first channel with positive float values (0, 0.5, 1.0)
for (int i = 0; i < 3; i++) {
    floatAudioBuffer.setSample(0, i, i*0.5f);
}
// write second channel with positive float values (0, 0.5, 1.0)
for (int i = 0; i < 3; i++) {
    floatAudioBuffer.setSample(1, i, (i*-0.5f));
}
DBG("Float uninterleaved buffer");
dumpAudioBuffer(&floatAudioBuffer);

AudioBuffer<float> floatAudioBufferInterleaved (1,6);
for (int i = 0; i < 6; i++) {
    floatAudioBufferInterleaved.setSample(0, i, 0.6f);
}
DBG("float interleaved after setting to 0.6f");
dumpAudioBuffer(&floatAudioBufferInterleaved);

{
    AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> pointer1 (*floatAudioBuffer.getArrayOfReadPointers());
    AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::NonConst> pointer2 (*floatAudioBufferInterleaved.getArrayOfWritePointers(), 2);
    pointer2.convertSamples(pointer1, 6);
    DBG("float interleaved after convert");
    dumpAudioBuffer(&floatAudioBufferInterleaved);
}

dumpAudioBuffer just spits the contents of the AudioBuffer to DBG. The above returns this:

======= INTERLEAVE VIA AUDIO DATA =======
Float uninterleaved buffer
Channel: 0 Sample: 0
Channel: 0 Sample: 0.5
Channel: 0 Sample: 1
Channel: 1 Sample: -0
Channel: 1 Sample: -0.5
Channel: 1 Sample: -1
===
float interleaved after setting to 0.6f
Channel: 0 Sample: 0.6
Channel: 0 Sample: 0.6
Channel: 0 Sample: 0.6
Channel: 0 Sample: 0.6
Channel: 0 Sample: 0.6
Channel: 0 Sample: 0.6
===
float interleaved after convert
Channel: 0 Sample: 0
Channel: 0 Sample: 0.6
Channel: 0 Sample: 0.5
Channel: 0 Sample: 0.6
Channel: 0 Sample: 1
Channel: 0 Sample: 0.6

So as you can see, every other sample in the interleaved AudioBuffer is not touched. Any ideas?

Thanks!
J


#3

The convertSamples method will not convert all of the channels at once. You need to call convertSamples for every channel that you want to convert.

We do exactly the type of conversion that you want to do (Int16 Interleaved <-> Float Non-Interleaved) in JUCE’s OpenSL driver: juce_android_OpenSL.cpp:171


#4

Thanks fabian, that makes sense!