static int qt_ima_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels, int block_size) { int initial_predictor[2] = {0}; int initial_index[2] = {0}; int i; if (channels != 1) channels = 2; if (block_size < channels * QT_IMA_ADPCM_BLOCK_SIZE) return -1; for (i = 0; i < channels; i++) { initial_index[i] = initial_predictor[i] = (int16_t)AV_RB16(&input[i * QT_IMA_ADPCM_BLOCK_SIZE]); // mask, sign-extend, and clamp the predictor portion initial_predictor[i] &= ~0x7F; CLAMP_S16(initial_predictor[i]); // mask and clamp the index portion initial_index[i] &= 0x7F; CLAMP_0_TO_88(initial_index[i]); } // break apart all of the nibbles in the block if (channels == 1) for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++) { output[i * 2 + 0] = input[2 + i] & 0x0F; output[i * 2 + 1] = input[2 + i] >> 4; } else for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++)
int qt_ima_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels) { int initial_predictor_l = 0; int initial_predictor_r = 0; int initial_index_l = 0; int initial_index_r = 0; int i; initial_predictor_l = BE_16(&input[0]); initial_index_l = initial_predictor_l; // mask, sign-extend, and clamp the predictor portion initial_predictor_l &= 0xFF80; SE_16BIT(initial_predictor_l); CLAMP_S16(initial_predictor_l); // mask and clamp the index portion initial_index_l &= 0x7F; CLAMP_0_TO_88(initial_index_l); // handle stereo if (channels > 1) { initial_predictor_r = BE_16(&input[QT_IMA_ADPCM_BLOCK_SIZE]); initial_index_r = initial_predictor_r; // mask, sign-extend, and clamp the predictor portion initial_predictor_r &= 0xFF80; SE_16BIT(initial_predictor_r); CLAMP_S16(initial_predictor_r); // mask and clamp the index portion initial_index_r &= 0x7F; CLAMP_0_TO_88(initial_index_r); } // break apart all of the nibbles in the block if (channels == 1) for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++) { output[i * 2 + 0] = input[2 + i] & 0x0F; output[i * 2 + 1] = input[2 + i] >> 4; } else for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2 * 2; i++)
static void decode_nibbles(unsigned short *output, int output_size, int channels, int predictor_l, int index_l, int predictor_r, int index_r) { int step[2]; int predictor[2]; int index[2]; int diff; int i; int sign; int delta; int channel_number = 0; step[0] = adpcm_step[index_l]; step[1] = adpcm_step[index_r]; predictor[0] = predictor_l; predictor[1] = predictor_r; index[0] = index_l; index[1] = index_r; for (i = 0; i < output_size; i++) { delta = output[i]; index[channel_number] += adpcm_index[delta]; CLAMP_0_TO_88(index[channel_number]); sign = delta & 8; delta = delta & 7; diff = step[channel_number] >> 3; if (delta & 4) diff += step[channel_number]; if (delta & 2) diff += step[channel_number] >> 1; if (delta & 1) diff += step[channel_number] >> 2; if (sign) predictor[channel_number] -= diff; else predictor[channel_number] += diff; CLAMP_S16(predictor[channel_number]); output[i] = predictor[channel_number]; step[channel_number] = adpcm_step[index[channel_number]]; // toggle channel channel_number ^= channels - 1; } }
static void decode_nibbles(unsigned short *output, int output_size, int channels, int predictor[2], int index[2]) { int step[2]; int i; int sign; int delta; int channel_number = 0; step[0] = adpcm_step[index[0]]; step[1] = adpcm_step[index[1]]; for (i = 0; i < output_size; i++) { delta = output[i]; sign = delta & 8; delta = delta & 7; index[channel_number] += adpcm_index[delta]; CLAMP_0_TO_88(index[channel_number]); delta = 2 * delta + 1; if (sign) delta = -delta; predictor[channel_number] += (delta * step[channel_number]) >> 3; CLAMP_S16(predictor[channel_number]); output[i] = predictor[channel_number]; step[channel_number] = adpcm_step[index[channel_number]]; // toggle channel channel_number ^= channels - 1; } }
// note: This decoder assumes the format 0x62 data always comes in // stereo flavor static int dk3_adpcm_decode_block(unsigned short *output, unsigned char *input, int block_size) { int sum_pred; int diff_pred; int sum_index; int diff_index; int diff_channel; int in_ptr = 0x10; int out_ptr = 0; unsigned char last_byte = 0; unsigned char nibble; int decode_top_nibble_next = 0; // ADPCM work variables int sign; int delta; int step; int diff; sum_pred = LE_16(&input[10]); diff_pred = LE_16(&input[12]); SE_16BIT(sum_pred); SE_16BIT(diff_pred); diff_channel = diff_pred; sum_index = input[14]; diff_index = input[15]; while (in_ptr < block_size - !decode_top_nibble_next) // while (in_ptr < 2048) { // process the first predictor of the sum channel DK3_GET_NEXT_NIBBLE(); step = adpcm_step[sum_index]; sign = nibble & 8; delta = nibble & 7; diff = step >> 3; if (delta & 4) diff += step; if (delta & 2) diff += step >> 1; if (delta & 1) diff += step >> 2; if (sign) sum_pred -= diff; else sum_pred += diff; CLAMP_S16(sum_pred); sum_index += adpcm_index[nibble]; CLAMP_0_TO_88(sum_index); // process the diff channel predictor DK3_GET_NEXT_NIBBLE(); step = adpcm_step[diff_index]; sign = nibble & 8; delta = nibble & 7; diff = step >> 3; if (delta & 4) diff += step; if (delta & 2) diff += step >> 1; if (delta & 1) diff += step >> 2; if (sign) diff_pred -= diff; else diff_pred += diff; CLAMP_S16(diff_pred); diff_index += adpcm_index[nibble]; CLAMP_0_TO_88(diff_index); // output the first pair of stereo PCM samples diff_channel = (diff_channel + diff_pred) / 2; output[out_ptr++] = sum_pred + diff_channel; output[out_ptr++] = sum_pred - diff_channel; // process the second predictor of the sum channel DK3_GET_NEXT_NIBBLE(); step = adpcm_step[sum_index]; sign = nibble & 8; delta = nibble & 7; diff = step >> 3; if (delta & 4) diff += step; if (delta & 2) diff += step >> 1; if (delta & 1) diff += step >> 2; if (sign) sum_pred -= diff; else sum_pred += diff; CLAMP_S16(sum_pred); sum_index += adpcm_index[nibble]; CLAMP_0_TO_88(sum_index); // output the second pair of stereo PCM samples output[out_ptr++] = sum_pred + diff_channel; output[out_ptr++] = sum_pred - diff_channel; } return out_ptr; }