summaryrefslogtreecommitdiffstats
path: root/adpcm.c
diff options
context:
space:
mode:
authormelanson <melanson@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-01-06 01:56:27 +0000
committermelanson <melanson@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-01-06 01:56:27 +0000
commit4bbefcad28c7b3200de0d274b8506a16ad8bb00a (patch)
tree9a3f64015bfa0cef46b13fc9294d33b2db4b47a5 /adpcm.c
parent657b60c71b3339faff3f6fdf26d1c6ddc79442a8 (diff)
downloadmpv-4bbefcad28c7b3200de0d274b8506a16ad8bb00a.tar.bz2
mpv-4bbefcad28c7b3200de0d274b8506a16ad8bb00a.tar.xz
fixed format 0x62 ADPCM audio
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4002 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'adpcm.c')
-rw-r--r--adpcm.c186
1 files changed, 145 insertions, 41 deletions
diff --git a/adpcm.c b/adpcm.c
index 30b73ff5e0..204a54126a 100644
--- a/adpcm.c
+++ b/adpcm.c
@@ -296,55 +296,159 @@ int fox61_adpcm_decode_block(unsigned short *output, unsigned char *input)
// note: This decoder assumes the format 0x62 data always comes in
// stereo flavor
-int fox62_adpcm_decode_block(unsigned short *output, unsigned char *input,
- int channels)
+int fox62_adpcm_decode_block(unsigned short *output, unsigned char *input)
{
- int predictor_l;
- int predictor_r;
- int index_l;
- int index_r;
- int i;
- int adjustment;
+ int pred1;
+ int pred2;
+ int index1;
+ int index2;
+ int in_ptr = 0x10;
+ int out_ptr = 0;
-static int counter = 0;
+ int flag1 = 0;
+ int flag2 = 1;
+ int sum;
+ unsigned char last_byte = 0;
+ unsigned char nibble;
- predictor_l = LE_16(&input[10]);
- predictor_r = LE_16(&input[12]);
- SE_16BIT(predictor_l);
- SE_16BIT(predictor_r);
- index_l = input[14];
- index_r = input[15];
+ // ADPCM work variables
+ int sign;
+ int delta;
+ int step;
+ int diff;
- for (i = 16; i < FOX62_ADPCM_BLOCK_SIZE; i++)
+ pred1 = LE_16(&input[10]);
+ pred2 = LE_16(&input[12]);
+ SE_16BIT(pred1);
+ SE_16BIT(pred2);
+ sum = pred2;
+ index1 = input[14];
+ index2 = input[15];
+
+ while (in_ptr < 2048)
{
- output[(i - 16) * 2 + 0] = input[i] & 0x0F;
- output[(i - 16) * 2 + 1] = (input[i] >> 4) & 0x0F;
- }
+ if (flag2)
+ {
+ last_byte = input[in_ptr++];
+ nibble = last_byte & 0x0F;
- decode_nibbles(output, FOX62_ADPCM_SAMPLES_PER_BLOCK * channels, channels,
- predictor_l, index_l,
- predictor_r, index_r);
+ step = adpcm_step[index1];
+ sign = nibble & 8;
+ delta = nibble & 7;
- for (i = 0; i < FOX62_ADPCM_SAMPLES_PER_BLOCK / 2; i += 2)
- {
- adjustment = (predictor_r + output[i + 1]) / 2;
-if (counter < 20)
-{
-printf ("(L, R) = %04X, %04X, prev_r = %04X, adjustment = %04X\n",
- output[i], output[i+1], predictor_r, adjustment);
- counter++;
-}
- predictor_r = output[i + 1];
- output[i + 1] = output[i] - adjustment;
- output[i] += adjustment;
+ diff = step >> 3;
+ if (delta & 4) diff += step;
+ if (delta & 2) diff += step >> 1;
+ if (delta & 1) diff += step >> 2;
+
+ if (sign)
+ pred1 -= diff;
+ else
+ pred1 += diff;
+
+ CLAMP_S16(pred1);
+
+ index1 += adpcm_index[nibble];
+ CLAMP_0_TO_88(index1);
+
+ if (flag1)
+ flag2 = 0;
+ else
+ {
+ nibble = (last_byte >> 4) & 0x0F;
+
+ step = adpcm_step[index2];
+
+ 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)
+ pred2 -= diff;
+ else
+ pred2 += diff;
+
+ CLAMP_S16(pred2);
+
+ index2 += adpcm_index[nibble];
+ CLAMP_0_TO_88(index2);
+
+ sum = (sum + pred2) / 2;
+ }
+ output[out_ptr++] = pred1 + sum;
+ output[out_ptr++] = pred1 - sum;
+
+ flag1 ^= 1;
+ if (in_ptr >= 2048)
+ break;
+ }
+ else
+ {
+ nibble = (last_byte >> 4) & 0x0F;
+
+ step = adpcm_step[index1];
+
+ 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)
+ pred1 -= diff;
+ else
+ pred1 += diff;
+
+ CLAMP_S16(pred1);
+
+ index1 += adpcm_index[nibble];
+ CLAMP_0_TO_88(index1);
+
+ if (flag1)
+ flag2 = 1;
+ else
+ {
+ last_byte = input[in_ptr++];
+ nibble = last_byte & 0x0F;
+
+ step = adpcm_step[index2];
+
+ 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)
+ pred2 -= diff;
+ else
+ pred2 += diff;
+
+ CLAMP_S16(pred2);
+
+ index2 += adpcm_index[nibble];
+ CLAMP_0_TO_88(index2);
+
+ sum = (sum + pred2) / 2;
+ }
+
+ output[out_ptr++] = pred1 + sum;
+ output[out_ptr++] = pred1 - sum;
+
+ flag1 ^= 1;
+ if (in_ptr >= 2048)
+ break;
+ }
}
-if (counter++ == 20)
-{
-printf (" after:\n");
-for (i = 0; i < 20; i++)
- printf ("%04X\n", output[i]);
-}
- return FOX62_ADPCM_SAMPLES_PER_BLOCK * channels;
+ return out_ptr;
}