static int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels, int block_size) { int current_channel = 0; int idelta[2]; int sample1[2]; int sample2[2]; int coeff1[2]; int coeff2[2]; int stream_ptr = 0; int out_ptr = 0; int upper_nibble = 1; int nibble; int snibble; // signed nibble int predictor; // fetch the header information, in stereo if both channels are present if (input[stream_ptr] > 6) mp_msg(MSGT_DECAUDIO, MSGL_WARN, "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", input[stream_ptr]); coeff1[0] = ms_adapt_coeff1[input[stream_ptr]]; coeff2[0] = ms_adapt_coeff2[input[stream_ptr]]; stream_ptr++; if (channels == 2) { if (input[stream_ptr] > 6) mp_msg(MSGT_DECAUDIO, MSGL_WARN, "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", input[stream_ptr]); coeff1[1] = ms_adapt_coeff1[input[stream_ptr]]; coeff2[1] = ms_adapt_coeff2[input[stream_ptr]]; stream_ptr++; } idelta[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(idelta[0]); if (channels == 2) { idelta[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(idelta[1]); } sample1[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(sample1[0]); if (channels == 2) { sample1[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(sample1[1]); } sample2[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(sample2[0]); if (channels == 2) { sample2[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; SE_16BIT(sample2[1]); } if (channels == 1) { output[out_ptr++] = sample2[0]; output[out_ptr++] = sample1[0]; } else { output[out_ptr++] = sample2[0]; output[out_ptr++] = sample2[1]; output[out_ptr++] = sample1[0]; output[out_ptr++] = sample1[1]; } while (stream_ptr < block_size) { // get the next nibble if (upper_nibble) nibble = snibble = input[stream_ptr] >> 4; else nibble = snibble = input[stream_ptr++] & 0x0F; upper_nibble ^= 1; SE_4BIT(snibble); predictor = ( ((sample1[current_channel] * coeff1[current_channel]) + (sample2[current_channel] * coeff2[current_channel])) / 256) + (snibble * idelta[current_channel]); CLAMP_S16(predictor); sample2[current_channel] = sample1[current_channel]; sample1[current_channel] = predictor; output[out_ptr++] = predictor; // compute the next adaptive scale factor (a.k.a. the variable idelta) idelta[current_channel] = (ms_adapt_table[nibble] * idelta[current_channel]) / 256; CLAMP_ABOVE_16(idelta[current_channel]); // toggle the channel current_channel ^= channels - 1; }
static int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels, int block_size) { int current_channel = 0; int coeff_idx; int idelta[2]; int sample1[2]; int sample2[2]; int coeff1[2]; int coeff2[2]; int stream_ptr = 0; int out_ptr = 0; int upper_nibble = 1; int nibble; int snibble; // signed nibble int predictor; if (channels != 1) channels = 2; if (block_size < 7 * channels) return -1; // fetch the header information, in stereo if both channels are present coeff_idx = check_coeff(input[stream_ptr]); coeff1[0] = ms_adapt_coeff1[coeff_idx]; coeff2[0] = ms_adapt_coeff2[coeff_idx]; stream_ptr++; if (channels == 2) { coeff_idx = check_coeff(input[stream_ptr]); coeff1[1] = ms_adapt_coeff1[coeff_idx]; coeff2[1] = ms_adapt_coeff2[coeff_idx]; stream_ptr++; } idelta[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; if (channels == 2) { idelta[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; } sample1[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; if (channels == 2) { sample1[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; } sample2[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; if (channels == 2) { sample2[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; } if (channels == 1) { output[out_ptr++] = sample2[0]; output[out_ptr++] = sample1[0]; } else { output[out_ptr++] = sample2[0]; output[out_ptr++] = sample2[1]; output[out_ptr++] = sample1[0]; output[out_ptr++] = sample1[1]; } while (stream_ptr < block_size) { // get the next nibble if (upper_nibble) nibble = snibble = input[stream_ptr] >> 4; else nibble = snibble = input[stream_ptr++] & 0x0F; upper_nibble ^= 1; SE_4BIT(snibble); // should this really be a division and not a shift? // coefficients were originally scaled by for, which might have // been an optimization for 8-bit CPUs _if_ a shift is correct predictor = ( ((sample1[current_channel] * coeff1[current_channel]) + (sample2[current_channel] * coeff2[current_channel])) / 64) + (snibble * idelta[current_channel]); CLAMP_S16(predictor); sample2[current_channel] = sample1[current_channel]; sample1[current_channel] = predictor; output[out_ptr++] = predictor; // compute the next adaptive scale factor (a.k.a. the variable idelta) idelta[current_channel] = (ms_adapt_table[nibble] * idelta[current_channel]) / 256; CLAMP_ABOVE_16(idelta[current_channel]); // toggle the channel current_channel ^= channels - 1; }