[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