changeset 3933:60db4273246d

added initial support for format 0x61 ADPCM (sounds good, but still pops)
author melanson
date Tue, 01 Jan 2002 20:04:54 +0000
parents 277187affd9a
children e8e7ca8995a1
files adpcm.c adpcm.h codec-cfg.c codec-cfg.h dec_audio.c etc/codecs.conf
diffstat 6 files changed, 98 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/adpcm.c	Tue Jan 01 19:39:59 2002 +0000
+++ b/adpcm.c	Tue Jan 01 20:04:54 2002 +0000
@@ -298,6 +298,68 @@
   return (block_size - (MS_ADPCM_PREAMBLE_SIZE * channels)) * 2;
 }
 
+// note: This decoder assumes the format 0x61 data always comes in
+// mono flavor
+int fox61_adpcm_decode_block(unsigned short *output, unsigned char *input)
+{
+  int i;
+  int out_ptr = 0;
+
+  int predictor;
+  int index;
+  int nibble;
+  int sign;
+  int delta;
+  int diff;
+  int step;	
+
+  predictor = output[out_ptr++] = LE_16(&input[0]);
+  index = input[2];
+
+  // iterate through and decode the rest of the bytes
+  for (i = 4; i < FOX61_ADPCM_BLOCK_SIZE; i++)
+  {
+    nibble = (input[i] >> 4) & 0x0F;
+
+    step = adpcm_step[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)
+      predictor -= diff;
+    else
+      predictor += diff;
+    CLAMP_S16(predictor);
+    output[out_ptr++] = predictor;
+    index += adpcm_index[nibble];
+    CLAMP_0_TO_88(index);
+
+    nibble = input[i] & 0x0F;
+
+    step = adpcm_step[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)
+      predictor -= diff;
+    else
+      predictor += diff;
+    CLAMP_S16(predictor);
+    output[out_ptr++] = predictor;
+    index += adpcm_index[nibble];
+    CLAMP_0_TO_88(index);
+  }
+
+  return FOX61_ADPCM_SAMPLES_PER_BLOCK;
+}
+
+
 // note: This decoder assumes the format 0x62 data always comes in
 // stereo flavor
 int fox62_adpcm_decode_block(unsigned short *output, unsigned char *input,
--- a/adpcm.h	Tue Jan 01 19:39:59 2002 +0000
+++ b/adpcm.h	Tue Jan 01 20:04:54 2002 +0000
@@ -10,6 +10,11 @@
 #define MS_ADPCM_SAMPLES_PER_BLOCK \
   ((sh_audio->wf->nBlockAlign - MS_ADPCM_PREAMBLE_SIZE) * 2)
 
+#define FOX61_ADPCM_PREAMBLE_SIZE 4
+#define FOX61_ADPCM_BLOCK_SIZE 0x200
+#define FOX61_ADPCM_SAMPLES_PER_BLOCK \
+  (((FOX61_ADPCM_BLOCK_SIZE - FOX61_ADPCM_PREAMBLE_SIZE) * 2) + 1)
+
 // pretend there's such a thing as mono for this format
 #define FOX62_ADPCM_PREAMBLE_SIZE 8
 #define FOX62_ADPCM_BLOCK_SIZE 0x400
@@ -20,7 +25,7 @@
   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);
-
 #endif
--- a/codec-cfg.c	Tue Jan 01 19:39:59 2002 +0000
+++ b/codec-cfg.c	Tue Jan 01 20:04:54 2002 +0000
@@ -219,6 +219,7 @@
 		"liba52",
 		"g72x",
 		"imaadpcm",
+		"fox61adpcm",
 		"fox62adpcm",
 		NULL
 	};
--- a/codec-cfg.h	Tue Jan 01 19:39:59 2002 +0000
+++ b/codec-cfg.h	Tue Jan 01 20:04:54 2002 +0000
@@ -34,7 +34,8 @@
 #define AFM_A52 14
 #define AFM_G72X 15
 #define AFM_IMAADPCM 16
-#define AFM_FOX62ADPCM 17
+#define AFM_FOX61ADPCM 17
+#define AFM_FOX62ADPCM 18
 
 #define VFM_MPEG 1
 #define VFM_VFW 2
--- a/dec_audio.c	Tue Jan 01 19:39:59 2002 +0000
+++ b/dec_audio.c	Tue Jan 01 20:04:54 2002 +0000
@@ -412,6 +412,11 @@
   sh_audio->ds->ss_div = MS_ADPCM_SAMPLES_PER_BLOCK;
   sh_audio->ds->ss_mul = sh_audio->wf->nBlockAlign;
   break;
+case AFM_FOX61ADPCM:
+  sh_audio->audio_out_minsize=FOX61_ADPCM_SAMPLES_PER_BLOCK * 4;
+  sh_audio->ds->ss_div=FOX61_ADPCM_SAMPLES_PER_BLOCK;
+  sh_audio->ds->ss_mul=FOX61_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;
@@ -693,6 +698,12 @@
   sh_audio->i_bps = sh_audio->wf->nBlockAlign *
     (sh_audio->channels*sh_audio->samplerate) / MS_ADPCM_SAMPLES_PER_BLOCK;
   break;
+case AFM_FOX61ADPCM:
+  sh_audio->channels=sh_audio->wf->nChannels;
+  sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
+  sh_audio->i_bps=FOX61_ADPCM_BLOCK_SIZE*
+    (sh_audio->channels*sh_audio->samplerate) / FOX61_ADPCM_SAMPLES_PER_BLOCK;
+  break;
 case AFM_FOX62ADPCM:
   sh_audio->channels=sh_audio->wf->nChannels;
   sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
@@ -1122,13 +1133,22 @@
           sh_audio->wf->nBlockAlign);
         break;
       }
+      case AFM_FOX61ADPCM:
+      { unsigned char ibuf[FOX61_ADPCM_BLOCK_SIZE]; // bytes / stereo frame
+        if (demux_read_data(sh_audio->ds, ibuf, FOX61_ADPCM_BLOCK_SIZE) != 
+          FOX61_ADPCM_BLOCK_SIZE)
+          break; // EOF
+        len=2*fox61_adpcm_decode_block((unsigned short*)buf,ibuf);
+        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);
+        len = 2 * fox62_adpcm_decode_block(
+          (unsigned short*)buf,ibuf, sh_audio->wf->nChannels);
         break;
       }
 #ifdef USE_LIBAC3
--- a/etc/codecs.conf	Tue Jan 01 19:39:59 2002 +0000
+++ b/etc/codecs.conf	Tue Jan 01 20:04:54 2002 +0000
@@ -331,6 +331,12 @@
   format 0x2
   driver msadpcm
 
+audiocodec fox61adpcm
+  info "Format 0x61 ADPCM"
+  status working
+  format 0x61
+  driver fox61adpcm
+
 audiocodec fox62adpcm
   info "Format 0x62 ADPCM"
   status buggy