mirror of
https://github.com/mpv-player/mpv.git
synced 2026-10-28 23:13:18 +08:00
fixed format 0x62 ADPCM audio
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4002 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
@@ -296,55 +296,159 @@ int fox61_adpcm_decode_block(unsigned short *output, unsigned char *input)
|
||||
|
||||
// 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;
|
||||
int pred1;
|
||||
int pred2;
|
||||
int index1;
|
||||
int index2;
|
||||
int in_ptr = 0x10;
|
||||
int out_ptr = 0;
|
||||
|
||||
static int counter = 0;
|
||||
int flag1 = 0;
|
||||
int flag2 = 1;
|
||||
int sum;
|
||||
unsigned char last_byte = 0;
|
||||
unsigned char nibble;
|
||||
|
||||
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];
|
||||
// ADPCM work variables
|
||||
int sign;
|
||||
int delta;
|
||||
int step;
|
||||
int diff;
|
||||
|
||||
for (i = 16; i < FOX62_ADPCM_BLOCK_SIZE; i++)
|
||||
pred1 = LE_16(&input[10]);
|
||||
pred2 = LE_16(&input[12]);
|
||||
SE_16BIT(pred1);
|
||||
SE_16BIT(pred2);
|
||||
sum = pred2;
|
||||
index1 = input[14];
|
||||
index2 = input[15];
|
||||
|
||||
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;
|
||||
|
||||
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 = 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;
|
||||
}
|
||||
}
|
||||
|
||||
decode_nibbles(output, FOX62_ADPCM_SAMPLES_PER_BLOCK * channels, channels,
|
||||
predictor_l, index_l,
|
||||
predictor_r, index_r);
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -1153,7 +1153,7 @@ int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){
|
||||
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
|
||||
|
||||
+1
-1
@@ -346,7 +346,7 @@ audiocodec fox61adpcm
|
||||
|
||||
audiocodec fox62adpcm
|
||||
info "Format 0x62 ADPCM"
|
||||
status buggy
|
||||
status working
|
||||
format 0x62
|
||||
driver fox62adpcm
|
||||
|
||||
|
||||
Reference in New Issue
Block a user