changeset 3826:8a88ed2473aa

added initial, not-yet-functional, support for fox62 audio
author melanson
date Fri, 28 Dec 2001 06:47:15 +0000
parents 7735c5a87121
children 6e7df97bd120
files adpcm.c adpcm.h codec-cfg.c codec-cfg.h dec_audio.c etc/codecs.conf
diffstat 6 files changed, 196 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/adpcm.c	Fri Dec 28 02:04:06 2001 +0000
+++ b/adpcm.c	Fri Dec 28 06:47:15 2001 +0000
@@ -32,13 +32,41 @@
   15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
 };
 
+//static int fox62_step[89] =
+static int fox62_step[] =
+{
+  0x7, 0x8, 0x9, 0xa,
+  0xb, 0xc, 0xd, 0xf,
+  0x10, 0x12, 0x13, 0x15,
+  0x17, 0x1a, 0x1c, 0x1f,
+  0x22, 0x26, 0x29, 0x2e,
+  0x32, 0x37, 0x3d, 0x43,
+  0x4a, 0x51, 0x59, 0x62,
+  0x6c, 0x76, 0x82, 0x8f,
+  0x9e, 0xad, 0xbf, 0xd2,
+  0xe7, 0xfe, 0x117, 0x133,
+  0x152, 0x174, 0x199, 0x1c2,
+  0x1ef, 0x220, 0x256, 0x292,
+  0x2d4, 0x31d, 0x36c, 0x3c4,
+  0x424, 0x48e, 0x503, 0x583,
+  0x610, 0x6ac, 0x756, 0x812,
+  0x8e1, 0x9c4, 0xabe, 0x8d1,
+  0xcff, 0xe4c, 0xfba, 0x114d,
+  0x1308, 0x14ef, 0x1707, 0x1954,
+  0x1bdd, 0x1ea6, 0x21b7, 0x2516,
+  0x28cb, 0x2cdf, 0x315c, 0x364c,
+  0x3bba, 0x41b2, 0x4844, 0x4f7e,
+  0x5771, 0x6030, 0x69ce, 0x7463,
+  0x7FFF
+};
+
 static int adpcm_index[16] =
 {
   -1, -1, -1, -1, 2, 4, 6, 8,
   -1, -1, -1, -1, 2, 4, 6, 8
 };
 
-static int format_0x62_table[16] =
+static int fox62_extra_table[16] =
 {
   1, 3, 5, 7, 9, 11, 13, 15,
   -1, -3, -5, -7, -9, -11, -13, -15
@@ -269,3 +297,127 @@
 
   return MS_ADPCM_SAMPLES_PER_BLOCK * channels;
 }
+
+// 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 predictor_l;
+  int predictor_r;
+  int index_l;
+  int index_r;
+  int code_l;
+  int code_r;
+  int i;
+  int out_ptr = 0;
+
+  int temp1, temp2, edi, eax, edx;
+static int counter = 0;
+
+  predictor_l = LE_16(&input[10]);
+  edi = predictor_r = LE_16(&input[12]);
+  SE_16BIT(predictor_l);
+  SE_16BIT(predictor_r);
+  index_l = input[14];
+  index_r = input[15];
+
+  for (i = 16; i < FOX62_ADPCM_BLOCK_SIZE; i++)
+  {
+    code_l = input[i] & 0x0F;
+    code_r = input[i] >> 4;
+if (counter == 0)
+  printf ("code_l = %02X, predictor_l = %04X, index_l = %02X\n",
+    code_l, predictor_l, index_l);
+if (counter == 0)
+  printf ("code_r = %02X, predictor_r = %04X, index_r = %02X\n",
+    code_r, predictor_r, index_r);
+
+    // left side
+if (counter == 0)
+  printf ("step = %04X, extra = %02X\n", fox62_step[index_l], fox62_extra_table[code_l]);
+    temp1 = fox62_step[index_l] * fox62_extra_table[code_l];
+if (counter == 0)
+  printf ("temp1 (before) = %04X\n", temp1);
+    if (temp1 < 0)
+      temp1 += 7;
+if (counter == 0)
+  printf ("temp1 (after) = %04X\n", temp1);
+
+    temp2 = predictor_l;
+    temp1 /= 8;
+if (counter == 0)
+  printf ("temp1 (after div) = %04X\n", temp1);
+    temp2 += temp1;
+if (counter == 0)
+  printf ("temp2 (predictor_l before clamp) = %04X\n", temp2);
+    CLAMP_S16(temp2);
+if (counter == 0)
+  printf ("temp2 (predictor_l after clamp) = %04X\n", temp2);
+    predictor_l = temp2;
+
+    index_l += adpcm_index[code_l];
+if (counter == 0)
+  printf ("adjusted index_l = %02X\n", index_l);
+    CLAMP_0_TO_88(index_l);
+
+    // right side
+if (counter == 0)
+  printf ("step = %04X, extra = %02X\n", fox62_step[index_r], fox62_extra_table[code_r]);
+    temp1 = fox62_step[index_r] * fox62_extra_table[code_r];
+if (counter == 0)
+  printf ("temp1 (before) = %04X\n", temp1);
+    if (temp1 < 0)
+      temp1 += 7;
+if (counter == 0)
+  printf ("temp1 (after) = %04X\n", temp1);
+
+    temp2 = predictor_r;
+    temp1 /= 8;
+if (counter == 0)
+  printf ("temp1 (after div) = %04X\n", temp1);
+    temp2 += temp1;
+if (counter == 0)
+  printf ("temp2 (predictor_r before clamp) = %04X\n", temp2);
+    CLAMP_S16(temp2);
+if (counter == 0)
+  printf ("temp2 (predictor_r after clamp) = %04X\n", temp2);
+    predictor_r = temp2;
+
+    index_r += adpcm_index[code_r];
+if (counter == 0)
+  printf ("adjusted index_r = %02X\n", index_r);
+    CLAMP_0_TO_88(index_r);
+
+    // do the weird final output process
+    edi += predictor_r;
+    edi /= 2;
+    eax = predictor_l + edi;
+    edx = edi * 2;
+if (counter == 0)
+  printf ("eax = %08X, edx = %08X, edi = %08X\n", eax, edx, edi);
+    output[out_ptr++] = eax;
+
+    predictor_l = eax;
+    eax -= edx;
+if (counter == 0)
+  printf ("eax = %08X, edx = %08X, edi = %08X\n", eax, edx, edi);
+// x24 += 4
+    output[out_ptr++] = eax;
+    predictor_l = eax;
+    eax += edi;
+if (counter == 0)
+  printf ("eax = %08X, edx = %08X, edi = %08X\n", eax, edx, edi);
+    edi = predictor_r;
+if (counter == 0)
+  printf ("eax = %08X, edx = %08X, edi = %08X\n", eax, edx, edi);
+    predictor_l = eax;
+
+if (counter == 0)
+  printf ("L-sample = %04X, R-sample = %04X\n",
+    output[out_ptr-2], output[out_ptr-1]);
+counter++;
+  }
+
+  return FOX62_ADPCM_SAMPLES_PER_BLOCK * channels;
+}
--- a/adpcm.h	Fri Dec 28 02:04:06 2001 +0000
+++ b/adpcm.h	Fri Dec 28 06:47:15 2001 +0000
@@ -1,15 +1,27 @@
 #ifndef ADPCM_H
 #define ADPCM_H
 
+#define IMA_ADPCM_PREAMBLE_SIZE 2
 #define IMA_ADPCM_BLOCK_SIZE 0x22
-#define IMA_ADPCM_SAMPLES_PER_BLOCK 0x40
+#define IMA_ADPCM_SAMPLES_PER_BLOCK \
+  ((IMA_ADPCM_BLOCK_SIZE - IMA_ADPCM_PREAMBLE_SIZE) * 2)
 
+#define MS_ADPCM_PREAMBLE_SIZE 7
 #define MS_ADPCM_BLOCK_SIZE 256
-#define MS_ADPCM_SAMPLES_PER_BLOCK ((256 - 7) * 2)
+#define MS_ADPCM_SAMPLES_PER_BLOCK \
+  ((MS_ADPCM_BLOCK_SIZE - MS_ADPCM_PREAMBLE_SIZE) * 2)
+
+// 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)
 
 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 fox62_adpcm_decode_block(unsigned short *output, unsigned char *input,
+  int channels);
 
 #endif
