📄 adpcm.c
字号:
p_channel->i_sample1 = i_predictor; p_channel->i_idelta = ( i_adaptation_table[i_nibble] * p_channel->i_idelta ) / 256; if( p_channel->i_idelta < 16 ) { p_channel->i_idelta = 16; } return( i_predictor );}static void DecodeAdpcmMs( decoder_t *p_dec, int16_t *p_sample, uint8_t *p_buffer ){ decoder_sys_t *p_sys = p_dec->p_sys; adpcm_ms_channel_t channel[2]; int i_nibbles; int b_stereo; int i_block_predictor; b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0; GetByte( i_block_predictor ); CLAMP( i_block_predictor, 0, 6 ); channel[0].i_coeff1 = i_adaptation_coeff1[i_block_predictor]; channel[0].i_coeff2 = i_adaptation_coeff2[i_block_predictor]; if( b_stereo ) { GetByte( i_block_predictor ); CLAMP( i_block_predictor, 0, 6 ); channel[1].i_coeff1 = i_adaptation_coeff1[i_block_predictor]; channel[1].i_coeff2 = i_adaptation_coeff2[i_block_predictor]; } GetWord( channel[0].i_idelta ); if( b_stereo ) { GetWord( channel[1].i_idelta ); } GetWord( channel[0].i_sample1 ); if( b_stereo ) { GetWord( channel[1].i_sample1 ); } GetWord( channel[0].i_sample2 ); if( b_stereo ) { GetWord( channel[1].i_sample2 ); } if( b_stereo ) { *p_sample++ = channel[0].i_sample2; *p_sample++ = channel[1].i_sample2; *p_sample++ = channel[0].i_sample1; *p_sample++ = channel[1].i_sample1; } else { *p_sample++ = channel[0].i_sample2; *p_sample++ = channel[0].i_sample1; } for( i_nibbles = 2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels); i_nibbles > 0; i_nibbles -= 2, p_buffer++ ) { *p_sample++ = AdpcmMsExpandNibble( &channel[0], (*p_buffer) >> 4); *p_sample++ = AdpcmMsExpandNibble( &channel[b_stereo ? 1 : 0], (*p_buffer)&0x0f); }}/* * IMA-WAV */typedef struct adpcm_ima_wav_channel_s{ int i_predictor; int i_step_index;} adpcm_ima_wav_channel_t;static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t *p_channel, int i_nibble ){ int i_diff; i_diff = i_step_table[p_channel->i_step_index] >> 3; if( i_nibble&0x04 ) i_diff += i_step_table[p_channel->i_step_index]; if( i_nibble&0x02 ) i_diff += i_step_table[p_channel->i_step_index]>>1; if( i_nibble&0x01 ) i_diff += i_step_table[p_channel->i_step_index]>>2; if( i_nibble&0x08 ) p_channel->i_predictor -= i_diff; else p_channel->i_predictor += i_diff; CLAMP( p_channel->i_predictor, -32768, 32767 ); p_channel->i_step_index += i_index_table[i_nibble]; CLAMP( p_channel->i_step_index, 0, 88 ); return( p_channel->i_predictor );}static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample, uint8_t *p_buffer ){ decoder_sys_t *p_sys = p_dec->p_sys; adpcm_ima_wav_channel_t channel[2]; int i_nibbles; int b_stereo; b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0; GetWord( channel[0].i_predictor ); GetByte( channel[0].i_step_index ); CLAMP( channel[0].i_step_index, 0, 88 ); p_buffer++; if( b_stereo ) { GetWord( channel[1].i_predictor ); GetByte( channel[1].i_step_index ); CLAMP( channel[1].i_step_index, 0, 88 ); p_buffer++; } if( b_stereo ) { for( i_nibbles = 2 * (p_sys->i_block - 8); i_nibbles > 0; i_nibbles -= 16 ) { int i; for( i = 0; i < 4; i++ ) { p_sample[i * 4] = AdpcmImaWavExpandNibble(&channel[0],p_buffer[i]&0x0f); p_sample[i * 4 + 2] = AdpcmImaWavExpandNibble(&channel[0],p_buffer[i] >> 4); } p_buffer += 4; for( i = 0; i < 4; i++ ) { p_sample[i * 4 + 1] = AdpcmImaWavExpandNibble(&channel[1],p_buffer[i]&0x0f); p_sample[i * 4 + 3] = AdpcmImaWavExpandNibble(&channel[1],p_buffer[i] >> 4); } p_buffer += 4; p_sample += 16; } } else { for( i_nibbles = 2 * (p_sys->i_block - 4); i_nibbles > 0; i_nibbles -= 2, p_buffer++ ) { *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer)&0x0f ); *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer) >> 4 ); } }}/* * Ima4 in QT file */static void DecodeAdpcmImaQT( decoder_t *p_dec, int16_t *p_sample, uint8_t *p_buffer ){ adpcm_ima_wav_channel_t channel[2]; int i_nibbles; int i_ch; int i_step; i_step = p_dec->fmt_in.audio.i_channels; for( i_ch = 0; i_ch < p_dec->fmt_in.audio.i_channels; i_ch++ ) { /* load preambule */ channel[i_ch].i_predictor = (int16_t)((( ( p_buffer[0] << 1 )|( p_buffer[1] >> 7 ) ))<<7); channel[i_ch].i_step_index = p_buffer[1]&0x7f; CLAMP( channel[i_ch].i_step_index, 0, 88 ); p_buffer += 2; for( i_nibbles = 0; i_nibbles < 64; i_nibbles +=2 ) { *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer)&0x0f); p_sample += i_step; *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer >> 4)&0x0f); p_sample += i_step; p_buffer++; } /* Next channel */ p_sample += 1 - 64 * i_step; }}/* * Dk4 */static void DecodeAdpcmDk4( decoder_t *p_dec, int16_t *p_sample, uint8_t *p_buffer ){ decoder_sys_t *p_sys = p_dec->p_sys; adpcm_ima_wav_channel_t channel[2]; int i_nibbles; int b_stereo; b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0; GetWord( channel[0].i_predictor ); GetByte( channel[0].i_step_index ); CLAMP( channel[0].i_step_index, 0, 88 ); p_buffer++; if( b_stereo ) { GetWord( channel[1].i_predictor ); GetByte( channel[1].i_step_index ); CLAMP( channel[1].i_step_index, 0, 88 ); p_buffer++; } /* first output predictor */ *p_sample++ = channel[0].i_predictor; if( b_stereo ) { *p_sample++ = channel[1].i_predictor; } for( i_nibbles = 0; i_nibbles < p_sys->i_block - 4 * (b_stereo ? 2:1 ); i_nibbles++ ) { *p_sample++ = AdpcmImaWavExpandNibble( &channel[0], (*p_buffer) >> 4); *p_sample++ = AdpcmImaWavExpandNibble( &channel[b_stereo ? 1 : 0], (*p_buffer)&0x0f); p_buffer++; }}/* * Dk3 */static void DecodeAdpcmDk3( decoder_t *p_dec, int16_t *p_sample, uint8_t *p_buffer ){ decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *p_end = &p_buffer[p_sys->i_block]; adpcm_ima_wav_channel_t sum; adpcm_ima_wav_channel_t diff; int i_diff_value; p_buffer += 10; GetWord( sum.i_predictor ); GetWord( diff.i_predictor ); GetByte( sum.i_step_index ); GetByte( diff.i_step_index ); i_diff_value = diff.i_predictor; /* we process 6 nibbles at once */ while( p_buffer + 1 <= p_end ) { /* first 3 nibbles */ AdpcmImaWavExpandNibble( &sum, (*p_buffer)&0x0f); AdpcmImaWavExpandNibble( &diff, (*p_buffer) >> 4 ); i_diff_value = ( i_diff_value + diff.i_predictor ) / 2; *p_sample++ = sum.i_predictor + i_diff_value; *p_sample++ = sum.i_predictor - i_diff_value; p_buffer++; AdpcmImaWavExpandNibble( &sum, (*p_buffer)&0x0f); *p_sample++ = sum.i_predictor + i_diff_value; *p_sample++ = sum.i_predictor - i_diff_value; /* now last 3 nibbles */ AdpcmImaWavExpandNibble( &sum, (*p_buffer)>>4); p_buffer++; if( p_buffer < p_end ) { AdpcmImaWavExpandNibble( &diff, (*p_buffer)&0x0f ); i_diff_value = ( i_diff_value + diff.i_predictor ) / 2; *p_sample++ = sum.i_predictor + i_diff_value; *p_sample++ = sum.i_predictor - i_diff_value; AdpcmImaWavExpandNibble( &sum, (*p_buffer)>>4); p_buffer++; *p_sample++ = sum.i_predictor + i_diff_value; *p_sample++ = sum.i_predictor - i_diff_value; } }}/* * EA ADPCM */#define MAX_CHAN 5static void DecodeAdpcmEA( decoder_t *p_dec, int16_t *p_sample, uint8_t *p_buffer ){ static const uint32_t EATable[]= { 0x00000000, 0x000000F0, 0x000001CC, 0x00000188, 0x00000000, 0x00000000, 0xFFFFFF30, 0xFFFFFF24, 0x00000000, 0x00000001, 0x00000003, 0x00000004, 0x00000007, 0x00000008, 0x0000000A, 0x0000000B, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFC }; decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *p_end; unsigned i_channels, c; int16_t *prev, *cur; int32_t c1[MAX_CHAN], c2[MAX_CHAN]; int8_t d[MAX_CHAN]; i_channels = p_dec->fmt_in.audio.i_channels; p_end = &p_buffer[p_sys->i_block]; prev = (int16_t *)p_dec->fmt_in.p_extra; cur = prev + i_channels; for (c = 0; c < i_channels; c++) { uint8_t input; input = p_buffer[c]; c1[c] = EATable[input >> 4]; c2[c] = EATable[(input >> 4) + 4]; d[c] = (input & 0xf) + 8; } for( p_buffer += i_channels; p_buffer < p_end ; p_buffer += i_channels) { for (c = 0; c < i_channels; c++) { int32_t spl; spl = (p_buffer[c] >> 4) & 0xf; spl = (spl << 0x1c) >> d[c]; spl = (spl + cur[c] * c1[c] + prev[c] * c2[c] + 0x80) >> 8; CLAMP( spl, -32768, 32767 ); prev[c] = cur[c]; cur[c] = spl; *(p_sample++) = spl; } for (c = 0; c < i_channels; c++) { int32_t spl; spl = p_buffer[c] & 0xf; spl = (spl << 0x1c) >> d[c]; spl = (spl + cur[c] * c1[c] + prev[c] * c2[c] + 0x80) >> 8; CLAMP( spl, -32768, 32767 ); prev[c] = cur[c]; cur[c] = spl; *(p_sample++) = spl; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -