⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adpcm.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -