📄 adpcm.c
字号:
if(i == froze + FREEZE_INTERVAL) { p = &paths[nodes[0]->path]; for(k=i; k>froze; k--) { dst[k] = p->nibble; p = &paths[p->prev]; } froze = i; pathn = 0; // other nodes might use paths that don't coincide with the frozen one. // checking which nodes do so is too slow, so just kill them all. // this also slightly improves quality, but I don't know why. memset(nodes+1, 0, (frontier-1)*sizeof(TrellisNode*)); } } p = &paths[nodes[0]->path]; for(i=n-1; i>froze; i--) { dst[i] = p->nibble; p = &paths[p->prev]; } c->predictor = nodes[0]->sample1; c->sample1 = nodes[0]->sample1; c->sample2 = nodes[0]->sample2; c->step_index = nodes[0]->step; c->step = nodes[0]->step; c->idelta = nodes[0]->step;}static int adpcm_encode_frame(AVCodecContext *avctx, unsigned char *frame, int buf_size, void *data){ int n, i, st; short *samples; unsigned char *dst; ADPCMContext *c = avctx->priv_data; dst = frame; samples = (short *)data; st= avctx->channels == 2;/* n = (BLKSIZE - 4 * avctx->channels) / (2 * 8 * avctx->channels); */ switch(avctx->codec->id) { case CODEC_ID_ADPCM_IMA_WAV: n = avctx->frame_size / 8; c->status[0].prev_sample = (signed short)samples[0]; /* XXX *//* c->status[0].step_index = 0; *//* XXX: not sure how to init the state machine */ bytestream_put_le16(&dst, c->status[0].prev_sample); *dst++ = (unsigned char)c->status[0].step_index; *dst++ = 0; /* unknown */ samples++; if (avctx->channels == 2) { c->status[1].prev_sample = (signed short)samples[0];/* c->status[1].step_index = 0; */ bytestream_put_le16(&dst, c->status[1].prev_sample); *dst++ = (unsigned char)c->status[1].step_index; *dst++ = 0; samples++; } /* stereo: 4 bytes (8 samples) for left, 4 bytes for right, 4 bytes left, ... */ if(avctx->trellis > 0) { uint8_t buf[2][n*8]; adpcm_compress_trellis(avctx, samples, buf[0], &c->status[0], n*8); if(avctx->channels == 2) adpcm_compress_trellis(avctx, samples+1, buf[1], &c->status[1], n*8); for(i=0; i<n; i++) { *dst++ = buf[0][8*i+0] | (buf[0][8*i+1] << 4); *dst++ = buf[0][8*i+2] | (buf[0][8*i+3] << 4); *dst++ = buf[0][8*i+4] | (buf[0][8*i+5] << 4); *dst++ = buf[0][8*i+6] | (buf[0][8*i+7] << 4); if (avctx->channels == 2) { *dst++ = buf[1][8*i+0] | (buf[1][8*i+1] << 4); *dst++ = buf[1][8*i+2] | (buf[1][8*i+3] << 4); *dst++ = buf[1][8*i+4] | (buf[1][8*i+5] << 4); *dst++ = buf[1][8*i+6] | (buf[1][8*i+7] << 4); } } } else for (; n>0; n--) { *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]); *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels]) << 4; dst++; *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]); *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4; dst++; *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]); *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4; dst++; *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]); *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4; dst++; /* right channel */ if (avctx->channels == 2) { *dst = adpcm_ima_compress_sample(&c->status[1], samples[1]); *dst |= adpcm_ima_compress_sample(&c->status[1], samples[3]) << 4; dst++; *dst = adpcm_ima_compress_sample(&c->status[1], samples[5]); *dst |= adpcm_ima_compress_sample(&c->status[1], samples[7]) << 4; dst++; *dst = adpcm_ima_compress_sample(&c->status[1], samples[9]); *dst |= adpcm_ima_compress_sample(&c->status[1], samples[11]) << 4; dst++; *dst = adpcm_ima_compress_sample(&c->status[1], samples[13]); *dst |= adpcm_ima_compress_sample(&c->status[1], samples[15]) << 4; dst++; } samples += 8 * avctx->channels; } break; case CODEC_ID_ADPCM_SWF: { int i; PutBitContext pb; init_put_bits(&pb, dst, buf_size*8); n = avctx->frame_size-1; //Store AdpcmCodeSize put_bits(&pb, 2, 2); //Set 4bits flash adpcm format //Init the encoder state for(i=0; i<avctx->channels; i++){ c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63); // clip step so it fits 6 bits put_bits(&pb, 16, samples[i] & 0xFFFF); put_bits(&pb, 6, c->status[i].step_index); c->status[i].prev_sample = (signed short)samples[i]; } if(avctx->trellis > 0) { uint8_t buf[2][n]; adpcm_compress_trellis(avctx, samples+2, buf[0], &c->status[0], n); if (avctx->channels == 2) adpcm_compress_trellis(avctx, samples+3, buf[1], &c->status[1], n); for(i=0; i<n; i++) { put_bits(&pb, 4, buf[0][i]); if (avctx->channels == 2) put_bits(&pb, 4, buf[1][i]); } } else { for (i=1; i<avctx->frame_size; i++) { put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels*i])); if (avctx->channels == 2) put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1], samples[2*i+1])); } } flush_put_bits(&pb); dst += put_bits_count(&pb)>>3; break; } case CODEC_ID_ADPCM_MS: for(i=0; i<avctx->channels; i++){ int predictor=0; *dst++ = predictor; c->status[i].coeff1 = AdaptCoeff1[predictor]; c->status[i].coeff2 = AdaptCoeff2[predictor]; } for(i=0; i<avctx->channels; i++){ if (c->status[i].idelta < 16) c->status[i].idelta = 16; bytestream_put_le16(&dst, c->status[i].idelta); } for(i=0; i<avctx->channels; i++){ c->status[i].sample1= *samples++; bytestream_put_le16(&dst, c->status[i].sample1); } for(i=0; i<avctx->channels; i++){ c->status[i].sample2= *samples++; bytestream_put_le16(&dst, c->status[i].sample2); } if(avctx->trellis > 0) { int n = avctx->block_align - 7*avctx->channels; uint8_t buf[2][n]; if(avctx->channels == 1) { n *= 2; adpcm_compress_trellis(avctx, samples, buf[0], &c->status[0], n); for(i=0; i<n; i+=2) *dst++ = (buf[0][i] << 4) | buf[0][i+1]; } else { adpcm_compress_trellis(avctx, samples, buf[0], &c->status[0], n); adpcm_compress_trellis(avctx, samples+1, buf[1], &c->status[1], n); for(i=0; i<n; i++) *dst++ = (buf[0][i] << 4) | buf[1][i]; } } else for(i=7*avctx->channels; i<avctx->block_align; i++) { int nibble; nibble = adpcm_ms_compress_sample(&c->status[ 0], *samples++)<<4; nibble|= adpcm_ms_compress_sample(&c->status[st], *samples++); *dst++ = nibble; } break; case CODEC_ID_ADPCM_YAMAHA: n = avctx->frame_size / 2; if(avctx->trellis > 0) { uint8_t buf[2][n*2]; n *= 2; if(avctx->channels == 1) { adpcm_compress_trellis(avctx, samples, buf[0], &c->status[0], n); for(i=0; i<n; i+=2) *dst++ = buf[0][i] | (buf[0][i+1] << 4); } else { adpcm_compress_trellis(avctx, samples, buf[0], &c->status[0], n); adpcm_compress_trellis(avctx, samples+1, buf[1], &c->status[1], n); for(i=0; i<n; i++) *dst++ = buf[0][i] | (buf[1][i] << 4); } } else for (; n>0; n--) { for(i = 0; i < avctx->channels; i++) { int nibble; nibble = adpcm_yamaha_compress_sample(&c->status[i], samples[i]); nibble |= adpcm_yamaha_compress_sample(&c->status[i], samples[i+avctx->channels]) << 4; *dst++ = nibble; } samples += 2 * avctx->channels; } break; default: return -1; } return dst - frame;}#endif //CONFIG_ENCODERSstatic int adpcm_decode_init(AVCodecContext * avctx){ ADPCMContext *c = avctx->priv_data; unsigned int max_channels = 2; switch(avctx->codec->id) { case CODEC_ID_ADPCM_EA_R1: case CODEC_ID_ADPCM_EA_R2: case CODEC_ID_ADPCM_EA_R3: max_channels = 6; break; } if(avctx->channels > max_channels){ return -1; } switch(avctx->codec->id) { case CODEC_ID_ADPCM_CT: c->status[0].step = c->status[1].step = 511; break; case CODEC_ID_ADPCM_IMA_WS: if (avctx->extradata && avctx->extradata_size == 2 * 4) { c->status[0].predictor = AV_RL32(avctx->extradata); c->status[1].predictor = AV_RL32(avctx->extradata + 4); } break; default: break; } return 0;}static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble, int shift){ int step_index; int predictor; int sign, delta, diff, step; step = step_table[c->step_index]; step_index = c->step_index + index_table[(unsigned)nibble]; if (step_index < 0) step_index = 0; else if (step_index > 88) step_index = 88; sign = nibble & 8; delta = nibble & 7; /* perform direct multiplication instead of series of jumps proposed by * the reference ADPCM implementation since modern CPUs can do the mults * quickly enough */ diff = ((2 * delta + 1) * step) >> shift; predictor = c->predictor; if (sign) predictor -= diff; else predictor += diff; c->predictor = av_clip_int16(predictor); c->step_index = step_index; return (short)c->predictor;}static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble){ int predictor; predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256; predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta; c->sample2 = c->sample1; c->sample1 = av_clip_int16(predictor); c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8; if (c->idelta < 16) c->idelta = 16; return c->sample1;}static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble){ int sign, delta, diff; int new_step; sign = nibble & 8; delta = nibble & 7; /* perform direct multiplication instead of series of jumps proposed by * the reference ADPCM implementation since modern CPUs can do the mults * quickly enough */ diff = ((2 * delta + 1) * c->step) >> 3; /* predictor update is not so trivial: predictor is multiplied on 254/256 before updating */ c->predictor = ((c->predictor * 254) >> 8) + (sign ? -diff : diff); c->predictor = av_clip_int16(c->predictor); /* calculate new step and clamp it to range 511..32767 */ new_step = (ct_adpcm_table[nibble & 7] * c->step) >> 8; c->step = av_clip(new_step, 511, 32767); return (short)c->predictor;}static inline short adpcm_sbpro_expand_nibble(ADPCMChannelStatus *c, char nibble, int size, int shift){ int sign, delta, diff; sign = nibble & (1<<(size-1)); delta = nibble & ((1<<(size-1))-1); diff = delta << (7 + c->step + shift); /* clamp result */ c->predictor = av_clip(c->predictor + (sign ? -diff : diff), -16384,16256); /* calculate new step */ if (delta >= (2*size - 3) && c->step < 3) c->step++; else if (delta == 0 && c->step > 0) c->step--; return (short) c->predictor;}static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned char nibble){ if(!c->step) { c->predictor = 0; c->step = 127; } c->predictor += (c->step * yamaha_difflookup[nibble]) / 8; c->predictor = av_clip_int16(c->predictor); c->step = (c->step * yamaha_indexscale[nibble]) >> 8; c->step = av_clip(c->step, 127, 24567); return c->predictor;}static void xa_decode(short *out, const unsigned char *in, ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc){ int i, j; int shift,filter,f0,f1; int s_1,s_2; int d,s,t; for(i=0;i<4;i++) { shift = 12 - (in[4+i*2] & 15); filter = in[4+i*2] >> 4; f0 = xa_adpcm_table[filter][0]; f1 = xa_adpcm_table[filter][1]; s_1 = left->sample1; s_2 = left->sample2; for(j=0;j<28;j++) { d = in[16+i+j*4]; t = (signed char)(d<<4)>>4; s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6); s_2 = s_1; s_1 = av_clip_int16(s); *out = s_1; out += inc; } if (inc==2) { /* stereo */ left->sample1 = s_1; left->sample2 = s_2; s_1 = right->sample1; s_2 = right->sample2; out = out + 1 - 28*2; } shift = 12 - (in[5+i*2] & 15); filter = in[5+i*2] >> 4; f0 = xa_adpcm_table[filter][0]; f1 = xa_adpcm_table[filter][1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -