📄 mpeg3dec.c
字号:
while (sb--) { temp = ST_MULT((*xrp0 + *xrp1), sq2); *xrp1 = ST_MULT((*xrp0 - *xrp1), sq2); *xrp0++ = temp; xrp1++; } else { xrp0 += sb; xrp1 += sb; } for (; sfb < sbmax; sfb++) { // sbmax instead of 22 sb = band_l[sfb + 1] - band_l[sfb]; if (sfb < 21) { // keep previous ispos for last sfb ispos = sf->l[sfb]; is_illegal = (lsf) ? mps-> is_max_l[sfb] : 7; } if (ispos == is_illegal) { if (ms_stereo) while (sb--) { temp = ST_MULT((*xrp0 + *xrp1), sq2); *xrp1 = ST_MULT((*xrp0 - *xrp1), sq2); *xrp0++ = temp; xrp1++; } else { xrp0 += sb; xrp1 += sb; } } else { // ispos != is_illegal k0 = pow_iok0[ispos]; k1 = pow_iok1[ispos]; while (sb--) { temp = ST_MULT(*xrp0, k0); *xrp1 = ST_MULT(*xrp0, k1); *xrp0++ = temp; xrp1++; } } } } } else if ((mps->stereo) && ms_stereo) { // MS stereo xrp0 = xr; xrp1 = &xr[MPA_GRANULE_SIZE]; sb = mps->imdct_max[0]; if (sb < mps->imdct_max[1]) sb = mps->imdct_max[1]; sb = (INT16) (sb + 1) * MPA_SSLIMIT; if (sb > MPA_GRANULE_SIZE) sb = MPA_GRANULE_SIZE; while (sb--) { temp = ST_MULT((*xrp0 + *xrp1), sq2); *xrp1 = ST_MULT((*xrp0 - *xrp1), sq2); *xrp0++ = temp; xrp1++; } } else { //Normal stereo or mono -> nothing to do ! } return(MPEGDEC_ERR_NONE);}/****************************************************************************//* * Decode the stereo data -> mono of a granule * Return 0 if Ok */static int MPEG3_stereo_mono(MPA_STREAM *mps, MPEGAUD_FRACT_TYPE *xr, INT16 gr){ const INT16 *band_l = sfBandIndex_l[mps->header.ID][mps->header.sampling_frequency]; const INT16 *band_s = sfBandIndex_s[mps->header.ID][mps->header.sampling_frequency]; MPA_SCALE_FAC3 *sf = &mps->scale_fac3[1]; MPA_GRANULE_INFO *gi = &mps->side_info.ch[0].gr[gr]; BOOL ms_stereo = (mps->header.mode == MPA_MODE_JOINT_STEREO) && (mps->header.mode_extension & 0x2); BOOL i_stereo = (mps->header.mode == MPA_MODE_JOINT_STEREO) && (mps->header.mode_extension & 0x1); INT16 sfb; INT16 i, j, sb, sbmax; BOOL lsf = (mps->header.ID == MPA_ID_2);#define MAX_POS1 7#define MAX_POS2 32 const ST_TYPE *pow_iok0; MPEGAUD_FRACT_TYPE *xrp0, *xrp1;#ifdef MPEGAUD_INT ST_TYPE sq2 = 0.7071067812 * (1 << ST_BITS);#else REAL sq2 = 0.7071067812;#endif if (lsf) { if (gi->scalefac_compress & 1) pow_iok0 = pow_io0[1]; else pow_iok0 = pow_io0[0]; } else { pow_iok0 = tan_pos0; } if ((mps->stereo) && i_stereo) { ST_TYPE k0; INT16 sfb_top; INT16 max_sfb = 0; INT16 ispos; INT16 is_illegal; if (gi->window_switching_flag && (gi->block_type == 2)) { sbmax = mps->sfb_nul_s_top[0]; if (sbmax < mps->sfb_nul_s_top[1]) sbmax = mps->sfb_nul_s_top[1]; sbmax++; if (sbmax > 13) sbmax = 13; for (j = 0; j < 3; j++) { sfb_top = mps->sfb_nul_s[j][1]; if ((gi->mixed_block_flag) && (sfb_top < 3)) sfb_top = 3; // Normaly not !!! if (sfb_top > max_sfb) max_sfb = sfb_top; is_illegal = (lsf) ? mps->is_max_s[j][0] : 7; // Implicit: ispos == is_illegal here (not nul bands) ispos = is_illegal; for (sfb = 0; sfb < sfb_top; sfb++) { sb = band_s[sfb + 1] - band_s[sfb]; i = 3 * band_s[sfb] + j * sb; xrp0 = &xr[i]; xrp1 = &xr[MPA_GRANULE_SIZE + i]; if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } } while (sfb < sbmax) { // #9: sbmax instead of 13 sb = band_s[sfb + 1] - band_s[sfb]; i = 3 * band_s[sfb] + j * sb; xrp0 = &xr[i]; xrp1 = &xr[MPA_GRANULE_SIZE + i]; if (sfb < 12) { // keep previous ispos for // last sfb ispos = sf->s[j][sfb]; is_illegal = (lsf) ? mps-> is_max_s[j][sfb] : 7; } if (ispos == is_illegal) { if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } } else { // ispos != is_illegal k0 = pow_iok0[ispos]; while (sb--) { *xrp0 = ST_MULT(*xrp0, k0); xrp0++; } } sfb++; } } if (gi->mixed_block_flag) { INT16 sfb_max = (lsf) ? 6 : 8; xrp0 = xr; xrp1 = &xr[MPA_GRANULE_SIZE]; if (max_sfb <= 3) { // Top of nul bands in long blocks sfb = mps->sfb_nul_l[1]; // Begin of nul bands } else { sfb = sfb_max; // Begin of nul band not in long blocks } sb = band_l[sfb]; // Implicit: ispos == is_illegal here (not nul bands) if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } else { xrp0 += sb; xrp1 += sb; } for (; sfb < sfb_max; sfb++) { sb = band_l[sfb + 1] - band_l[sfb]; ispos = sf->l[sfb]; is_illegal = (lsf) ? mps-> is_max_l[sfb] : 7; if (ispos == is_illegal) { if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } else { xrp0 += sb; xrp1 += sb; } } else { // ispos != is_illegal k0 = pow_iok0[ispos]; xrp1 += sb; while (sb--) { *xrp0 = ST_MULT(*xrp0, k0); xrp0++; } } } } } else { // Long blocks, intensity stereo sbmax = mps->sfb_nul_l[0]; if (sbmax < mps->sfb_nul_l[1]) sbmax = mps->sfb_nul_l[1]; sbmax++; if (sbmax > 22) sbmax = 22; xrp0 = xr; xrp1 = &xr[MPA_GRANULE_SIZE]; sfb = mps->sfb_nul_l[1]; // Begin of nul bands sb = band_l[sfb]; is_illegal = (lsf) ? mps->is_max_l[0] : 7; // Implicit: ispos == is_illegal here (not nul bands) ispos = is_illegal; if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } else { xrp0 += sb; xrp1 += sb; } for (; sfb < sbmax; sfb++) { // #9: sbmax instead of 22 sb = band_l[sfb + 1] - band_l[sfb]; if (sfb < 21) { // keep previous ispos for last sfb ispos = sf->l[sfb]; is_illegal = (lsf) ? mps-> is_max_l[sfb] : 7; } if (ispos == is_illegal) { if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } else { xrp0 += sb; xrp1 += sb; } } else { // ispos != is_illegal k0 = pow_iok0[ispos]; xrp1 += sb; while (sb--) { *xrp0 = ST_MULT(*xrp0, k0); xrp0++; } } } } } else if ((mps->stereo) && ms_stereo) { // MS stereo xrp0 = xr; xrp1 = &xr[MPA_GRANULE_SIZE]; sb = mps->imdct_max[0]; if (sb < mps->imdct_max[1]) sb = mps->imdct_max[1]; sb = (INT16) (sb + 1) * MPA_SSLIMIT; if (sb > MPA_GRANULE_SIZE) sb = MPA_GRANULE_SIZE; while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } } else { //Normal stereo or mono -> nothing to do ! } return(MPEGDEC_ERR_NONE);}/****************************************************************************//* * Reorder a granule (block type 2) * Return 0 if Ok*/static int MPEG3_reorder(MPA_STREAM *mps, MPEGAUD_FRACT_TYPE *xr, MPEGAUD_FRACT_TYPE *ro, INT16 gr, INT16 ch){ MPA_GRANULE_INFO *gi = &mps->side_info.ch[ch].gr[gr]; register MPEGAUD_FRACT_TYPE *pro; register MPEGAUD_FRACT_TYPE *pxr0, *pxr1, *pxr2; const INT16 *sfbindex; INT16 sfb, freq; INT16 sfb_start, sfb_lines; // In ISO/IEC 11172-3 window_switching_flag is set if window type <> 0 // so, must be set if gi->block_type == 2 ! if (gi->window_switching_flag && (gi->block_type == 2)) { pro = ro; pxr2 = xr; sfbindex = sfBandIndex_s[mps->header.ID][mps->header.sampling_frequency]; sfb = 13; if (gi->mixed_block_flag) { // No Reorder for the 2 first subbands freq = (2 * MPA_SSLIMIT); while (freq--) *pro++ = *pxr2++; sfb -= 3; sfbindex += 3; } while (sfb--) { sfb_start = *sfbindex++; sfb_lines = *sfbindex - sfb_start; pxr0 = pxr2; pxr1 = pxr0 + sfb_lines; pxr2 = pxr1 + sfb_lines; freq = sfb_lines; while (freq--) { *pro++ = *pxr0++; *pro++ = *pxr1++; *pro++ = *pxr2++; } } } else { // Long blocks are in good order memcpy(ro, xr, MPA_GRANULE_SIZE * sizeof(MPEGAUD_FRACT_TYPE)); } return(MPEGDEC_ERR_NONE);}/****************************************************************************/#ifdef MPEGAUD_INT#define ALIAS_TYPE INT16#define ALIAS_BITS 15#define ALIAS_MULT(bu, cx) (((bu) * (cx))>>(ALIAS_BITS))#else#define ALIAS_TYPE REAL#define ALIAS_MULT(bu, cx) ((bu) * (cx))#endif/****************************************************************************//* * Apply the antialiasing buterfflies on a granule * Return 0 if Ok */static int MPEG3_antialias(MPA_STREAM *mps, MPEGAUD_FRACT_TYPE *xr, INT16 gr, INT16 ch, INT16 sb_max){ MPA_GRANULE_INFO *gi = &mps->side_info.ch[ch].gr[gr];#ifdef MPEGAUD_INT // Pre-calc tables for ALIAS_BITS=15 static const ALIAS_TYPE ca[8] = { -16858, -15457, -10268, -5960, -3099, -1342, -465, -121, }; static const ALIAS_TYPE cs[8] = { 28098, 28892, 31117, 32221, 32621, 32740, 32764, 32767, };#else static const ALIAS_TYPE ca[8] = { -0.514495730, -0.471731961, -0.313377440, -0.181913197, -0.094574191, -0.040965579, -0.014198568, -0.003699975, }; static const ALIAS_TYPE cs[8] = { 0.857492924, 0.881741941, 0.949628592, 0.983314574, 0.995517790, 0.999160528, 0.999899149, 0.999993145, };#endif INT16 sb, ss, i; MPEGAUD_FRACT_TYPE *bu, *bd; // upper and lower butterfly inputs const ALIAS_TYPE *csi, *cai; MPEGAUD_FRACT_TYPE obu; // temp butterfly output INT16 sblim; if (gi->window_switching_flag && (gi->block_type == 2)) { if (!gi->mixed_block_flag) return(MPEGDEC_ERR_NONE); sblim = 1; } else { sblim = sb_max - 1; } i = MPA_SSLIMIT - 1; for (sb = 0; sb < sblim; sb++) { bu = &xr[i]; bd = bu + 1; i += MPA_SSLIMIT; csi = cs; cai = ca; for (ss = 0; ss < 8; ss++) { obu = ALIAS_MULT(*bu, *csi) - ALIAS_MULT(*bd, *cai); *bd = ALIAS_MULT(*bd, *csi) + ALIAS_MULT(*bu, *cai); *bu = obu; csi++; cai++; bd++; bu--; } } return(MPEGDEC_ERR_NONE);}/****************************************************************************//* * Reset the decoder */int MPEG3_reset(MPA_STREAM *mps){ // Reset the huffman decoder return(HUFF_reset(mps->huffman));}/****************************************************************************//* * Decode the current frame * Return # of decoded samples */INT32 MPEG3_decode_frame(MPA_STREAM *mps){ INT16 max_gr, gr, ch; int slots; BITSTREAM *bs = mps->bitstream; HUFFMAN *h = mps->huffman; register char byte; int status; int start, seek_pos; INT16 pcm_offset[2]; INT16 sb_max; INT16 channels = (mps->force_mono) ? 1 : mps->channels; int err;#define ERR_CHECK(i) \ err = i;\ if (err) { \ printf("Error %d in decode_frame\n", i); \ return(err); \ } ERR_CHECK(MPEG3_decode_side_info(mps)); status = HUFF_set_start(h, mps->side_info.main_data_begin); slots = MPEG3_main_data_slots(mps); { // 1440 is the max theorical value for layer III char buffer[1440]; int i; while (slots > 0) { i = (slots > 1440) ? 1440 : slots; BSTR_read_bytes(bs, slots, buffer);#ifdef USE_RC4 if (mps->header.private_bit) { if (mps->keyp == NULL) return(-1); RC4(mps->keyp, slots, buffer, buffer); }#endif HUFF_fill_bytes(h, slots, buffer); slots -= i; } } if (BSTR_end(bs)) return(MPEGDEC_ERR_EOF); if (status) { // Can't decode this frame (not enough data) // printf("Can't decode this frame (not enough data)\n"); return(0); } max_gr = (mps->header.ID == MPA_ID_1) ? 2 : 1; pcm_offset[0] = pcm_offset[1] = 0; seek_pos = HUFF_pos(h); for (gr = 0; gr < max_gr; gr++) { for (ch = 0; ch < mps->channels; ch++) { // WE HAVE TO SEEK IN HUFFMAN DATA // use part2_3_length of each granule HUFF_seek(h, seek_pos); start = HUFF_pos(h); // calculate next seek position with actual part2_3_length seek_pos += mps->side_info.ch[ch].gr[gr].part2_3_length; if (mps->header.ID == MPA_ID_1) { ERR_CHECK(MPEG3_decode_scale1(mps, gr, ch)); } else { ERR_CHECK(MPEG3_decode_scale2(mps, gr, ch)); } ERR_CHECK(MPEG3_huffman_decode (mps, mps->is, gr, ch, start)); MPEG3_get_nul_pos(mps, mps->is, gr, ch); ERR_CHECK(MPEG3_dequantize_samples (mps, mps->is, &mps->xr[ch][0], gr, ch)); } if (channels == 2) { ERR_CHECK(MPEG3_stereo(mps, &mps->xr[0][0], gr)); } else if ((channels == 1) && (mps->channels == 2)) { ERR_CHECK(MPEG3_stereo_mono(mps, &mps->xr[0][0], gr)); } for (ch = 0; ch < channels; ch++) { INT16 ss; MPEGAUD_FRACT_TYPE *sub; INT16 *pcm; sb_max = mps->imdct_max[ch]; pcm = mps->pcm[ch]; if (mps->side_info.ch[ch].gr[gr].window_switching_flag && (mps->side_info.ch[ch].gr[gr].block_type == 2)) { ERR_CHECK(MPEG3_reorder(mps, &mps->xr[ch][0], &mps->lr[0][0], gr, ch)); ERR_CHECK(MPEG3_antialias(mps, &mps->lr[0][0], gr, ch, sb_max)); sub = &mps->lr[1][0]; MPEGIMDCT_hybrid(mps->mpegimdct, &mps->lr[0][0], sub, mps->side_info.ch[ch].gr[gr].block_type, (BOOL) mps->side_info.ch[ch].gr[gr].mixed_block_flag, ch, sb_max); } else { ERR_CHECK(MPEG3_antialias(mps, &mps->xr[ch][0], gr, ch, sb_max)); sub = &mps->lr[1][0]; MPEGIMDCT_hybrid(mps->mpegimdct, &mps->xr[ch][0], sub, mps->side_info.ch[ch].gr[gr].block_type, (BOOL) mps->side_info.ch[ch].gr[gr].mixed_block_flag, ch, sb_max); } for (ss = 0; ss < MPA_SSLIMIT; ss++) { pcm_offset[ch] += MPEGSUB_synthesis( mps->mpegsub, sub, ch, &pcm[pcm_offset[ch]]); sub += MPA_SBLIMIT; } } } HUFF_seek(h, seek_pos); return((INT32) pcm_offset[0]);}/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -