📄 adpcm.c
字号:
src += m<<st; break; case CODEC_ID_ADPCM_MS: if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; n = buf_size - 7 * avctx->channels; if (n < 0) return -1; block_predictor[0] = clip(*src++, 0, 7); block_predictor[1] = 0; if (st) block_predictor[1] = clip(*src++, 0, 7); c->status[0].idelta = (int16_t)((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); src+=2; if (st){ c->status[1].idelta = (int16_t)((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); src+=2; } c->status[0].coeff1 = AdaptCoeff1[block_predictor[0]]; c->status[0].coeff2 = AdaptCoeff2[block_predictor[0]]; c->status[1].coeff1 = AdaptCoeff1[block_predictor[1]]; c->status[1].coeff2 = AdaptCoeff2[block_predictor[1]]; c->status[0].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); src+=2; if (st) c->status[1].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); if (st) src+=2; c->status[0].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); src+=2; if (st) c->status[1].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); if (st) src+=2; *samples++ = c->status[0].sample1; if (st) *samples++ = c->status[1].sample1; *samples++ = c->status[0].sample2; if (st) *samples++ = c->status[1].sample2; for(;n>0;n--) { *samples++ = adpcm_ms_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F); *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F); src ++; } break; case CODEC_ID_ADPCM_IMA_DK4: if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; c->status[0].predictor = (int16_t)(src[0] | (src[1] << 8)); c->status[0].step_index = src[2]; src += 4; *samples++ = c->status[0].predictor; if (st) { c->status[1].predictor = (int16_t)(src[0] | (src[1] << 8)); c->status[1].step_index = src[2]; src += 4; *samples++ = c->status[1].predictor; } while (src < buf + buf_size) { /* take care of the top nibble (always left or mono channel) */ *samples++ = adpcm_ima_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F, 3); /* take care of the bottom nibble, which is right sample for * stereo, or another mono sample */ if (st) *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[0] & 0x0F, 3); else *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] & 0x0F, 3); src++; } break; case CODEC_ID_ADPCM_IMA_DK3: if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; c->status[0].predictor = (int16_t)(src[10] | (src[11] << 8)); c->status[1].predictor = (int16_t)(src[12] | (src[13] << 8)); c->status[0].step_index = src[14]; c->status[1].step_index = src[15]; /* sign extend the predictors */ src += 16; diff_channel = c->status[1].predictor; /* the DK3_GET_NEXT_NIBBLE macro issues the break statement when * the buffer is consumed */ while (1) { /* for this algorithm, c->status[0] is the sum channel and * c->status[1] is the diff channel */ /* process the first predictor of the sum channel */ DK3_GET_NEXT_NIBBLE(); adpcm_ima_expand_nibble(&c->status[0], nibble, 3); /* process the diff channel predictor */ DK3_GET_NEXT_NIBBLE(); adpcm_ima_expand_nibble(&c->status[1], nibble, 3); /* process the first pair of stereo PCM samples */ diff_channel = (diff_channel + c->status[1].predictor) / 2; *samples++ = c->status[0].predictor + c->status[1].predictor; *samples++ = c->status[0].predictor - c->status[1].predictor; /* process the second predictor of the sum channel */ DK3_GET_NEXT_NIBBLE(); adpcm_ima_expand_nibble(&c->status[0], nibble, 3); /* process the second pair of stereo PCM samples */ diff_channel = (diff_channel + c->status[1].predictor) / 2; *samples++ = c->status[0].predictor + c->status[1].predictor; *samples++ = c->status[0].predictor - c->status[1].predictor; } break; case CODEC_ID_ADPCM_IMA_WS: /* no per-block initialization; just start decoding the data */ while (src < buf + buf_size) { if (st) { *samples++ = adpcm_ima_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F, 3); *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[0] & 0x0F, 3); } else { *samples++ = adpcm_ima_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F, 3); *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] & 0x0F, 3); } src++; } break; case CODEC_ID_ADPCM_XA: c->status[0].sample1 = c->status[0].sample2 = c->status[1].sample1 = c->status[1].sample2 = 0; while (buf_size >= 128) { xa_decode(samples, src, &c->status[0], &c->status[1], avctx->channels); src += 128; samples += 28 * 8; buf_size -= 128; } break; case CODEC_ID_ADPCM_EA: samples_in_chunk = LE_32(src); if (samples_in_chunk >= ((buf_size - 12) * 2)) { src += buf_size; break; } src += 4; current_left_sample = (int16_t)LE_16(src); src += 2; previous_left_sample = (int16_t)LE_16(src); src += 2; current_right_sample = (int16_t)LE_16(src); src += 2; previous_right_sample = (int16_t)LE_16(src); src += 2; for (count1 = 0; count1 < samples_in_chunk/28;count1++) { coeff1l = ea_adpcm_table[(*src >> 4) & 0x0F]; coeff2l = ea_adpcm_table[((*src >> 4) & 0x0F) + 4]; coeff1r = ea_adpcm_table[*src & 0x0F]; coeff2r = ea_adpcm_table[(*src & 0x0F) + 4]; src++; shift_left = ((*src >> 4) & 0x0F) + 8; shift_right = (*src & 0x0F) + 8; src++; for (count2 = 0; count2 < 28; count2++) { next_left_sample = (((*src & 0xF0) << 24) >> shift_left); next_right_sample = (((*src & 0x0F) << 28) >> shift_right); src++; next_left_sample = (next_left_sample + (current_left_sample * coeff1l) + (previous_left_sample * coeff2l) + 0x80) >> 8; next_right_sample = (next_right_sample + (current_right_sample * coeff1r) + (previous_right_sample * coeff2r) + 0x80) >> 8; CLAMP_TO_SHORT(next_left_sample); CLAMP_TO_SHORT(next_right_sample); previous_left_sample = current_left_sample; current_left_sample = next_left_sample; previous_right_sample = current_right_sample; current_right_sample = next_right_sample; *samples++ = (unsigned short)current_left_sample; *samples++ = (unsigned short)current_right_sample; } } break; case CODEC_ID_ADPCM_IMA_SMJPEG: c->status[0].predictor = *src; src += 2; c->status[0].step_index = *src++; src++; /* skip another byte before getting to the meat */ while (src < buf + buf_size) { *samples++ = adpcm_ima_expand_nibble(&c->status[0], *src & 0x0F, 3); *samples++ = adpcm_ima_expand_nibble(&c->status[0], (*src >> 4) & 0x0F, 3); src++; } break; case CODEC_ID_ADPCM_CT: while (src < buf + buf_size) { if (st) { *samples++ = adpcm_ct_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F); *samples++ = adpcm_ct_expand_nibble(&c->status[1], src[0] & 0x0F); } else { *samples++ = adpcm_ct_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F); *samples++ = adpcm_ct_expand_nibble(&c->status[0], src[0] & 0x0F); } src++; } break; case CODEC_ID_ADPCM_SWF: { GetBitContext gb; const int *table; int k0, signmask; int size = buf_size*8; init_get_bits(&gb, buf, size); // first frame, read bits & inital values if (!c->nb_bits) { c->nb_bits = get_bits(&gb, 2)+2;// av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", c->nb_bits); } table = swf_index_tables[c->nb_bits-2]; k0 = 1 << (c->nb_bits-2); signmask = 1 << (c->nb_bits-1); while (get_bits_count(&gb) <= size) { int i; c->nb_samples++; // wrap around at every 4096 samples... if ((c->nb_samples & 0xfff) == 1) { for (i = 0; i <= st; i++) { *samples++ = c->status[i].predictor = get_sbits(&gb, 16); c->status[i].step_index = get_bits(&gb, 6); } } // similar to IMA adpcm for (i = 0; i <= st; i++) { int delta = get_bits(&gb, c->nb_bits); int step = step_table[c->status[i].step_index]; long vpdiff = 0; // vpdiff = (delta+0.5)*step/4 int k = k0; do { if (delta & k) vpdiff += step; step >>= 1; k >>= 1; } while(k); vpdiff += step; if (delta & signmask) c->status[i].predictor -= vpdiff; else c->status[i].predictor += vpdiff; c->status[i].step_index += table[delta & (~signmask)]; c->status[i].step_index = clip(c->status[i].step_index, 0, 88); c->status[i].predictor = clip(c->status[i].predictor, -32768, 32767); *samples++ = c->status[i].predictor; } } // src += get_bits_count(&gb)*8; src += size; break; } case CODEC_ID_ADPCM_YAMAHA: while (src < buf + buf_size) { if (st) { *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], src[0] & 0x0F); *samples++ = adpcm_yamaha_expand_nibble(&c->status[1], (src[0] >> 4) & 0x0F); } else { *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], src[0] & 0x0F); *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F); } src++; } break; default: return -1; } *data_size = (uint8_t *)samples - (uint8_t *)data; return src - buf;}#ifdef CONFIG_ENCODERS#define ADPCM_ENCODER(id,name) \AVCodec name ## _encoder = { \ #name, \ CODEC_TYPE_AUDIO, \ id, \ sizeof(ADPCMContext), \ adpcm_encode_init, \ adpcm_encode_frame, \ adpcm_encode_close, \ NULL, \};#else#define ADPCM_ENCODER(id,name)#endif#ifdef CONFIG_DECODERS#define ADPCM_DECODER(id,name) \AVCodec name ## _decoder = { \ #name, \ CODEC_TYPE_AUDIO, \ id, \ sizeof(ADPCMContext), \ adpcm_decode_init, \ NULL, \ NULL, \ adpcm_decode_frame, \};#else#define ADPCM_DECODER(id,name)#endif#define ADPCM_CODEC(id, name) \ADPCM_ENCODER(id,name) ADPCM_DECODER(id,name)ADPCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt);ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav);ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3);ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4);ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);ADPCM_CODEC(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg);ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);ADPCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa);ADPCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx);ADPCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea);ADPCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct);ADPCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf);ADPCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha);#undef ADPCM_CODEC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -