mirror of
https://github.com/mpv-player/mpv
synced 2025-02-17 13:17:13 +00:00
added initial, not-yet-functional, support for fox62 audio
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3827 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
57a9da01e2
commit
296399a5bb
154
adpcm.c
154
adpcm.c
@ -32,13 +32,41 @@ static int adpcm_step[89] =
|
||||
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 @@ int ms_adpcm_decode_block(unsigned short *output, unsigned char *input,
|
||||
|
||||
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;
|
||||
}
|
||||
|
16
adpcm.h
16
adpcm.h
@ -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
|
||||
|
@ -219,6 +219,7 @@ static short get_driver(char *s,int audioflag)
|
||||
"liba52",
|
||||
"g72x",
|
||||
"imaadpcm",
|
||||
"fox62adpcm",
|
||||
NULL
|
||||
};
|
||||
static char *videodrv[] = {
|
||||
|
@ -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
|
||||
|
22
dec_audio.c
22
dec_audio.c
@ -288,6 +288,11 @@ case AFM_MSADPCM:
|
||||
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 @@ case AFM_MSADPCM:
|
||||
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 @@ int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){
|
||||
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();
|
||||
|
@ -330,6 +330,12 @@ audiocodec msadpcm
|
||||
format 0x2
|
||||
driver msadpcm
|
||||
|
||||
audiocodec fox62adpcm
|
||||
info "Format 0x62 ADPCM"
|
||||
status working
|
||||
format 0x62
|
||||
driver fox62adpcm
|
||||
|
||||
; =============== WINDOWS DLL's ==============
|
||||
|
||||
videocodec vp3
|
||||
|
Loading…
Reference in New Issue
Block a user