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 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;
  }
// 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;
}