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

📄 mp3dec_layer3_fp.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 3 页
字号:

    if (!intensity) {
        ptrL = &((*smpl_xr)[0][0]);
        ptrR = &((*smpl_xr)[1][0]);

        for (i = 0; i < nz; i++) {
            li = mult * (ptrL[0] + ptrR[0]);
            ri = mult * (ptrL[0] - ptrR[0]);
            ptrL[0] = li;
            ptrR[0] = ri;
            ptrL++; ptrR++;
        }
        return 1;
    }

    scalefPtr = isPos;
    if (si_blockType[gr][1] == 2) {
        if (si_mixedBlock[gr][1]) {
            numSfbLong = sfBandNum[header->id][2][0];
            numSfbShort = sfBandNum[header->id][2][1];
            width = sfBandWidths[header->id][header->samplingFreq].m;
            for (sfb = 0; sfb < numSfbLong; sfb++) {
                *scalefPtr = ScaleFactors[1].l[sfb];
                scalefPtr++;
            }
            for (sfb = 3; sfb < 12; sfb++) {
                for (i = 0; i < 3; i++) {
                    *scalefPtr = ScaleFactors[1].s[i][sfb];
                    scalefPtr++;
                }
            }
        } else {
            numSfbLong = sfBandNum[header->id][1][0];
            numSfbShort = sfBandNum[header->id][1][1];
            width = sfBandWidths[header->id][header->samplingFreq].s;
            for (sfb = 0; sfb < 12; sfb++) {
                for (i = 0; i < 3; i++) {
                    *scalefPtr = ScaleFactors[1].s[i][sfb];
                    scalefPtr++;
                }
            }
        }
        for (i = 0; i < 3; i++) {
            *scalefPtr = 0;
            scalefPtr++;
        }
    } else {
        numSfbLong = sfBandNum[header->id][0][0];
        numSfbShort = sfBandNum[header->id][0][1];
        width = sfBandWidths[header->id][header->samplingFreq].l;
        for (sfb = 0; sfb < 21; sfb++) {
            *scalefPtr = ScaleFactors[1].l[sfb];
            scalefPtr++;
        }
        *scalefPtr = 0;
    }

    if (header->id) {
        illegal = 7;
    } else {
        illegal = 100;
    }

    numSfb = numSfbLong + numSfbShort * 3;
    widthPtr = width + numSfb - 1;
    ptrR = &((*smpl_xr)[1][576]);

    found[0] = found[1] = found[2] = 0;
    sfbStart = numSfb;
    sfbEnd = numSfbLong;
    numBlock = 3;
    for (j = 0; j < 2; j++) {
        for (sfb = sfbStart - 1; sfb >= sfbEnd; sfb-=numBlock) {
            for (i = 0; i < numBlock; i++) {
                Ipp32f tmp;
                w = *widthPtr;
                widthPtr--;
                ptrR -= w;
                if (found[i] == 0) {
                    ippsDotProd_32f(ptrR, ptrR, w, &tmp);
                    if (tmp > 0) {
                        isPos[sfb - i] = illegal;
                        found[i] = 1;
                        if (numSfbLong && sfb == 20) f20 = 1;
                        if (numSfbShort && sfb >= 33 && sfb <= 35) f11 = 1;
                    }
                } else {
                    isPos[sfb - i] = illegal;
                }
            }
        }
        found[0] += (found[1] + found[2]);
        sfbStart = sfbEnd;
        sfbEnd = 0;
        numBlock = 1;
    }

    if (header->id == 0) {
        Ipp8u *ptr = mp3dec_nr_of_sfb[blocknumber][blocktypenumber];

        scalefPtr = isPos;

        for (i = 0; i < 4; i++) {
            Ipp32s num = ptr[i];
            Ipp32s len = s_len[i];

            if (len) {
                Ipp32s tmp = (1 << len) - 1;
                for (sfb = 0; sfb < num; sfb++) {
                    if (*scalefPtr == tmp) {
                        *scalefPtr = illegal;
                    }
                    scalefPtr++;
                }
            } else {
                scalefPtr += num;
            }
        }
    }

    if (si_blockType[gr][1] == 2) {
      if (f11) {
        isPos[numSfb - 1] = isPos[numSfb - 2] = isPos[numSfb - 3] =  0;
      } else {
        isPos[numSfb - 1] =  isPos[numSfb - 4];
        isPos[numSfb - 2] =  isPos[numSfb - 5];
        isPos[numSfb - 3] =  isPos[numSfb - 6];
      }
    } else {
      isPos[numSfb - 1] = f20 ? 0 : isPos[numSfb - 2];
    }

    ptrL = &((*smpl_xr)[0][0]);
    ptrR = &((*smpl_xr)[1][0]);

    for (sfb = 0; sfb < numSfb; sfb++) {
        w = width[sfb];
        if (isPos[sfb] == illegal) {
            if (ms_stereo) {
                for (i = 0; i < w; i++) {
                    li = mult * (ptrL[0] + ptrR[0]);
                    ri = mult * (ptrL[0] - ptrR[0]);
                    ptrL[0] = li;
                    ptrR[0] = ri;
                    ptrL++; ptrR++;
                }
            } else {
                ptrL += w;
                ptrR += w;
            }
        } else {
            if (header->id) {
                if (isPos[sfb] > 6) {
                    isPos[sfb] = 6;
                }
                k[0]  = mpeg1_intensity[isPos[sfb]];
                k[1]  = mpeg1_intensity[6 - isPos[sfb]];
            } else {
                Ipp32s tmp0, tmp1;
                tmp0 = isPos[sfb] & 1;
                tmp1 = (isPos[sfb] + 1) >> 1;

                k[tmp0] = 1;
                k[1-tmp0] = mpeg2_intensity[(si_sfCompress[0][1] & 1)][tmp1];
            }

            for (i = 0; i < w; i++) {
                li = k[0] * ptrL[0];
                ri = k[1] * ptrL[0];
                ptrL[0] = li;
                ptrR[0] = ri;
                ptrL++; ptrR++;
            }
        }
    }
    return 1;
}

/******************************************************************************
//  Name:
//    IMDCT
//
//  Description:
//    inverse modifid cosine tranformation. overlaping and adding.
//
//
//  Input Arguments:
//    DC - point to sDecoderContext structure
//    gr - number of granule
//    ch - number of channel
//
//  Output Arguments:
//    smpl_rw - prepared values for synthesis filterbank
//
//  Returns:
//    1 - all ok
//
******************************************************************************/
static Ipp32s mp3dec_IMDCT(MP3Dec *state, Ipp32s gr, Ipp32s ch)
{
    Ipp32s bt;
    Ipp32s wnd, sb;
    Ipp32s j;

    Ipp32f rawout[36], tmp[36], tmpBuf[576];
    Ipp32f *prev_ptr;
    Ipp32f *in, *tmpBufPtr;

    Ipp8u  *mdct_buffer = state->mdct_buffer;
    IppsMDCTInvSpec_32f *pMDCTSpecShort = state->pMDCTSpecShort;
    IppsMDCTInvSpec_32f *pMDCTSpecLong = state->pMDCTSpecLong;
    Ipp32f (*prevblk)[576] = state->prevblk;
    Ipp32u (*si_blockType)[2] = state->com.si_blockType;
    Ipp32u (*si_mixedBlock)[2] = state->com.si_mixedBlock;
    Ipp32u (*si_winSwitch)[2] = state->com.si_winSwitch;
    samplefloat *smpl_re = state->smpl_re;       /* out of antialiasing */
    samplefloatrw *smpl_rw = state->smpl_rw;     /* out of imdct */
    Ipp32s nz = state->com.non_zero[ch];
    Ipp32s nimdct = (nz + 17 + 9) * 3641 >> 16;
    Ipp32s maximdct;

    if (nimdct > 32)
        nimdct = 32;
    maximdct = nimdct;

    if (state->dctnum_prev[ch] > maximdct)
        maximdct = state->dctnum_prev[ch];
    state->dctnum_prev[ch] = nimdct;

    prev_ptr = prevblk[ch];
    in = (*smpl_re)[ch];
    tmpBufPtr = tmpBuf;

    for (sb = 0; sb < maximdct; sb++) {
        bt = si_blockType[gr][ch];

        if (si_winSwitch[gr][ch] && si_mixedBlock[gr][ch] && (sb < 2)) {
            bt = 0;
        }

        if (bt != 2) {
            if (sb < nimdct) {
                ippsMDCTInv_32f(in, rawout, pMDCTSpecLong, mdct_buffer);
                ippsMul_32f_I(mp3dec_imdct_table[bt], rawout, 18);
                ippsAdd_32f(prev_ptr, rawout, tmpBufPtr, 18);
                ippsMul_32f(mp3dec_imdct_table[bt] + 18, rawout + 18, prev_ptr, 18);
            } else {
                ippsCopy_32f(prev_ptr, tmpBufPtr, 18);
                ippsZero_32f(prev_ptr, 18);
            }
            in += 18;
        } else {
            if (sb < nimdct) {
                for (wnd = 0; wnd < 3; wnd++) {
                    Ipp32f ttt[6];
                    Ipp32s iii;

                    for (iii = 0; iii < 6; iii++) {
                        ttt[iii] = in[iii*3+wnd];
                    }

                    ippsMDCTInv_32f(ttt, tmp + wnd * 12,
                        pMDCTSpecShort, mdct_buffer);
                }
                ippsMul_32f_I(mp3dec_imdct_table[2], tmp, 36);

                ippsCopy_32f(prev_ptr, tmpBufPtr, 6);
                ippsAdd_32f(prev_ptr + 6, tmp, tmpBufPtr + 6, 6);
                ippsAdd_32f(tmp + 6, tmp + 12, rawout + 12, 6);
                ippsAdd_32f(prev_ptr + 12, rawout + 12, tmpBufPtr + 12, 6);

                ippsAdd_32f(tmp + 18, tmp + 24, prev_ptr, 6);
                ippsCopy_32f(tmp + 30, prev_ptr + 6, 6);
                ippsZero_32f(prev_ptr + 12, 6);
            } else {
                ippsCopy_32f(prev_ptr, tmpBufPtr, 18);
                ippsZero_32f(prev_ptr, 18);
            }
            in += 18;
        }

        if (sb & 1) {
            for (j = 1; j < 18; j += 2) {
                tmpBufPtr[j] = -tmpBufPtr[j];
            }
        }

        prev_ptr += 18;
        tmpBufPtr += 18;
    }

    if (sb < 32)
        ippsZero_32f(tmpBufPtr, 18 * (32 - sb));

    for (j = 0; j < 18; j++) {
        for (sb = 0; sb < 32; sb++) {
            (*smpl_rw)[ch][j][sb] = tmpBuf[sb * 18 + j];
        }
    }

    return 1;
}

