[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
support.
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