[Mplayer-cvslog] CVS: main adpcm.c,1.8,1.9 adpcm.h,1.6,1.7 dec_audio.c,1.82,1.83 codec-cfg.c,1.69,1.70 codec-cfg.h,1.42,1.43
Mike Melanson
melanson at mplayer.dev.hu
Mon Feb 25 03:48:39 CET 2002
Update of /cvsroot/mplayer/main
In directory mplayer:/var/tmp.root/cvs-serv16121
Modified Files:
adpcm.c adpcm.h dec_audio.c codec-cfg.c codec-cfg.h
Log Message:
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
(including MS, DK4 and DK3 ADPCM)
Index: adpcm.c
===================================================================
RCS file: /cvsroot/mplayer/main/adpcm.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- adpcm.c 6 Jan 2002 01:56:19 -0000 1.8
+++ adpcm.c 25 Feb 2002 02:48:37 -0000 1.9
@@ -12,6 +12,7 @@
#include "config.h"
#include "bswap.h"
#include "adpcm.h"
+#include "mp_msg.h"
#define BE_16(x) (be2me_16(*(unsigned short *)(x)))
#define BE_32(x) (be2me_32(*(unsigned int *)(x)))
@@ -196,11 +197,19 @@
int predictor;
// fetch the header information, in stereo if both channels are present
+ if (input[stream_ptr] > 6)
+ mp_msg(MSGT_DECAUDIO, MSGL_WARN,
+ "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n",
+ input[stream_ptr]);
coeff1[0] = ms_adapt_coeff1[input[stream_ptr]];
coeff2[0] = ms_adapt_coeff2[input[stream_ptr]];
stream_ptr++;
if (channels == 2)
{
+ if (input[stream_ptr] > 6)
+ mp_msg(MSGT_DECAUDIO, MSGL_WARN,
+ "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n",
+ input[stream_ptr]);
coeff1[1] = ms_adapt_coeff1[input[stream_ptr]];
coeff2[1] = ms_adapt_coeff2[input[stream_ptr]];
stream_ptr++;
@@ -267,49 +276,71 @@
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 dk4_adpcm_decode_block(unsigned short *output, unsigned char *input,
+ int channels, int block_size)
{
int i;
- int predictor;
- int index;
+ int output_ptr;
+ int predictor_l = 0;
+ int predictor_r = 0;
+ int index_l = 0;
+ int index_r = 0;
// the first predictor value goes straight to the output
- predictor = output[0] = LE_16(&input[0]);
- SE_16BIT(predictor);
- index = input[2];
-
- // unpack the nibbles
- for (i = 4; i < FOX61_ADPCM_BLOCK_SIZE; i++)
+ predictor_l = output[0] = LE_16(&input[0]);
+ SE_16BIT(predictor_l);
+ index_l = input[2];
+ if (channels == 2)
{
- output[1 + (i - 4) * 2 + 0] = (input[i] >> 4) & 0x0F;
- output[1 + (i - 4) * 2 + 1] = input[i] & 0x0F;
+ predictor_r = output[1] = LE_16(&input[4]);
+ SE_16BIT(predictor_r);
+ index_r = input[6];
}
- decode_nibbles(&output[1], FOX61_ADPCM_SAMPLES_PER_BLOCK - 1, 1,
- predictor, index,
- 0, 0);
+ output_ptr = channels;
+ for (i = DK4_ADPCM_PREAMBLE_SIZE * channels; i < block_size; i++)
+ {
+ output[output_ptr++] = input[i] >> 4;
+ output[output_ptr++] = input[i] & 0x0F;
+ }
+
+ decode_nibbles(&output[channels],
+ (block_size - DK4_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels,
+ channels,
+ predictor_l, index_l,
+ predictor_r, index_r);
- return FOX61_ADPCM_SAMPLES_PER_BLOCK;
+ return (block_size - DK4_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels;
}
+#define DK3_GET_NEXT_NIBBLE() \
+ if (decode_top_nibble_next) \
+ { \
+ nibble = (last_byte >> 4) & 0x0F; \
+ decode_top_nibble_next = 0; \
+ } \
+ else \
+ { \
+ last_byte = input[in_ptr++]; \
+ nibble = last_byte & 0x0F; \
+ decode_top_nibble_next = 1; \
+ }
+
// 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 dk3_adpcm_decode_block(unsigned short *output, unsigned char *input)
{
- int pred1;
- int pred2;
- int index1;
- int index2;
+ int sum_pred;
+ int diff_pred;
+ int sum_index;
+ int diff_index;
+ int diff_channel;
int in_ptr = 0x10;
int out_ptr = 0;
- int flag1 = 0;
- int flag2 = 1;
- int sum;
unsigned char last_byte = 0;
unsigned char nibble;
+ int decode_top_nibble_next = 0;
// ADPCM work variables
int sign;
@@ -317,137 +348,93 @@
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];
+ sum_pred = LE_16(&input[10]);
+ diff_pred = LE_16(&input[12]);
+ SE_16BIT(sum_pred);
+ SE_16BIT(diff_pred);
+ diff_channel = diff_pred;
+ sum_index = input[14];
+ diff_index = input[15];
while (in_ptr < 2048)
{
- if (flag2)
- {
- last_byte = input[in_ptr++];
- nibble = last_byte & 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);
+ // process the first predictor of the sum channel
+ DK3_GET_NEXT_NIBBLE();
- index1 += adpcm_index[nibble];
- CLAMP_0_TO_88(index1);
+ step = adpcm_step[sum_index];
- if (flag1)
- flag2 = 0;
- else
- {
- nibble = (last_byte >> 4) & 0x0F;
+ sign = nibble & 8;
+ delta = nibble & 7;
- step = adpcm_step[index2];
+ diff = step >> 3;
+ if (delta & 4) diff += step;
+ if (delta & 2) diff += step >> 1;
+ if (delta & 1) diff += step >> 2;
- sign = nibble & 8;
- delta = nibble & 7;
+ if (sign)
+ sum_pred -= diff;
+ else
+ sum_pred += diff;
- diff = step >> 3;
- if (delta & 4) diff += step;
- if (delta & 2) diff += step >> 1;
- if (delta & 1) diff += step >> 2;
+ CLAMP_S16(sum_pred);
- if (sign)
- pred2 -= diff;
- else
- pred2 += diff;
+ sum_index += adpcm_index[nibble];
+ CLAMP_0_TO_88(sum_index);
+
+ // process the diff channel predictor
+ DK3_GET_NEXT_NIBBLE();
- CLAMP_S16(pred2);
+ step = adpcm_step[diff_index];
- index2 += adpcm_index[nibble];
- CLAMP_0_TO_88(index2);
+ sign = nibble & 8;
+ delta = nibble & 7;
- sum = (sum + pred2) / 2;
- }
- output[out_ptr++] = pred1 + sum;
- output[out_ptr++] = pred1 - sum;
+ diff = step >> 3;
+ if (delta & 4) diff += step;
+ if (delta & 2) diff += step >> 1;
+ if (delta & 1) diff += step >> 2;
- flag1 ^= 1;
- if (in_ptr >= 2048)
- break;
- }
+ if (sign)
+ diff_pred -= diff;
else
- {
- nibble = (last_byte >> 4) & 0x0F;
-
- step = adpcm_step[index1];
-
- sign = nibble & 8;
- delta = nibble & 7;
+ diff_pred += diff;
- diff = step >> 3;
- if (delta & 4) diff += step;
- if (delta & 2) diff += step >> 1;
- if (delta & 1) diff += step >> 2;
+ CLAMP_S16(diff_pred);
- if (sign)
- pred1 -= diff;
- else
- pred1 += diff;
+ diff_index += adpcm_index[nibble];
+ CLAMP_0_TO_88(diff_index);
- CLAMP_S16(pred1);
+ // output the first pair of stereo PCM samples
+ diff_channel = (diff_channel + diff_pred) / 2;
+ output[out_ptr++] = sum_pred + diff_channel;
+ output[out_ptr++] = sum_pred - diff_channel;
- index1 += adpcm_index[nibble];
- CLAMP_0_TO_88(index1);
+ // process the second predictor of the sum channel
+ DK3_GET_NEXT_NIBBLE();
- if (flag1)
- flag2 = 1;
- else
- {
- last_byte = input[in_ptr++];
- nibble = last_byte & 0x0F;
+ step = adpcm_step[sum_index];
- step = adpcm_step[index2];
+ sign = nibble & 8;
+ delta = nibble & 7;
- 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;
- 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);
+ if (sign)
+ sum_pred -= diff;
+ else
+ sum_pred += diff;
- sum = (sum + pred2) / 2;
- }
+ CLAMP_S16(sum_pred);
- output[out_ptr++] = pred1 + sum;
- output[out_ptr++] = pred1 - sum;
+ sum_index += adpcm_index[nibble];
+ CLAMP_0_TO_88(sum_index);
- flag1 ^= 1;
- if (in_ptr >= 2048)
- break;
- }
+ // output the second pair of stereo PCM samples
+ output[out_ptr++] = sum_pred + diff_channel;
+ output[out_ptr++] = sum_pred - diff_channel;
}
return out_ptr;
Index: adpcm.h
===================================================================
RCS file: /cvsroot/mplayer/main/adpcm.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- adpcm.h 6 Jan 2002 01:56:19 -0000 1.6
+++ adpcm.h 25 Feb 2002 02:48:37 -0000 1.7
@@ -10,21 +10,22 @@
#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)
+#define DK4_ADPCM_PREAMBLE_SIZE 4
+#define DK4_ADPCM_SAMPLES_PER_BLOCK \
+ (((sh_audio->wf->nBlockAlign - DK4_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
+#define DK3_ADPCM_PREAMBLE_SIZE 8
+#define DK3_ADPCM_BLOCK_SIZE 0x400
// this isn't exact
-#define FOX62_ADPCM_SAMPLES_PER_BLOCK 6000
+#define DK3_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 dk4_adpcm_decode_block(unsigned short *output, unsigned char *input,
+ int channels, int block_size);
+int dk3_adpcm_decode_block(unsigned short *output, unsigned char *input);
+
#endif
Index: dec_audio.c
===================================================================
RCS file: /cvsroot/mplayer/main/dec_audio.c,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -r1.82 -r1.83
--- dec_audio.c 3 Feb 2002 10:27:26 -0000 1.82
+++ dec_audio.c 25 Feb 2002 02:48:37 -0000 1.83
@@ -425,21 +425,21 @@
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;
- sh_audio->ds->ss_mul=FOX62_ADPCM_BLOCK_SIZE;
+case AFM_DK4ADPCM:
+ sh_audio->audio_out_minsize=DK4_ADPCM_SAMPLES_PER_BLOCK * 4;
+ sh_audio->ds->ss_div=DK4_ADPCM_SAMPLES_PER_BLOCK;
+ sh_audio->ds->ss_mul=sh_audio->wf->nBlockAlign;
+ break;
+case AFM_DK3ADPCM:
+ sh_audio->audio_out_minsize=DK3_ADPCM_SAMPLES_PER_BLOCK * 4;
+ sh_audio->ds->ss_div=DK3_ADPCM_SAMPLES_PER_BLOCK;
+ sh_audio->ds->ss_mul=DK3_ADPCM_BLOCK_SIZE;
break;
case AFM_ROQAUDIO:
// minsize was stored in wf->nBlockAlign by the RoQ demuxer
sh_audio->audio_out_minsize=sh_audio->wf->nBlockAlign;
- sh_audio->ds->ss_div=FOX62_ADPCM_SAMPLES_PER_BLOCK;
- sh_audio->ds->ss_mul=FOX62_ADPCM_BLOCK_SIZE;
+ sh_audio->ds->ss_div=DK3_ADPCM_SAMPLES_PER_BLOCK;
+ sh_audio->ds->ss_mul=DK3_ADPCM_BLOCK_SIZE;
sh_audio->context = roq_decode_audio_init();
break;
case AFM_MPEG:
@@ -724,17 +724,17 @@
sh_audio->i_bps = sh_audio->wf->nBlockAlign *
(sh_audio->channels*sh_audio->samplerate) / MS_ADPCM_SAMPLES_PER_BLOCK;
break;
-case AFM_FOX61ADPCM:
+case AFM_DK4ADPCM:
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;
+ sh_audio->i_bps = sh_audio->wf->nBlockAlign *
+ (sh_audio->channels*sh_audio->samplerate) / DK4_ADPCM_SAMPLES_PER_BLOCK;
break;
-case AFM_FOX62ADPCM:
+case AFM_DK3ADPCM:
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;
+ sh_audio->i_bps=DK3_ADPCM_BLOCK_SIZE*
+ (sh_audio->channels*sh_audio->samplerate) / DK3_ADPCM_SAMPLES_PER_BLOCK;
break;
case AFM_ROQAUDIO:
sh_audio->channels=sh_audio->wf->nChannels;
@@ -1163,21 +1163,24 @@
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)
+ case AFM_DK4ADPCM:
+ { static unsigned char *ibuf = NULL;
+ if (!ibuf)
+ ibuf = (unsigned char *)malloc(sh_audio->wf->nBlockAlign);
+ if (demux_read_data(sh_audio->ds, ibuf, sh_audio->wf->nBlockAlign) !=
+ sh_audio->wf->nBlockAlign)
break; // EOF
- len=2*fox61_adpcm_decode_block((unsigned short*)buf,ibuf);
+ len=2*dk4_adpcm_decode_block((unsigned short*)buf,ibuf,
+ sh_audio->wf->nChannels, sh_audio->wf->nBlockAlign);
break;
}
- case AFM_FOX62ADPCM:
- { unsigned char ibuf[FOX62_ADPCM_BLOCK_SIZE * 2]; // bytes / stereo frame
+ case AFM_DK3ADPCM:
+ { unsigned char ibuf[DK3_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)
+ DK3_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels) !=
+ DK3_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels)
break; // EOF
- len = 2 * fox62_adpcm_decode_block(
+ len = 2 * dk3_adpcm_decode_block(
(unsigned short*)buf,ibuf);
break;
}
Index: codec-cfg.c
===================================================================
RCS file: /cvsroot/mplayer/main/codec-cfg.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- codec-cfg.c 12 Feb 2002 17:52:30 -0000 1.69
+++ codec-cfg.c 25 Feb 2002 02:48:37 -0000 1.70
@@ -224,8 +224,8 @@
"liba52",
"g72x",
"imaadpcm",
- "fox61adpcm",
- "fox62adpcm",
+ "dk4adpcm",
+ "dk3adpcm",
"roqaudio",
NULL
};
Index: codec-cfg.h
===================================================================
RCS file: /cvsroot/mplayer/main/codec-cfg.h,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- codec-cfg.h 12 Feb 2002 17:33:27 -0000 1.42
+++ codec-cfg.h 25 Feb 2002 02:48:37 -0000 1.43
@@ -35,8 +35,8 @@
#define AFM_A52 14
#define AFM_G72X 15
#define AFM_IMAADPCM 16
-#define AFM_FOX61ADPCM 17
-#define AFM_FOX62ADPCM 18
+#define AFM_DK4ADPCM 17
+#define AFM_DK3ADPCM 18
#define AFM_ROQAUDIO 19
#define VFM_MPEG 1
More information about the MPlayer-cvslog
mailing list