|
|
|
|
@ -42,8 +42,10 @@ namespace nqr
|
|
|
|
|
|
|
|
|
|
static const int ima_index_table[16] =
|
|
|
|
|
{
|
|
|
|
|
-1, -1, -1, -1, 2, 4, 6, 8,
|
|
|
|
|
-1, -1, -1, -1, 2, 4, 6, 8
|
|
|
|
|
-1, -1, -1, -1, // +0 / +3 : - the step
|
|
|
|
|
2, 4, 6, 8, // +4 / +7 : + the step
|
|
|
|
|
-1, -1, -1, -1, // -0 / -3 : - the step
|
|
|
|
|
2, 4, 6, 8, // -4 / -7 : + the step
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static inline int ima_clamp_index(int index)
|
|
|
|
|
@ -62,69 +64,68 @@ namespace nqr
|
|
|
|
|
|
|
|
|
|
static const int ima_step_table[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, 22385, 24623, 27086, 29794, 32767
|
|
|
|
|
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, 22385, 24623,
|
|
|
|
|
27086, 29794, 32767
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Decodes an IMA ADPCM nibble to a 16 bit pcm sample
|
|
|
|
|
static inline int16_t decode_nibble(uint8_t nibble, int16_t & p, int & s)
|
|
|
|
|
{
|
|
|
|
|
// Compute a delta to add to the predictor value
|
|
|
|
|
int diff = 0;
|
|
|
|
|
int diff = ima_step_table[s] >> 3;
|
|
|
|
|
if (nibble & 4) diff += ima_step_table[s];
|
|
|
|
|
if (nibble & 2) diff += ima_step_table[s] >> 1;
|
|
|
|
|
if (nibble & 1) diff += ima_step_table[s] >> 2;
|
|
|
|
|
|
|
|
|
|
diff += ima_step_table[s] >> 3;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Sign
|
|
|
|
|
if (nibble & 8) diff = -diff;
|
|
|
|
|
|
|
|
|
|
// Add delta
|
|
|
|
|
p += diff;
|
|
|
|
|
|
|
|
|
|
p = ima_clamp_predict(p);
|
|
|
|
|
|
|
|
|
|
s += ima_index_table[nibble];
|
|
|
|
|
s = ima_clamp_index(s);
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
return ima_clamp_predict(p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void decode_ima_adpcm(ADPCMState & state, int16_t * outBuffer, uint32_t num_channels)
|
|
|
|
|
{
|
|
|
|
|
const uint8_t * data = state.inBuffer;
|
|
|
|
|
|
|
|
|
|
// Loop over the interleaved words
|
|
|
|
|
// Loop over the interleaved channels
|
|
|
|
|
for (int32_t ch = 0; ch < num_channels; ch++)
|
|
|
|
|
{
|
|
|
|
|
const int byteOffset = ch * 4;
|
|
|
|
|
|
|
|
|
|
// Get step table index and predicted value from the header word for the current channel
|
|
|
|
|
int16_t predictedSample = (data[byteOffset] | (data[byteOffset + 1] << 8));
|
|
|
|
|
// Header Structure:
|
|
|
|
|
// Byte0: packed low byte of the initial predictor
|
|
|
|
|
// Byte1: packed high byte of the initial predictor
|
|
|
|
|
// Byte2: initial step index
|
|
|
|
|
// Byte3: Reserved empty value
|
|
|
|
|
int16_t predictor = ((int16_t)data[byteOffset + 1] << 8) | data[byteOffset];
|
|
|
|
|
int stepIndex = data[byteOffset + 2];
|
|
|
|
|
|
|
|
|
|
// Reserved byte of the header word should be 0.
|
|
|
|
|
uint8_t reserved = data[byteOffset + 3];
|
|
|
|
|
if (reserved != 0) std::cout << "Fuck" << std::endl;
|
|
|
|
|
if (reserved != 0) throw std::runtime_error("adpcm decode error");
|
|
|
|
|
|
|
|
|
|
int byteIdx = num_channels * 4 + byteOffset; //the byte index of the first data word for this channel
|
|
|
|
|
int idx = ch;
|
|
|
|
|
|
|
|
|
|
// Decode each nibble of the current data word, containing 8 encoded samples, for the current channel
|
|
|
|
|
// Decode nibbles of the remaining data
|
|
|
|
|
while (byteIdx < state.frame_size)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < 4; j++)
|
|
|
|
|
{
|
|
|
|
|
outBuffer[idx] = decode_nibble(data[byteIdx] & 0xf, predictedSample, stepIndex); // low nibble
|
|
|
|
|
outBuffer[idx] = decode_nibble(data[byteIdx] & 0xf, predictor, stepIndex); // low nibble
|
|
|
|
|
idx += num_channels;
|
|
|
|
|
outBuffer[idx] = decode_nibble(data[byteIdx] >> 4, predictedSample, stepIndex); // high nibble
|
|
|
|
|
outBuffer[idx] = decode_nibble(data[byteIdx] >> 4, predictor, stepIndex); // high nibble
|
|
|
|
|
idx += num_channels;
|
|
|
|
|
byteIdx++;
|
|
|
|
|
}
|
|
|
|
|
|