diff options
author | Chris Robinson <[email protected]> | 2019-07-28 17:22:00 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-07-28 17:22:00 -0700 |
commit | bb0062625f13bd64c9f83f8c482eae119009a48f (patch) | |
tree | cdf5090af2ce0f33a031616f0769ebf4ad0d0799 /OpenAL32 | |
parent | b4d56d3fdff4243ae2a3fc64934ced2af3187690 (diff) |
Move the ADPCM decoders to alBuffer.cpp
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/Include/sample_cvt.h | 13 | ||||
-rw-r--r-- | OpenAL32/alBuffer.cpp | 184 | ||||
-rw-r--r-- | OpenAL32/sample_cvt.cpp | 195 |
3 files changed, 183 insertions, 209 deletions
diff --git a/OpenAL32/Include/sample_cvt.h b/OpenAL32/Include/sample_cvt.h deleted file mode 100644 index c8c1ad23..00000000 --- a/OpenAL32/Include/sample_cvt.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef SAMPLE_CVT_H -#define SAMPLE_CVT_H - -#include "AL/al.h" -#include "albyte.h" - - -void Convert_ALshort_ALima4(ALshort *dst, const al::byte *src, ALsizei numchans, ALsizei len, - ALsizei align); -void Convert_ALshort_ALmsadpcm(ALshort *dst, const al::byte *src, ALsizei numchans, ALsizei len, - ALsizei align); - -#endif /* SAMPLE_CVT_H */ diff --git a/OpenAL32/alBuffer.cpp b/OpenAL32/alBuffer.cpp index 843d4e76..c9a9d9f6 100644 --- a/OpenAL32/alBuffer.cpp +++ b/OpenAL32/alBuffer.cpp @@ -51,12 +51,194 @@ #include "atomic.h" #include "inprogext.h" #include "opthelpers.h" -#include "sample_cvt.h" #include "vector.h" namespace { +/* IMA ADPCM Stepsize table */ +constexpr int IMAStep_size[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, + 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, + 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, + 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, + 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, + 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, + 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442, + 11487,12635,13899,15289,16818,18500,20350,22358,24633,27086,29794, + 32767 +}; + +/* IMA4 ADPCM Codeword decode table */ +constexpr int IMA4Codeword[16] = { + 1, 3, 5, 7, 9, 11, 13, 15, + -1,-3,-5,-7,-9,-11,-13,-15, +}; + +/* IMA4 ADPCM Step index adjust decode table */ +constexpr int IMA4Index_adjust[16] = { + -1,-1,-1,-1, 2, 4, 6, 8, + -1,-1,-1,-1, 2, 4, 6, 8 +}; + + +/* MSADPCM Adaption table */ +constexpr int MSADPCMAdaption[16] = { + 230, 230, 230, 230, 307, 409, 512, 614, + 768, 614, 512, 409, 307, 230, 230, 230 +}; + +/* MSADPCM Adaption Coefficient tables */ +constexpr int MSADPCMAdaptionCoeff[7][2] = { + { 256, 0 }, + { 512, -256 }, + { 0, 0 }, + { 192, 64 }, + { 240, 0 }, + { 460, -208 }, + { 392, -232 } +}; + + +void DecodeIMA4Block(ALshort *dst, const al::byte *src, ALint numchans, ALsizei align) +{ + ALint sample[MAX_INPUT_CHANNELS]{}; + ALint index[MAX_INPUT_CHANNELS]{}; + ALuint code[MAX_INPUT_CHANNELS]{}; + + for(int c{0};c < numchans;c++) + { + sample[c] = al::to_integer<int>(src[0]) | (al::to_integer<int>(src[1])<<8); + sample[c] = (sample[c]^0x8000) - 32768; + src += 2; + index[c] = al::to_integer<int>(src[0]) | (al::to_integer<int>(src[1])<<8); + index[c] = clampi((index[c]^0x8000) - 32768, 0, 88); + src += 2; + + *(dst++) = sample[c]; + } + + for(int i{1};i < align;i++) + { + if((i&7) == 1) + { + for(int c{0};c < numchans;c++) + { + code[c] = al::to_integer<ALuint>(src[0]) | (al::to_integer<ALuint>(src[1])<< 8) | + (al::to_integer<ALuint>(src[2])<<16) | (al::to_integer<ALuint>(src[3])<<24); + src += 4; + } + } + + for(int c{0};c < numchans;c++) + { + const ALuint nibble{code[c]&0xf}; + code[c] >>= 4; + + sample[c] += IMA4Codeword[nibble] * IMAStep_size[index[c]] / 8; + sample[c] = clampi(sample[c], -32768, 32767); + + index[c] += IMA4Index_adjust[nibble]; + index[c] = clampi(index[c], 0, 88); + + *(dst++) = sample[c]; + } + } +} + +void DecodeMSADPCMBlock(ALshort *dst, const al::byte *src, ALint numchans, ALsizei align) +{ + ALubyte blockpred[MAX_INPUT_CHANNELS]{}; + ALint delta[MAX_INPUT_CHANNELS]{}; + ALshort samples[MAX_INPUT_CHANNELS][2]{}; + + for(int c{0};c < numchans;c++) + { + blockpred[c] = minu(al::to_integer<ALubyte>(src[0]), 6); + ++src; + } + for(int c{0};c < numchans;c++) + { + delta[c] = al::to_integer<int>(src[0]) | (al::to_integer<int>(src[1])<<8); + delta[c] = (delta[c]^0x8000) - 32768; + src += 2; + } + for(int c{0};c < numchans;c++) + { + samples[c][0] = al::to_integer<short>(src[0]) | (al::to_integer<short>(src[1])<<8); + samples[c][0] = (samples[c][0]^0x8000) - 32768; + src += 2; + } + for(int c{0};c < numchans;c++) + { + samples[c][1] = al::to_integer<short>(src[0]) | (al::to_integer<short>(src[1])<<8); + samples[c][1] = (samples[c][1]^0x8000) - 32768; + src += 2; + } + + /* Second sample is written first. */ + for(int c{0};c < numchans;c++) + *(dst++) = samples[c][1]; + for(int c{0};c < numchans;c++) + *(dst++) = samples[c][0]; + + int num{0}; + for(int i{2};i < align;i++) + { + for(int c{0};c < numchans;c++) + { + /* Read the nibble (first is in the upper bits). */ + al::byte nibble; + if(!(num++ & 1)) + nibble = *src >> 4; + else + nibble = *(src++) & 0x0f; + + ALint pred{(samples[c][0]*MSADPCMAdaptionCoeff[blockpred[c]][0] + + samples[c][1]*MSADPCMAdaptionCoeff[blockpred[c]][1]) / 256}; + pred += (al::to_integer<int>(nibble^0x08) - 0x08) * delta[c]; + pred = clampi(pred, -32768, 32767); + + samples[c][1] = samples[c][0]; + samples[c][0] = pred; + + delta[c] = (MSADPCMAdaption[al::to_integer<ALubyte>(nibble)] * delta[c]) / 256; + delta[c] = maxi(16, delta[c]); + + *(dst++) = pred; + } + } +} + +void Convert_ALshort_ALima4(ALshort *dst, const al::byte *src, ALsizei numchans, ALsizei len, + ALsizei align) +{ + const ALsizei byte_align{((align-1)/2 + 4) * numchans}; + + len /= align; + while(len--) + { + DecodeIMA4Block(dst, src, numchans, align); + src += byte_align; + dst += align*numchans; + } +} + +void Convert_ALshort_ALmsadpcm(ALshort *dst, const al::byte *src, ALsizei numchans, ALsizei len, + ALsizei align) +{ + const ALsizei byte_align{((align-2)/2 + 7) * numchans}; + + len /= align; + while(len--) + { + DecodeMSADPCMBlock(dst, src, numchans, align); + src += byte_align; + dst += align*numchans; + } +} + + constexpr ALbitfieldSOFT INVALID_STORAGE_MASK{~unsigned(AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT | AL_MAP_PERSISTENT_BIT_SOFT | AL_PRESERVE_DATA_BIT_SOFT)}; constexpr ALbitfieldSOFT MAP_READ_WRITE_FLAGS{AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT}; diff --git a/OpenAL32/sample_cvt.cpp b/OpenAL32/sample_cvt.cpp deleted file mode 100644 index 79d0d1c5..00000000 --- a/OpenAL32/sample_cvt.cpp +++ /dev/null @@ -1,195 +0,0 @@ - -#include "config.h" - -#include "sample_cvt.h" - -#include "AL/al.h" -#include "alu.h" -#include "alBuffer.h" - - -namespace { - -/* IMA ADPCM Stepsize table */ -constexpr int IMAStep_size[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, - 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, - 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, - 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, - 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, - 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, - 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442, - 11487,12635,13899,15289,16818,18500,20350,22358,24633,27086,29794, - 32767 -}; - -/* IMA4 ADPCM Codeword decode table */ -constexpr int IMA4Codeword[16] = { - 1, 3, 5, 7, 9, 11, 13, 15, - -1,-3,-5,-7,-9,-11,-13,-15, -}; - -/* IMA4 ADPCM Step index adjust decode table */ -constexpr int IMA4Index_adjust[16] = { - -1,-1,-1,-1, 2, 4, 6, 8, - -1,-1,-1,-1, 2, 4, 6, 8 -}; - - -/* MSADPCM Adaption table */ -constexpr int MSADPCMAdaption[16] = { - 230, 230, 230, 230, 307, 409, 512, 614, - 768, 614, 512, 409, 307, 230, 230, 230 -}; - -/* MSADPCM Adaption Coefficient tables */ -constexpr int MSADPCMAdaptionCoeff[7][2] = { - { 256, 0 }, - { 512, -256 }, - { 0, 0 }, - { 192, 64 }, - { 240, 0 }, - { 460, -208 }, - { 392, -232 } -}; - - -void DecodeIMA4Block(ALshort *dst, const al::byte *src, ALint numchans, ALsizei align) -{ - ALint sample[MAX_INPUT_CHANNELS]{}; - ALint index[MAX_INPUT_CHANNELS]{}; - ALuint code[MAX_INPUT_CHANNELS]{}; - - for(int c{0};c < numchans;c++) - { - sample[c] = al::to_integer<int>(src[0]) | (al::to_integer<int>(src[1])<<8); - sample[c] = (sample[c]^0x8000) - 32768; - src += 2; - index[c] = al::to_integer<int>(src[0]) | (al::to_integer<int>(src[1])<<8); - index[c] = clampi((index[c]^0x8000) - 32768, 0, 88); - src += 2; - - *(dst++) = sample[c]; - } - - for(int i{1};i < align;i++) - { - if((i&7) == 1) - { - for(int c{0};c < numchans;c++) - { - code[c] = al::to_integer<ALuint>(src[0]) | (al::to_integer<ALuint>(src[1])<< 8) | - (al::to_integer<ALuint>(src[2])<<16) | (al::to_integer<ALuint>(src[3])<<24); - src += 4; - } - } - - for(int c{0};c < numchans;c++) - { - const ALuint nibble{code[c]&0xf}; - code[c] >>= 4; - - sample[c] += IMA4Codeword[nibble] * IMAStep_size[index[c]] / 8; - sample[c] = clampi(sample[c], -32768, 32767); - - index[c] += IMA4Index_adjust[nibble]; - index[c] = clampi(index[c], 0, 88); - - *(dst++) = sample[c]; - } - } -} - -void DecodeMSADPCMBlock(ALshort *dst, const al::byte *src, ALint numchans, ALsizei align) -{ - ALubyte blockpred[MAX_INPUT_CHANNELS]{}; - ALint delta[MAX_INPUT_CHANNELS]{}; - ALshort samples[MAX_INPUT_CHANNELS][2]{}; - - for(int c{0};c < numchans;c++) - { - blockpred[c] = minu(al::to_integer<ALubyte>(src[0]), 6); - ++src; - } - for(int c{0};c < numchans;c++) - { - delta[c] = al::to_integer<int>(src[0]) | (al::to_integer<int>(src[1])<<8); - delta[c] = (delta[c]^0x8000) - 32768; - src += 2; - } - for(int c{0};c < numchans;c++) - { - samples[c][0] = al::to_integer<short>(src[0]) | (al::to_integer<short>(src[1])<<8); - samples[c][0] = (samples[c][0]^0x8000) - 32768; - src += 2; - } - for(int c{0};c < numchans;c++) - { - samples[c][1] = al::to_integer<short>(src[0]) | (al::to_integer<short>(src[1])<<8); - samples[c][1] = (samples[c][1]^0x8000) - 32768; - src += 2; - } - - /* Second sample is written first. */ - for(int c{0};c < numchans;c++) - *(dst++) = samples[c][1]; - for(int c{0};c < numchans;c++) - *(dst++) = samples[c][0]; - - int num{0}; - for(int i{2};i < align;i++) - { - for(int c{0};c < numchans;c++) - { - /* Read the nibble (first is in the upper bits). */ - al::byte nibble; - if(!(num++ & 1)) - nibble = *src >> 4; - else - nibble = *(src++) & 0x0f; - - ALint pred{(samples[c][0]*MSADPCMAdaptionCoeff[blockpred[c]][0] + - samples[c][1]*MSADPCMAdaptionCoeff[blockpred[c]][1]) / 256}; - pred += (al::to_integer<int>(nibble^0x08) - 0x08) * delta[c]; - pred = clampi(pred, -32768, 32767); - - samples[c][1] = samples[c][0]; - samples[c][0] = pred; - - delta[c] = (MSADPCMAdaption[al::to_integer<ALubyte>(nibble)] * delta[c]) / 256; - delta[c] = maxi(16, delta[c]); - - *(dst++) = pred; - } - } -} - -} // namespace - -void Convert_ALshort_ALima4(ALshort *dst, const al::byte *src, ALsizei numchans, ALsizei len, - ALsizei align) -{ - const ALsizei byte_align{((align-1)/2 + 4) * numchans}; - - len /= align; - while(len--) - { - DecodeIMA4Block(dst, src, numchans, align); - src += byte_align; - dst += align*numchans; - } -} - -void Convert_ALshort_ALmsadpcm(ALshort *dst, const al::byte *src, ALsizei numchans, ALsizei len, - ALsizei align) -{ - const ALsizei byte_align{((align-2)/2 + 7) * numchans}; - - len /= align; - while(len--) - { - DecodeMSADPCMBlock(dst, src, numchans, align); - src += byte_align; - dst += align*numchans; - } -} |