[Mplayer-cvslog] CVS: main dec_audio.c,1.76,1.77 adpcm.h,1.5,1.6 adpcm.c,1.7,1.8
Mike Melanson
melanson at mplayer.dev.hu
Sun Jan 6 02:56:29 CET 2002
Update of /cvsroot/mplayer/main
In directory mplayer:/var/tmp.root/cvs-serv11809
Modified Files:
dec_audio.c adpcm.h adpcm.c
Log Message:
fixed format 0x62 ADPCM audio
Index: dec_audio.c
===================================================================
RCS file: /cvsroot/mplayer/main/dec_audio.c,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -r1.76 -r1.77
--- dec_audio.c 3 Jan 2002 23:14:13 -0000 1.76
+++ dec_audio.c 6 Jan 2002 01:56:19 -0000 1.77
@@ -1153,7 +1153,7 @@
FOX62_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels)
break; // EOF
len = 2 * fox62_adpcm_decode_block(
- (unsigned short*)buf,ibuf, sh_audio->wf->nChannels);
+ (unsigned short*)buf,ibuf);
break;
}
#ifdef USE_LIBAC3
Index: adpcm.h
===================================================================
RCS file: /cvsroot/mplayer/main/adpcm.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- adpcm.h 1 Jan 2002 20:04:54 -0000 1.5
+++ adpcm.h 6 Jan 2002 01:56:19 -0000 1.6
@@ -18,14 +18,13 @@
// pretend there's such a thing as mono for this format
#define FOX62_ADPCM_PREAMBLE_SIZE 8
#define FOX62_ADPCM_BLOCK_SIZE 0x400
-#define FOX62_ADPCM_SAMPLES_PER_BLOCK \
- ((FOX62_ADPCM_BLOCK_SIZE - FOX62_ADPCM_PREAMBLE_SIZE) * 2)
+// this isn't exact
+#define FOX62_ADPCM_SAMPLES_PER_BLOCK 6000
int ima_adpcm_decode_block(unsigned short *output, unsigned char *input,
int channels);
int ms_adpcm_decode_block(unsigned short *output, unsigned char *input,
int channels, int block_size);
int fox61_adpcm_decode_block(unsigned short *output, unsigned char *input);
-int fox62_adpcm_decode_block(unsigned short *output, unsigned char *input,
- int channels);
+int fox62_adpcm_decode_block(unsigned short *output, unsigned char *input);
#endif
Index: adpcm.c
===================================================================
RCS file: /cvsroot/mplayer/main/adpcm.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- adpcm.c 2 Jan 2002 00:45:41 -0000 1.7
+++ adpcm.c 6 Jan 2002 01:56:19 -0000 1.8
@@ -296,55 +296,159 @@
// 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;
-
-static int counter = 0;
-
- 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];
+ int pred1;
+ int pred2;
+ int index1;
+ int index2;
+ int in_ptr = 0x10;
+ int out_ptr = 0;
+
+ int flag1 = 0;
+ int flag2 = 1;
+ int sum;
+ unsigned char last_byte = 0;
+ unsigned char nibble;
+
+ // ADPCM work variables
+ int sign;
+ int delta;
+ int step;
+ int diff;
+
+ pred1 = LE_16(&input[10]);
+ pred2 = LE_16(&input[12]);
+ SE_16BIT(pred1);
+ SE_16BIT(pred2);
+ sum = pred2;
+ index1 = input[14];
+ index2 = input[15];
- for (i = 16; i < FOX62_ADPCM_BLOCK_SIZE; i++)
+ 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;
}
More information about the MPlayer-cvslog
mailing list