--- a/codec-cfg.c	Fri Dec 28 02:04:06 2001 +0000
+++ b/codec-cfg.c	Fri Dec 28 06:47:15 2001 +0000
@@ -219,6 +219,7 @@
 		"liba52",
 		"g72x",
 		"imaadpcm",
+		"fox62adpcm",
 		NULL
 	};
 	static char *videodrv[] = {
--- a/codec-cfg.h	Fri Dec 28 02:04:06 2001 +0000
+++ b/codec-cfg.h	Fri Dec 28 06:47:15 2001 +0000
@@ -34,6 +34,7 @@
 #define AFM_A52 14
 #define AFM_G72X 15
 #define AFM_IMAADPCM 16
+#define AFM_FOX62ADPCM 17
 
 #define VFM_MPEG 1
 #define VFM_VFW 2
--- a/dec_audio.c	Fri Dec 28 02:04:06 2001 +0000
+++ b/dec_audio.c	Fri Dec 28 06:47:15 2001 +0000
@@ -288,6 +288,11 @@
   sh_audio->ds->ss_div=MS_ADPCM_SAMPLES_PER_BLOCK;
   sh_audio->ds->ss_mul=MS_ADPCM_BLOCK_SIZE;
   break;
+case AFM_FOX62ADPCM:
+  sh_audio->audio_out_minsize=FOX62_ADPCM_SAMPLES_PER_BLOCK * 4;
+  sh_audio->ds->ss_div=FOX62_ADPCM_SAMPLES_PER_BLOCK;
+  sh_audio->ds->ss_mul=FOX62_ADPCM_BLOCK_SIZE;
+  break;
 case AFM_MPEG:
   // MPEG Audio:
   sh_audio->audio_out_minsize=4608;
@@ -517,7 +522,13 @@
   sh_audio->channels=sh_audio->wf->nChannels;
   sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
   sh_audio->i_bps=MS_ADPCM_BLOCK_SIZE*
-    (sh_audio->channels*sh_audio->samplerate)/MS_ADPCM_SAMPLES_PER_BLOCK;
+    (sh_audio->channels*sh_audio->samplerate) / MS_ADPCM_SAMPLES_PER_BLOCK;
+  break;
+case AFM_FOX62ADPCM:
+  sh_audio->channels=sh_audio->wf->nChannels;
+  sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
+  sh_audio->i_bps=FOX62_ADPCM_BLOCK_SIZE*
+    (sh_audio->channels*sh_audio->samplerate) / FOX62_ADPCM_SAMPLES_PER_BLOCK;
   break;
 case AFM_MPEG: {
   // MPEG Audio:
@@ -931,6 +942,15 @@
         len=2*ms_adpcm_decode_block((unsigned short*)buf,ibuf, sh_audio->wf->nChannels);
         break;
       }
+      case AFM_FOX62ADPCM:
+      { unsigned char ibuf[FOX62_ADPCM_BLOCK_SIZE * 2]; // bytes / stereo frame
+        if (demux_read_data(sh_audio->ds, ibuf,
+          FOX62_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels) != 
+          FOX62_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels) 
+          break; // EOF
+        len=2*fox62_adpcm_decode_block((unsigned short*)buf,ibuf, sh_audio->wf->nChannels);
+        break;
+      }
       case AFM_AC3: // AC3 decoder
         //printf("{1:%d}",avi_header.idx_pos);fflush(stdout);
         if(!sh_audio->ac3_frame) sh_audio->ac3_frame=ac3_decode_frame();
--- a/etc/codecs.conf	Fri Dec 28 02:04:06 2001 +0000
+++ b/etc/codecs.conf	Fri Dec 28 06:47:15 2001 +0000
@@ -330,6 +330,12 @@
   format 0x2
   driver msadpcm
 
+audiocodec fox62adpcm
+  info "Format 0x62 ADPCM"
+  status working
+  format 0x62
+  driver fox62adpcm
+
 ; =============== WINDOWS DLL's ==============
 
 videocodec vp3