/******************************************************************************
//  Name:
//    decode_data_LayerIII
//
//  Description:
//    decode one frame of mpeg 1 layer 3 bitstream and save decoded value
//    to output buffer
//
//  Input Arguments:
//    DC - point to sDecoderContext structure
//
//  Output Arguments:
//    outsamples - decoded values of one frame
//
//  Returns:
//
******************************************************************************/

MP3Status mp3dec_decode_data_LayerIII(MP3Dec *state)
{
    Ipp32s main_data_bits;
    Ipp32s i, gr, ch;
    Ipp32f *pSampl[2];

    IppMP3FrameHeader *header = &(state->com.header);
    sBitsreamBuffer *m_MainData = &(state->com.m_MainData);
    Ipp32f (*GlobalScaleFactor)[2] = state->GlobalScaleFactor;
    Ipp16s *m_pOutSamples = state->com.m_pOutSamples;
    Ipp32u (*si_part23Len)[2] = state->com.si_part23Len;
    Ipp16s (*si_globGain)[2] = state->com.si_globGain;
    samplefloat *smpl_sb = state->smpl_sb;       // out of subband synth
    Ipp32s stereo = state->com.stereo;

    Ipp32s part2_start;

    pSampl[0] = (*smpl_sb)[0];
    pSampl[1] = (*smpl_sb)[1];

    // restores actual scalefactors to the values extracted from the bitstream.
    // Four scalefactors in si_globGain (beginning at an offset of 210)
    // are restored to the GlobalScaleFactor vector.

    ippsCalcSF_16s32f((Ipp16s *)(si_globGain), 210, (Ipp32f *)GlobalScaleFactor, 4);

    if (mp3dec_ReadMainData(&state->com))
        return MP3_NOT_FIND_SYNCWORD;

    main_data_bits =
        (m_MainData->pCurrent_dword - m_MainData->pBuffer) * 32 + (32 -
        m_MainData->nBit_offset);

    if (main_data_bits < 0)
        return MP3_NOT_ENOUGH_DATA;

    for (gr = 0; gr < header->id + 1; gr++) {
        for (ch = 0; ch < stereo; ch++) {
            Ipp32s rested_bits;

            // detect start point
            m_MainData->pCurrent_dword = m_MainData->pBuffer + (main_data_bits >> 5);
            m_MainData->dword = BSWAP(m_MainData->pCurrent_dword[0]);
            m_MainData->nBit_offset = 32 - (main_data_bits % 32);
            main_data_bits += si_part23Len[gr][ch];

            part2_start =
                (m_MainData->pCurrent_dword - m_MainData->pBuffer) * 32 + 32 -
                m_MainData->nBit_offset;
            state->com.part2_start = part2_start;

            rested_bits =
                (m_MainData->nDataLen -
                (Ipp32s)(m_MainData->pCurrent_dword - m_MainData->pBuffer) * 4) * 32 +
                32 - m_MainData->nBit_offset;
            if (rested_bits < (Ipp32s)si_part23Len[gr][ch])
                return MP3_BAD_STREAM;

            if (header->id)
                mp3dec_GetScaleFactorsL3(&state->com, gr, ch);
            else
                mp3dec_GetScaleFactorsL3_LSF(&state->com, ch);

            if (mp3dec_Huffmancodebits(&state->com, gr, ch))
              return MP3_BAD_STREAM;
            mp3dec_Dequant(state, gr, ch);
        }

        if ((header->mode == 0x01) && (header->modeExt != 0)) {
            if (state->com.non_zero[0] < state->com.non_zero[1])
                state->com.non_zero[0] = state->com.non_zero[1];
            else
                state->com.non_zero[1] = state->com.non_zero[0];
            mp3dec_JointStereo(state, gr);
        }
        for (ch = 0; ch < stereo; ch++) {
            mp3dec_Reordering(state, gr, ch);
            mp3dec_Antialiasing(state, gr, ch);
            mp3dec_IMDCT(state, gr, ch);
            for (i = 0; i < 18; i++) {
              ippsSynthesisFilter_PQMF_MP3_32f((*(state->smpl_rw))[ch][i],
                pSampl[ch] + i * 32,
                state->pPQMFSpec[ch], 1);
            }
        }

        // combines the data from all channels in the working array after the
        // SubBandSynth phase
        // into one joined vector.
        // arguments:
        // pSampl -- points to smpl_sb in global (the working array for the
        // SubBandSynth phase)
        // stereo -- number of channels
        // 576 -- number of data elements in each channel
        // outsamples + ... -- points to the joined (output) vector
        ippsJoin_32f16s_D2L((const Ipp32f **)pSampl, stereo, 576,
            m_pOutSamples + gr * 576 * stereo);
    }
    return MP3_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -