1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-03 21:52:12 +00:00

implemented open source MS ADPCM decoder

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3788 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
melanson 2001-12-27 05:09:43 +00:00
parent 5194d8791e
commit a527e0f508
6 changed files with 187 additions and 53 deletions

140
adpcm.c
View File

@ -1,6 +1,11 @@
/*
Unified ADPCM Decoder for MPlayer
This file is in charge of decoding all of the various ADPCM data
formats that various entities have created. Details about the data
formats can be found here:
http://www.pcisys.net/~melanson/codecs/
(C) 2001 Mike Melanson
*/
@ -13,13 +18,60 @@
#define LE_16(x) (le2me_16(*(unsigned short *)(x)))
#define LE_32(x) (le2me_32(*(unsigned int *)(x)))
// pertinent tables
static int adpcm_step[89] =
{
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};
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] =
{
1, 3, 5, 7, 9, 11, 13, 15,
-1, -3, -5, -7, -9, -11, -13, -15
};
static int ms_adapt_table[] =
{
230, 230, 230, 230, 307, 409, 512, 614,
768, 614, 512, 409, 307, 230, 230, 230
};
static int ms_adapt_coeff1[] =
{
256, 512, 0, 192, 240, 460, 392
};
static int ms_adapt_coeff2[] =
{
0, -256, 0, 64, 0, -208, -232
};
// useful macros
// clamp a number between 0 and 88
#define CLAMP_0_TO_88(x) if (x < 0) x = 0; else if (x > 88) x = 88;
// clamp a number within a signed 16-bit range
#define CLAMP_S16(x) if (x < -32768) x = -32768; \
else if (x > 32767) x = 32767;
// clamp a number above 16
#define CLAMP_ABOVE_16(x) if (x < 16) x = 16;
// sign extend a 16-bit value
#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000;
// sign extend a 4-bit value
#define SE_4BIT(x) if (x & 0x8) x -= 0x10;
void ima_dvi_decode_nibbles(unsigned short *output, int channels,
int predictor_l, int index_l,
@ -129,3 +181,91 @@ int ima_adpcm_decode_block(unsigned short *output, unsigned char *input,
return IMA_ADPCM_SAMPLES_PER_BLOCK * channels;
}
int ms_adpcm_decode_block(unsigned short *output, unsigned char *input,
int channels)
{
int current_channel = 0;
int idelta[2];
int sample1[2];
int sample2[2];
int coeff1[2];
int coeff2[2];
int stream_ptr = 0;
int out_ptr = 0;
int upper_nibble = 1;
int nibble;
int snibble; // signed nibble
int predictor;
// fetch the header information, in stereo if both channels are present
coeff1[0] = ms_adapt_coeff1[input[stream_ptr]];
coeff2[0] = ms_adapt_coeff2[input[stream_ptr]];
stream_ptr++;
if (channels == 2)
{
coeff1[1] = ms_adapt_coeff1[input[stream_ptr]];
coeff2[1] = ms_adapt_coeff2[input[stream_ptr]];
stream_ptr++;
}
idelta[0] = LE_16(&input[stream_ptr]);
stream_ptr += 2;
SE_16BIT(idelta[0]);
if (channels == 2)
{
idelta[1] = LE_16(&input[stream_ptr]);
stream_ptr += 2;
SE_16BIT(idelta[1]);
}
sample1[0] = LE_16(&input[stream_ptr]);
stream_ptr += 2;
SE_16BIT(sample1[0]);
if (channels == 2)
{
sample1[1] = LE_16(&input[stream_ptr]);
stream_ptr += 2;
SE_16BIT(sample1[1]);
}
sample2[0] = LE_16(&input[stream_ptr]);
stream_ptr += 2;
SE_16BIT(sample2[0]);
if (channels == 2)
{
sample2[1] = LE_16(&input[stream_ptr]);
stream_ptr += 2;
SE_16BIT(sample2[1]);
}
while (stream_ptr < MS_ADPCM_BLOCK_SIZE * channels)
{
// get the next nibble
if (upper_nibble)
nibble = snibble = input[stream_ptr] >> 4;
else
nibble = snibble = input[stream_ptr++] & 0x0F;
upper_nibble ^= 1;
SE_4BIT(snibble);
predictor = (
((sample1[current_channel] * coeff1[current_channel]) +
(sample2[current_channel] * coeff2[current_channel])) / 256) +
(snibble * idelta[current_channel]);
CLAMP_S16(predictor);
sample2[current_channel] = sample1[current_channel];
sample1[current_channel] = predictor;
output[out_ptr++] = predictor;
// compute the next adaptive scale factor (a.k.a. the variable idelta)
idelta[current_channel] =
(ms_adapt_table[nibble] * idelta[current_channel]) / 256;
CLAMP_ABOVE_16(idelta[current_channel]);
// toggle the channel
current_channel ^= channels - 1;
}
return MS_ADPCM_SAMPLES_PER_BLOCK * channels;
}

29
adpcm.h
View File

@ -4,29 +4,12 @@
#define IMA_ADPCM_BLOCK_SIZE 0x22
#define IMA_ADPCM_SAMPLES_PER_BLOCK 0x40
static int adpcm_step[89] =
{
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};
#define MS_ADPCM_BLOCK_SIZE 256
#define MS_ADPCM_SAMPLES_PER_BLOCK ((256 - 7) * 2)
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] =
{
1, 3, 5, 7, 9, 11, 13, 15,
-1, -3, -5, -7, -9, -11, -13, -15
};
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);
#endif

View File

@ -212,10 +212,10 @@ static short get_driver(char *s,int audioflag)
"libvorbis",
"ffmpeg",
"libmad",
"ima4",
"msadpcm",
"liba52",
"g72x",
"adpcm",
"imaadpcm",
NULL
};
static char *videodrv[] = {

View File

@ -30,10 +30,10 @@
#define AFM_VORBIS 10
#define AFM_FFMPEG 11
#define AFM_MAD 12
#define AFM_IMA4 13
#define AFM_MSADPCM 13
#define AFM_A52 14
#define AFM_G72X 15
#define AFM_ADPCM 16
#define AFM_IMAADPCM 16
#define VFM_MPEG 1
#define VFM_VFW 2

View File

@ -278,13 +278,16 @@ case AFM_GSM:
// MS-GSM audio codec:
sh_audio->audio_out_minsize=4*320;
break;
case AFM_IMA4:
case AFM_ADPCM:
// IMA-ADPCM 4:1 audio codec:
case AFM_IMAADPCM:
sh_audio->audio_out_minsize=4096;
sh_audio->ds->ss_div=IMA_ADPCM_SAMPLES_PER_BLOCK;
sh_audio->ds->ss_mul=IMA_ADPCM_BLOCK_SIZE;
break;
case AFM_MSADPCM:
sh_audio->audio_out_minsize=4096;
sh_audio->ds->ss_div=MS_ADPCM_SAMPLES_PER_BLOCK;
sh_audio->ds->ss_mul=MS_ADPCM_BLOCK_SIZE;
break;
case AFM_MPEG:
// MPEG Audio:
sh_audio->audio_out_minsize=4608;
@ -503,15 +506,19 @@ case AFM_GSM: {
sh_audio->i_bps=65*(sh_audio->channels*sh_audio->samplerate)/320; // 1:10
break;
}
case AFM_ADPCM:
case AFM_IMA4: {
case AFM_IMAADPCM:
// IMA-ADPCM 4:1 audio codec:
sh_audio->channels=sh_audio->wf->nChannels;
sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
// decodes 34 byte -> 64 short
sh_audio->i_bps=IMA_ADPCM_BLOCK_SIZE*(sh_audio->channels*sh_audio->samplerate)/IMA_ADPCM_SAMPLES_PER_BLOCK; // 1:4
break;
}
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;
break;
case AFM_MPEG: {
// MPEG Audio:
dec_audio_sh=sh_audio; // save sh_audio for the callback:
@ -906,15 +913,22 @@ int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){
memcpy(buf,g72x_data.samples,len);
break;
}
case AFM_ADPCM:
case AFM_IMA4: // IMA-ADPCM 4:1 audio codec:
case AFM_IMAADPCM:
{ unsigned char ibuf[IMA_ADPCM_BLOCK_SIZE * 2]; // bytes / stereo frame
if (demux_read_data(sh_audio->ds, ibuf,
IMA_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels) !=
IMA_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels) !=
IMA_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels)
break; // EOF
len=2*ima_adpcm_decode_block((unsigned short*)buf,ibuf, sh_audio->wf->nChannels);
// len=2*ima4_decode_block((unsigned short*)buf,ibuf,2*IMA_ADPCM_SAMPLES_PER_BLOCK);
break;
}
case AFM_MSADPCM:
{ unsigned char ibuf[MS_ADPCM_BLOCK_SIZE * 2]; // bytes / stereo frame
if (demux_read_data(sh_audio->ds, ibuf,
MS_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels) !=
MS_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels)
break; // EOF
len=2*ms_adpcm_decode_block((unsigned short*)buf,ibuf, sh_audio->wf->nChannels);
break;
}
case AFM_AC3: // AC3 decoder

View File

@ -315,8 +315,13 @@ audiocodec imaadpcm
status working
format 0x11
format 0x34616d69 ; "ima4" (MOV files)
driver adpcm
dll "imaadpcm"
driver imaadpcm
audiocodec msadpcm
info "MS ADPCM"
status working
format 0x2
driver msadpcm
; =============== WINDOWS DLL's ==============
@ -792,12 +797,12 @@ audiocodec divx
dll "divxa32.acm"
cpuflags mmx
audiocodec msadpcm
info "MS ADPCM"
status working
format 0x2
driver acm
dll "msadp32.acm"
;audiocodec msadpcm
; info "MS ADPCM"
; status working
; format 0x2
; driver acm
; dll "msadp32.acm"
audiocodec mp3
info "MPEG layer-2, layer-3"
@ -948,14 +953,6 @@ audiocodec vorbis
; driver acm
; dll "vorbis.acm"
audiocodec ima4
info "IMA4:1"
status working
comment "MONO only"
format 0x34616d69 ; "ima4" (MOV files)
driver ima4
dll "ima4.c"
audiocodec vivoaudio
info "Vivo G.723/Siren Audio Codec"
status working