📄 mpc_decoder.c
字号:
mpc_decoder_read_bitstream_sv7(d);
break;
default:
return (mpc_uint32_t)(-1);
}
d->FrameWasValid = mpc_decoder_bits_read(d) - FrameBitCnt == d->FwdJumpInfo;
// synthesize signal
mpc_decoder_requantisierung(d, d->Max_Band);
//if ( d->EQ_activated && PluginSettings.EQbyMPC )
// perform_EQ ();
mpc_decoder_synthese_filter_float(d, buffer);
d->DecodedFrames++;
// cut off first MPC_DECODER_SYNTH_DELAY zero-samples
if (d->DecodedFrames == d->OverallFrames && d->StreamVersion >= 6) {
// reconstruct exact filelength
mpc_int32_t mod_block = mpc_decoder_bitstream_read(d, 11);
mpc_int32_t FilterDecay;
if (mod_block == 0) {
// Encoder bugfix
mod_block = 1152;
}
FilterDecay = (mod_block + MPC_DECODER_SYNTH_DELAY) % MPC_FRAME_LENGTH;
// additional FilterDecay samples are needed for decay of synthesis filter
if (MPC_DECODER_SYNTH_DELAY + mod_block >= MPC_FRAME_LENGTH) {
// **********************************************************************
// Rhoades 4/16/2002
// Commented out are blocks of code which cause gapless playback to fail.
// Temporary fix...
// **********************************************************************
if (!d->TrueGaplessPresent) {
mpc_decoder_reset_y(d);
}
else {
//if ( MPC_FRAME_LENGTH != d->LastValidSamples ) {
mpc_decoder_bitstream_read(d, 20);
mpc_decoder_read_bitstream_sv7(d);
mpc_decoder_requantisierung(d, d->Max_Band);
//FilterDecay = d->LastValidSamples;
//}
//else {
//FilterDecay = 0;
//}
}
mpc_decoder_synthese_filter_float(d, buffer + 2304);
output_frame_length = MPC_FRAME_LENGTH + FilterDecay;
}
else { // there are only FilterDecay samples needed for this frame
output_frame_length = FilterDecay;
}
}
if (d->samples_to_skip) {
if (output_frame_length < d->samples_to_skip) {
d->samples_to_skip -= output_frame_length;
output_frame_length = 0;
}
else {
output_frame_length -= d->samples_to_skip;
memmove(
buffer,
buffer + d->samples_to_skip * 2,
output_frame_length * 2 * sizeof (MPC_SAMPLE_FORMAT));
d->samples_to_skip = 0;
}
}
return output_frame_length;
}
mpc_uint32_t mpc_decoder_decode(
mpc_decoder *d,
MPC_SAMPLE_FORMAT *buffer,
mpc_uint32_t *vbr_update_acc,
mpc_uint32_t *vbr_update_bits)
{
for(;;)
{
//const mpc_int32_t MaxBrokenFrames = 0; // PluginSettings.MaxBrokenFrames
mpc_uint32_t RING = d->Zaehler;
mpc_int32_t vbr_ring = (RING << 5) + d->pos;
mpc_uint32_t valid_samples = mpc_decoder_decode_internal(d, buffer);
if (valid_samples == (mpc_uint32_t)(-1) ) {
return 0;
}
/**************** ERROR CONCEALMENT *****************/
if (d->FrameWasValid == 0 ) {
// error occurred in bitstream
return (mpc_uint32_t)(-1);
}
else {
if (vbr_update_acc && vbr_update_bits) {
(*vbr_update_acc) ++;
vbr_ring = (d->Zaehler << 5) + d->pos - vbr_ring;
if (vbr_ring < 0) {
vbr_ring += 524288;
}
(*vbr_update_bits) += vbr_ring;
}
}
mpc_decoder_update_buffer(d, RING);
if (valid_samples > 0) {
return valid_samples;
}
}
}
void
mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band)
{
mpc_int32_t Band;
mpc_int32_t n;
MPC_SAMPLE_FORMAT facL;
MPC_SAMPLE_FORMAT facR;
MPC_SAMPLE_FORMAT templ;
MPC_SAMPLE_FORMAT tempr;
MPC_SAMPLE_FORMAT* YL;
MPC_SAMPLE_FORMAT* YR;
mpc_int32_t* L;
mpc_int32_t* R;
#ifdef MPC_FIXED_POINT
#if MPC_FIXED_POINT_FRACTPART == 14
#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \
MPC_MULTIPLY_EX(CcVal, d->SCF[SCF_idx], d->SCF_shift[SCF_idx])
#else
#error FIXME, Cc table is in 18.14 format
#endif
#else
#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \
MPC_MULTIPLY(CcVal, d->SCF[SCF_idx])
#endif
// requantization and scaling of subband-samples
for ( Band = 0; Band <= Last_Band; Band++ ) { // setting pointers
YL = d->Y_L[0] + Band;
YR = d->Y_R[0] + Band;
L = d->Q[Band].L;
R = d->Q[Band].R;
/************************** MS-coded **************************/
if ( d->MS_Flag [Band] ) {
if ( d->Res_L [Band] ) {
if ( d->Res_R [Band] ) { // M!=0, S!=0
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]);
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]);
for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
*YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++));
*YR = templ - tempr;
}
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]);
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]);
for ( ; n < 24; n++, YL += 32, YR += 32 ) {
*YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++));
*YR = templ - tempr;
}
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]);
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]);
for ( ; n < 36; n++, YL += 32, YR += 32 ) {
*YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++));
*YR = templ - tempr;
}
} else { // M!=0, S==0
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]);
for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
*YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
}
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]);
for ( ; n < 24; n++, YL += 32, YR += 32 ) {
*YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
}
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]);
for ( ; n < 36; n++, YL += 32, YR += 32 ) {
*YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
}
}
} else {
if (d->Res_R[Band]) // M==0, S!=0
{
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]);
for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
*YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++)));
}
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]);
for ( ; n < 24; n++, YL += 32, YR += 32 ) {
*YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++)));
}
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]);
for ( ; n < 36; n++, YL += 32, YR += 32 ) {
*YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++)));
}
} else { // M==0, S==0
for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) {
*YR = *YL = 0;
}
}
}
}
/************************** LR-coded **************************/
else {
if ( d->Res_L [Band] ) {
if ( d->Res_R [Band] ) { // L!=0, R!=0
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]);
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]);
for (n = 0; n < 12; n++, YL += 32, YR += 32 ) {
*YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
*YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
}
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]);
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]);
for (; n < 24; n++, YL += 32, YR += 32 ) {
*YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
*YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
}
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]);
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]);
for (; n < 36; n++, YL += 32, YR += 32 ) {
*YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
*YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
}
} else { // L!=0, R==0
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]);
for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
*YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
*YR = 0;
}
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]);
for ( ; n < 24; n++, YL += 32, YR += 32 ) {
*YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
*YR = 0;
}
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]);
for ( ; n < 36; n++, YL += 32, YR += 32 ) {
*YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
*YR = 0;
}
}
}
else {
if ( d->Res_R [Band] ) { // L==0, R!=0
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]);
for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
*YL = 0;
*YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
}
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]);
for ( ; n < 24; n++, YL += 32, YR += 32 ) {
*YL = 0;
*YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
}
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]);
for ( ; n < 36; n++, YL += 32, YR += 32 ) {
*YL = 0;
*YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
}
} else { // L==0, R==0
for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) {
*YR = *YL = 0;
}
}
}
}
}
}
/****************************************** SV 6 ******************************************/
void
mpc_decoder_read_bitstream_sv6(mpc_decoder *d)
{
mpc_int32_t n,k;
mpc_int32_t Max_used_Band=0;
HuffmanTyp *Table;
const HuffmanTyp *x1;
const HuffmanTyp *x2;
mpc_int32_t *L;
mpc_int32_t *R;
mpc_int32_t *ResL = d->Res_L;
mpc_int32_t *ResR = d->Res_R;
/************************ HEADER **************************/
ResL = d->Res_L;
ResR = d->Res_R;
for (n=0; n <= d->Max_Band; ++n, ++ResL, ++ResR)
{
if (n<11) Table = d->Region_A;
else if (n>=11 && n<=22) Table = d->Region_B;
else /*if (n>=23)*/ Table = d->Region_C;
*ResL = d->Q_res[n][mpc_decoder_huffman_decode(d, Table)];
if (d->MS_used) {
d->MS_Flag[n] = mpc_decoder_bitstream_read(d, 1);
}
*ResR = d->Q_res[n][mpc_decoder_huffman_decode(d, Table)];
// only perform the following procedure up to the maximum non-zero subband
if (*ResL || *ResR) Max_used_Band = n;
}
/************************* SCFI-Bundle *****************************/
ResL = d->Res_L;
ResR = d->Res_R;
for (n=0; n<=Max_used_Band; ++n, ++ResL, ++ResR) {
if (*ResL) mpc_decoder_scfi_bundle_read(d, d->SCFI_Bundle, &(d->SCFI_L[n]), &(d->DSCF_Flag_L[n]));
if (*ResR) mpc_decoder_scfi_bundle_read(d, d->SCFI_Bundle, &(d->SCFI_R[n]), &(d->DSCF_Flag_R[n]));
}
/***************************** SCFI ********************************/
ResL = d->Res_L;
ResR = d->Res_R;
L = d->SCF_Index_L[0];
R = d->SCF_Index_R[0];
for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, L+=3, R+=3)
{
if (*ResL)
{
/*********** DSCF ************/
if (d->DSCF_Flag_L[n]==1)
{
L[2] = d->DSCF_Reference_L[n];
switch (d->SCFI_L[n])
{
case 3:
L[0] = L[2] + mpc_decoder_huffman_decode_fast(d, d->DSCF_Entropie);
L[1] = L[0];
L[2] = L[1];
break;
case 1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -