[openal] [WIP] AL_EXT_MSADPCM in OpenAL Soft

Chris Robinson chris.kcat at gmail.com
Sat Mar 1 22:03:27 EST 2014

On 03/01/2014 02:16 AM, Ethan Lee wrote:
> Before pursuing this work further, I wanted to ask the mailing list for
> feedback regarding what we have now. At the moment we have support for
> decoding MSADPCM wavedata, but no support for encoding (those portions
> are currently stubbed, but if this is simply not needed then I wouldn't
> object to removing it). Additionally, we only support 64-/128-/256-byte
> blocks, and each have their own code paths. I wasn't sure if this was
> the best path, or if there should be a new BufferData function that
> accepts a `blockAlign` parameter to handle a wider range of block sizes
> in addition to possibly reducing the amount of code.

One of the issues I've had on my mind in regards to the IMA4 ADPCM 
format is how to best handle different block sizes, since it currently 
only handles a block align of 36*num_channels bytes, or 65 sample 
frames, which heavily restricts its utility. One idea I had was to add 
buffer properties like AL_UNPACK_BLOCK_SIZE and AL_PACK_BLOCK_SIZE, not 
too unlike the GL_UNPACK_/GL_PACK_ properties for handling user 
input/output. So for example:

alBufferi(buffer, AL_UNPACK_BLOCK_SIZE, 32 /* or 64 or whatever */);
alBufferData(buffer, AL_FORMAT_MONO_MSADPCM, data, data_len, srate);

The value would be the number of sample frames per block. Calculating 
the block size from the WaveFormatEx header for MSADPCM would be:

/* 7 bytes (per channel) in the block preamble */
if(wfx.nBlockAlign < 7*wfx.nChannels)
     error("Invalid block size");
int bsize = wfx.nBlockAlign - (7*wfx.nChannels);
/* Each remaining nibble is a sample */
bsize *= 2;
/* Convert to sample frames */
if((bsize%wfx.nChannels) != 0)
     error("Invalid block size");
bsize /= wfx.nChannels;
/* 2 sample frames from the block preamble */
bsize += 2;

alBufferi(buffer, AL_UNPACK_BLOCK_SIZE, bsize);

Though I'm not sure that's the best way to go about it. Having the block 
size as part of the format enum seems unnecessarily restrictive too 
though, since it requires new enums for every block size you want to 

The other option is, of course, to add a new function with an extra 
block size parameter, but that can also get a bit messy considering the 
AL_SOFT_buffer_sub_data and AL_SOFT_buffer_samples extensions (the 
latter being a new, more flexible buffering API designed to supersede 
the old).

> The current patch is here:
> http://flibitijibibo.com/al_ext_msadpcm.txt

Hmm, to be honest, I'm not really keen on the special-cased mono and 
stereo decoders. I don't think the potential speed gain is worth the 
extra code and manual unrolling, considering all the other work being 
done here too (unless there's really notable gains, I think it's best to 
write clean code and let the compiler worry about optimizing it). I 
think the amount of templating could also be cut down by passing the 
block size as a parameter to the Convert_##T##_ALmsadpcm functions.

More information about the openal mailing list