www.pudn.com > VC写的MP3播放器源代码.zip > LayerIII.cpp
///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "LayerIII.h" #include///////////////////////////////////////////////////////////////////////////// // BOOL CLayerIII::DecodeBlock(BYTE *pVarIn, // block from file passed in DWORD nLength, // length of block BYTE *pVarOut, // out buffer DWORD *outLevel,// acumulated bytes in out buffer DWORD mpVersion, // fix march 30 MCO DWORD nMode, // fix march 30 MCO DWORD modeExtension,// fix march 30 MCO DWORD freqIdx) // fix march 30 MCO { DWORD flDwm = 0; DWORD dwGr, dwCh, dwTmp1, dwTmp2, iSb18; int nMainDataEnd = 0; int nDiscardBytes = 0; int nSamples = 0; int dw = (int)nLength; int acLeft = *outLevel/2; int acRight = *outLevel/2; double dblSum ; // this array pass to the scope the spectrum double tdblSum[40] ={0}; m_version = mpVersion; m_flMode = nMode; m_dwExtensionMode = modeExtension; m_pbyWalk = pVarIn; m_nBitsOffset = 0; GetSideInfo(); // looking for fast copying while(--dw >= 0) AddTail(Bits(8)); nMainDataEnd = GetReadBits() >> 3; // /4 if (flDwm = (GetReadBits() & 7)) { GetBits(8 - flDwm); nMainDataEnd++; } nDiscardBytes = m_nFrmStart - nMainDataEnd - m_SIDEINF.dataMainStart; m_nFrmStart += nLength; if (nDiscardBytes < 0) return FALSE ; if (nMainDataEnd > 4096) { m_nFrmStart -= 4096; GoBackOctets(); } while(nDiscardBytes-->0) { GetBits(8); } for (dwGr =0; dwGr < m_dwMaxGr; dwGr++) { for (dwCh = 0; dwCh < (DWORD)m_nChanels; dwCh++) { m_nPart2Start = GetReadBits(); if (m_dwMaxGr == 2) GetScaleFact(dwCh, dwGr); else // MPEG-2 LSF GetLSFScaleFactor(dwCh, dwGr); HuffmanDecode(dwCh, dwGr); DeqSample(m_cubeRo[dwCh], dwCh, dwGr); } if(-1 == Stereo(dwGr)) return FALSE; for (dwCh = m_chFirst ; dwCh <= (DWORD)m_chLast; dwCh++) { Reorder(m_cubeLr[dwCh], dwCh, dwGr); AntiAlias(dwCh, dwGr); Hibrid(dwCh, dwGr); for (iSb18 = 18; iSb18 < 576;iSb18+=36) { for (dwTmp1=1; dwTmp1 < 18; dwTmp1 += 2) { m_dOutArr[iSb18 + dwTmp1] = -m_dOutArr[iSb18 + dwTmp1]; } } if (dwCh == 0 || m_nChanel == 2) { for (dwTmp1=0; dwTmp1 < 18; dwTmp1++) { dblSum = 0; for (dwTmp2 = 0,iSb18=0; iSb18 < 576; iSb18 += 18,dwTmp2++) { tdblSum[dwTmp2] += m_pFilterX->InSample(m_dOutArr[iSb18 + dwTmp1],dwTmp2 ); } m_pFilterX->PrepPCMSampleX(pVarOut,nSamples,acRight,m_pfnCallback); } (*m_pfnCallback)(0,tdblSum,dwTmp2); } else { for (dwTmp1=0; dwTmp1 < 18; dwTmp1++) { for (dwTmp2 = 0,iSb18=0; iSb18 < 576; iSb18 += 18,dwTmp2++) { m_pFilterY->InSample(m_dOutArr[iSb18 + dwTmp1], dwTmp2); } m_pFilterY->PrepPCMSampleX(pVarOut,nSamples,acLeft,m_pfnCallback); } } } } //MCO *outLevel += nSamples; return TRUE; } ////////////////////////////////////////////////////////////////////////////////// // The original code has been shrinked // by 16 times, without losing to mutch speed(Marius C.) // Also added the support for callback function pFn. If there is no pFn // the default gain is applied(MC) int SynthesisFilter::PrepPCMSampleX(BYTE* pBuff,int& samples,int& nOffset, PFN pFn,void* pData) { double* pDb = m_pToTable; int idx = m_nWriteIndex; double dblV = 0.0f; WORD* pwOutBuf = (WORD*)pBuff; CompNewTable(); // Marius C. for( double *pTd = dblISO; pTd < dblISO + (512); pTd += 16, pDb += 16 ) { dblV = (double)(( ((pDb[(idx) & 0xf] * pTd[0])) + ((pDb[(idx-1) & 0xf] * pTd[1])) + ((pDb[(idx-2) & 0xf] * pTd[2])) + ((pDb[(idx-3) & 0xf] * pTd[3])) + ((pDb[(idx-4) & 0xf] * pTd[4])) + ((pDb[(idx-5) & 0xf] * pTd[5])) + ((pDb[(idx-6) & 0xf] * pTd[6])) + ((pDb[(idx-7) & 0xf] * pTd[7])) + ((pDb[(idx-8) & 0xf] * pTd[8])) + ((pDb[(idx-9) & 0xf] * pTd[9])) + ((pDb[(idx-10) & 0xf] * pTd[10])) + ((pDb[(idx-11) & 0xf] * pTd[11])) + ((pDb[(idx-12) & 0xf] * pTd[12])) + ((pDb[(idx-13) & 0xf] * pTd[13])) + ((pDb[(idx-14) & 0xf] * pTd[14])) + ((pDb[(idx-15) & 0xf] * pTd[15])) )*32767.0f); // IF CRASH HERE THAT MEANS YOU CHANGED THE MCI BUFFER SIZE // OR THE MODULO IN MAIN THREAD LOOP if(pFn != 0) // leave you to use the vol controland or the EQ pwOutBuf[m_nCan + (nOffset<<1)] = (WORD)((*pFn) (&dblV,0,m_nCan)); else // auto gain pre amplif { pwOutBuf[m_nCan + (nOffset<<1)] = Clip(dblV); } nOffset++; samples++; } m_nWriteIndex = (m_nWriteIndex + 1) & 0xf; m_pToTable = (m_pToTable == m_tableA) ? m_tableB : m_tableA; // MCO not necesarely // ZeroMemory(m_tdbSubSamples,sizeof(m_tdbSubSamples)); return 1; } BOOL CLayerIII::Init(DWORD mpVersion, DWORD nMode, DWORD modeExtension, DWORD freqIdx, long pFnCallBack ) { m_pFilterX = new SynthesisFilter(0); m_pFilterY = new SynthesisFilter(1); if(m_pFilterY == 0 || m_pFilterY == 0) { delete m_pFilterX; delete m_pFilterY; m_pFilterY=m_pFilterX=0; return FALSE; } ResolveChannels(nMode); // callback fn added by M.C m_pfnCallback = reinterpret_cast (pFnCallBack); m_nFrmStart = 0; m_version = mpVersion; m_dwMaxGr = (mpVersion == 1) ? 2 : 1; m_flMode = nMode; m_nFreqIdx = freqIdx + ((m_dwMaxGr == 2) ? 3 : 0); m_dwExtensionMode = modeExtension; ZeroMemory(m_PreBlkArr,sizeof(m_PreBlkArr)); m_arrNonZero[0] = m_arrNonZero[1] = 576; m_pbyWalk = 0; return TRUE; } void CLayerIII::Reset() { if(0 != m_pFilterX && 0 != m_pFilterY) { m_pFilterY->Reset(); m_pFilterX->Reset(); m_pbyWalk = 0; m_nFrmStart = 0; ZeroMemory(m_PreBlkArr,sizeof(m_PreBlkArr)); } } /////////////////////////////////////////////////////////////////////////////// // Marius C void CLayerIII::ResolveChannels(int nMode) { m_chFirst = 0; m_chLast = 1; m_nChanel = 0; m_nChanels = (nMode == 3) ? 1 : 2; if(m_nChanels == 1) { m_nChanel = 1; //left channel m_chFirst = m_chLast = 0; } } /////////////////////////////////////////////////////////////////////////////// // BOOL CLayerIII::GetSideInfo() { int dwCh, dwGr; STR_GRINFO* pToCel; int nChanels = m_nChanels; if (m_dwMaxGr == 2) // MPEG1 { m_SIDEINF.dataMainStart = Bits(9); if (m_nChanels == 1) m_SIDEINF.privBits = Bits(5); else m_SIDEINF.privBits = Bits(3); for (dwCh=0; dwCh < nChanels; dwCh++) { m_SIDEINF.sArrCH[dwCh].arrScfSi[0] = Bits(1); m_SIDEINF.sArrCH[dwCh].arrScfSi[1] = Bits(1); m_SIDEINF.sArrCH[dwCh].arrScfSi[2] = Bits(1); m_SIDEINF.sArrCH[dwCh].arrScfSi[3] = Bits(1); } for (dwGr=0; dwGr < 2; dwGr++) { for (dwCh=0; dwCh < nChanels; dwCh++) { pToCel = &m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr]; pToCel->p23Len = Bits(12); pToCel->bigVal = Bits(9); pToCel->glbGain = Bits(8); pToCel->scaleFactCompress = Bits(4); if(pToCel->wndSwitchFlag = Bits(1)) { pToCel->nBlockType = Bits(2); pToCel->mixedBlockFlag = Bits(1); pToCel->arrSelect[0] = Bits(5); pToCel->arrSelect[1] = Bits(5); pToCel->arrSubBlockGain[0] = Bits(3); pToCel->arrSubBlockGain[1] = Bits(3); pToCel->arrSubBlockGain[2] = Bits(3); // Set region_count parameters since they are implicit pDblIn this case. if (0 ==pToCel->nBlockType) { return FALSE; } else if (2 == pToCel->nBlockType && 0 == pToCel->mixedBlockFlag ) { pToCel->region0Count = 8; } else { pToCel->region0Count = 7; } pToCel->region1Count = 20 - pToCel->region0Count; } else { pToCel->arrSelect[0] = Bits(5); pToCel->arrSelect[1] = Bits(5); pToCel->arrSelect[2] = Bits(5); pToCel->region0Count = Bits(4); pToCel->region1Count = Bits(3); pToCel->nBlockType = 0; } pToCel->preflag = Bits(1); pToCel->scaleFactScale = Bits(1); pToCel->countTblSelect = Bits(1); } } } else { // MPEG-2 LSF m_SIDEINF.dataMainStart = Bits(8); if (nChanels == 1) m_SIDEINF.privBits = Bits(1); else m_SIDEINF.privBits = Bits(2); for (dwCh=0; dwCh p23Len = Bits(12); pToCel->bigVal = Bits(9); pToCel->glbGain = Bits(8); pToCel->scaleFactCompress = Bits(9); pToCel->wndSwitchFlag = Bits(1); if (pToCel->wndSwitchFlag) { pToCel->nBlockType = Bits(2); pToCel->mixedBlockFlag = Bits(1); pToCel->arrSelect[0] = Bits(5); pToCel->arrSelect[1] = Bits(5); pToCel->arrSubBlockGain[0] = Bits(3); pToCel->arrSubBlockGain[1] = Bits(3); pToCel->arrSubBlockGain[2] = Bits(3); // Set region_count parameters since they are implicit pDblIn this case. if (pToCel->nBlockType == 0) { // Side info bad: nBlockType == 0 pDblIn split block return FALSE; } else if (pToCel->nBlockType == 2 && pToCel->mixedBlockFlag == 0) { pToCel->region0Count = 8; } else { pToCel->region0Count = 7; pToCel->region1Count = 20 - pToCel->region0Count; } } else { pToCel->arrSelect[0] = Bits(5); pToCel->arrSelect[1] = Bits(5); pToCel->arrSelect[2] = Bits(5); pToCel->region0Count = Bits(4); pToCel->region1Count = Bits(3); pToCel->nBlockType = 0; } pToCel->scaleFactScale = Bits(1); pToCel->countTblSelect = Bits(1); } } return TRUE; } void CLayerIII::GetScaleFact(DWORD dwCh, DWORD dwGr) { int nSfb, nWnd; STR_GRINFO* pGRLOCAL = &(m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr]); int nscaleFact = pGRLOCAL->scaleFactCompress; int nLenLeft = slen[0][nscaleFact]; int nLenRight = slen[1][nscaleFact]; if (pGRLOCAL->wndSwitchFlag && (pGRLOCAL->nBlockType == 2)) { if (pGRLOCAL->mixedBlockFlag) { // MIXED for (nSfb = 0; nSfb < 8; nSfb++) m_sCALEF[dwCh].l[nSfb] = GetBits( slen[0][pGRLOCAL->scaleFactCompress]); for (nSfb = 3; nSfb < 6; nSfb++) for (nWnd=0; nWnd<3; nWnd++) m_sCALEF[dwCh].s[nWnd][nSfb] = GetBits( slen[0][pGRLOCAL->scaleFactCompress]); for (nSfb = 6; nSfb < 12; nSfb++) for (nWnd=0; nWnd<3; nWnd++) m_sCALEF[dwCh].s[nWnd][nSfb] = GetBits( slen[1][pGRLOCAL->scaleFactCompress]); for (nSfb=12,nWnd=0; nWnd<3; nWnd++) m_sCALEF[dwCh].s[nWnd][nSfb] = 0; } else { // SHORT m_sCALEF[dwCh].s[0][0] = GetBits(nLenLeft); m_sCALEF[dwCh].s[1][0] = GetBits(nLenLeft); m_sCALEF[dwCh].s[2][0] = GetBits(nLenLeft); m_sCALEF[dwCh].s[0][1] = GetBits(nLenLeft); m_sCALEF[dwCh].s[1][1] = GetBits(nLenLeft); m_sCALEF[dwCh].s[2][1] = GetBits(nLenLeft); m_sCALEF[dwCh].s[0][2] = GetBits(nLenLeft); m_sCALEF[dwCh].s[1][2] = GetBits(nLenLeft); m_sCALEF[dwCh].s[2][2] = GetBits(nLenLeft); m_sCALEF[dwCh].s[0][3] = GetBits(nLenLeft); m_sCALEF[dwCh].s[1][3] = GetBits(nLenLeft); m_sCALEF[dwCh].s[2][3] = GetBits(nLenLeft); m_sCALEF[dwCh].s[0][4] = GetBits(nLenLeft); m_sCALEF[dwCh].s[1][4] = GetBits(nLenLeft); m_sCALEF[dwCh].s[2][4] = GetBits(nLenLeft); m_sCALEF[dwCh].s[0][5] = GetBits(nLenLeft); m_sCALEF[dwCh].s[1][5] = GetBits(nLenLeft); m_sCALEF[dwCh].s[2][5] = GetBits(nLenLeft); m_sCALEF[dwCh].s[0][6] = GetBits(nLenRight); m_sCALEF[dwCh].s[1][6] = GetBits(nLenRight); m_sCALEF[dwCh].s[2][6] = GetBits(nLenRight); m_sCALEF[dwCh].s[0][7] = GetBits(nLenRight); m_sCALEF[dwCh].s[1][7] = GetBits(nLenRight); m_sCALEF[dwCh].s[2][7] = GetBits(nLenRight); m_sCALEF[dwCh].s[0][8] = GetBits(nLenRight); m_sCALEF[dwCh].s[1][8] = GetBits(nLenRight); m_sCALEF[dwCh].s[2][8] = GetBits(nLenRight); m_sCALEF[dwCh].s[0][9] = GetBits(nLenRight); m_sCALEF[dwCh].s[1][9] = GetBits(nLenRight); m_sCALEF[dwCh].s[2][9] = GetBits(nLenRight); m_sCALEF[dwCh].s[0][10] = GetBits(nLenRight); m_sCALEF[dwCh].s[1][10] = GetBits(nLenRight); m_sCALEF[dwCh].s[2][10] = GetBits(nLenRight); m_sCALEF[dwCh].s[0][11] = GetBits(nLenRight); m_sCALEF[dwCh].s[1][11] = GetBits(nLenRight); m_sCALEF[dwCh].s[2][11] = GetBits(nLenRight); m_sCALEF[dwCh].s[0][12] = 0; m_sCALEF[dwCh].s[1][12] = 0; m_sCALEF[dwCh].s[2][12] = 0; } // SHORT } else { // LONG types 0,1,3 if ((m_SIDEINF.sArrCH[dwCh].arrScfSi[0] == 0) || (dwGr == 0)) { m_sCALEF[dwCh].l[0] = GetBits(nLenLeft); m_sCALEF[dwCh].l[1] = GetBits(nLenLeft); m_sCALEF[dwCh].l[2] = GetBits(nLenLeft); m_sCALEF[dwCh].l[3] = GetBits(nLenLeft); m_sCALEF[dwCh].l[4] = GetBits(nLenLeft); m_sCALEF[dwCh].l[5] = GetBits(nLenLeft); } if ((m_SIDEINF.sArrCH[dwCh].arrScfSi[1] == 0) || (dwGr == 0)) { m_sCALEF[dwCh].l[6] = GetBits(nLenLeft); m_sCALEF[dwCh].l[7] = GetBits(nLenLeft); m_sCALEF[dwCh].l[8] = GetBits(nLenLeft); m_sCALEF[dwCh].l[9] = GetBits(nLenLeft); m_sCALEF[dwCh].l[10] = GetBits(nLenLeft); } if ((m_SIDEINF.sArrCH[dwCh].arrScfSi[2] == 0) || (dwGr == 0)) { m_sCALEF[dwCh].l[11] = GetBits(nLenRight); m_sCALEF[dwCh].l[12] = GetBits(nLenRight); m_sCALEF[dwCh].l[13] = GetBits(nLenRight); m_sCALEF[dwCh].l[14] = GetBits(nLenRight); m_sCALEF[dwCh].l[15] = GetBits(nLenRight); } if ((m_SIDEINF.sArrCH[dwCh].arrScfSi[3] == 0) || (dwGr == 0)) { m_sCALEF[dwCh].l[16] = GetBits(nLenRight); m_sCALEF[dwCh].l[17] = GetBits(nLenRight); m_sCALEF[dwCh].l[18] = GetBits(nLenRight); m_sCALEF[dwCh].l[19] = GetBits(nLenRight); m_sCALEF[dwCh].l[20] = GetBits(nLenRight); } m_sCALEF[dwCh].l[21] = 0; m_sCALEF[dwCh].l[22] = 0; } } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::GetLSFScaleData(DWORD dwCh, DWORD dwGr) { DWORD newLength[4]; DWORD scFctComp, scFctCompInt; int nBlkType, nBlkNr; DWORD dwExtensionMode = m_dwExtensionMode; STR_GRINFO *pGRLOCAL = &(m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr]); scFctComp = pGRLOCAL->scaleFactCompress; if (pGRLOCAL->nBlockType == 2) { if (pGRLOCAL->mixedBlockFlag == 0) nBlkType = 1; else if (pGRLOCAL->mixedBlockFlag == 1) nBlkType = 2; else nBlkType = 0; } else { nBlkType = 0; } if(!(((dwExtensionMode == 1) || (dwExtensionMode == 3)) && (dwCh == 1))) { if(scFctComp < 400) { newLength[0] = (scFctComp >> 4) / 5 ; newLength[1] = (scFctComp >> 4) % 5 ; newLength[2] = (scFctComp & 0xF) >> 2 ; newLength[3] = (scFctComp & 3); m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].preflag = 0; nBlkNr = 0; } else if (scFctComp < 500) { newLength[0] = ((scFctComp - 400) >> 2) / 5 ; newLength[1] = ((scFctComp - 400) >> 2) % 5 ; newLength[2] = (scFctComp - 400 ) & 3 ; newLength[3] = 0; m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].preflag = 0; nBlkNr = 1; } else if (scFctComp < 512) { newLength[0] = (scFctComp - 500 ) / 3 ; newLength[1] = (scFctComp - 500) % 3 ; newLength[2] = 0; newLength[3] = 0; m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].preflag = 1; nBlkNr = 2; } } if((((dwExtensionMode == 1) || (dwExtensionMode == 3)) && (dwCh == 1))) { scFctCompInt = scFctComp >> 1; if (scFctCompInt < 180) { newLength[0] = scFctCompInt / 36 ; newLength[1] = (scFctCompInt % 36 ) / 6 ; newLength[2] = (scFctCompInt % 36) % 6; newLength[3] = 0; m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].preflag = 0; nBlkNr = 3; } else if (scFctCompInt < 244) { newLength[0] = ((scFctCompInt - 180 ) & 0x3F) >> 4 ; newLength[1] = ((scFctCompInt - 180) & 0xF) >> 2 ; newLength[2] = (scFctCompInt - 180 ) & 3 ; newLength[3] = 0; m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].preflag = 0; nBlkNr = 4; } else if (scFctCompInt < 255) { newLength[0] = (scFctCompInt - 244 ) / 3 ; newLength[1] = (scFctCompInt - 244 ) % 3 ; newLength[2] = 0 ; newLength[3] = 0; m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].preflag = 0; nBlkNr = 5; } } ZeroMemory(m_dwScale,sizeof(m_dwScale)); // why 45, not 54? int m = 0; for (DWORD dw=0; dw<4;dw++) { for (DWORD j = 0; j < nr_of_nSfb_block[nBlkNr][nBlkType][dw];j++) { m_dwScale[m] = (newLength[dw] == 0) ? 0 : GetBits(newLength[dw]); m++; } } } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::GetLSFScaleFactor(DWORD dwCh, DWORD dwGr) { DWORD m = 0; DWORD nSfb, nWnd; STR_GRINFO *pGRLOCAL = &(m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr]); GetLSFScaleData(dwCh, dwGr); if (pGRLOCAL->wndSwitchFlag && (pGRLOCAL->nBlockType == 2)) { if (pGRLOCAL->mixedBlockFlag) { // MIXED for (nSfb = 0; nSfb < 8; nSfb++) { m_sCALEF[dwCh].l[nSfb] = m_dwScale[m]; m++; } for (nSfb = 3; nSfb < 12; nSfb++) { for (nWnd=0; nWnd<3; nWnd++) { m_sCALEF[dwCh].s[nWnd][nSfb] = m_dwScale[m]; m++; } } for (nWnd=0; nWnd<3; nWnd++) m_sCALEF[dwCh].s[nWnd][12] = 0; } else { // SHORT for (nSfb = 0; nSfb < 12; nSfb++) { for (nWnd=0; nWnd<3; nWnd++) { m_sCALEF[dwCh].s[nWnd][nSfb] = m_dwScale[m]; m++; } } for (nWnd=0; nWnd < 3; nWnd++) m_sCALEF[dwCh].s[nWnd][12] = 0; } } else { // LONG types 0,1,3 for (nSfb = 0; nSfb < 21; nSfb++) { m_sCALEF[dwCh].l[nSfb] = m_dwScale[m]; m++; } m_sCALEF[dwCh].l[21] = 0; // Jeff m_sCALEF[dwCh].l[22] = 0; } } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::HuffmanDecode(DWORD dwCh, DWORD dwGr) { int x, y; int v, w; int part2_3_end = m_nPart2Start + m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].p23Len; int num_bits; int region1Start; int region2Start; int mIndex; struct sHUFDECTAB *pHfDecTab; // Find region boundary for short block case if ( (m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].wndSwitchFlag) && (m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].nBlockType == 2) ) { // Region2. region1Start = 36; // nSfb[9/3]*3=36 region2Start = 576; // No Region2 for short block case } else { // Find region boundary for long block case region1Start = sfBandIndex[m_nFreqIdx].l[m_SIDEINF.sArrCH[dwCh]. sArrGRINF[dwGr].region0Count + 1]; region2Start = sfBandIndex[m_nFreqIdx].l[m_SIDEINF.sArrCH[dwCh]. sArrGRINF[dwGr].region0Count + m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr]. region1Count + 2]; /* MI */ } mIndex = 0; // Read bigvalues area for (int dw=0; dw < (m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].bigVal<<1); dw+=2) { if (dw < (int)region1Start) pHfDecTab = &ht[m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].arrSelect[0]]; else if (dw < (int)region2Start) pHfDecTab = &ht[m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].arrSelect[1]]; else pHfDecTab = &ht[m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].arrSelect[2]]; HuffmanDec(pHfDecTab, &x, &y, &v, &w); m_nArray[mIndex++] = x; m_nArray[mIndex++] = y; } // Read count1 area pHfDecTab = &ht[m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr].countTblSelect+32]; num_bits = GetReadBits(); while ((num_bits < part2_3_end) && (mIndex < 576)) { HuffmanDec(pHfDecTab, &x, &y, &v, &w); m_nArray[mIndex++] = v; m_nArray[mIndex++] = w; m_nArray[mIndex++] = x; m_nArray[mIndex++] = y; num_bits = GetReadBits(); } if (num_bits > part2_3_end) { GoBackBits(num_bits - part2_3_end); mIndex-=4; } num_bits = GetReadBits(); // Dismiss stuffing bits if (num_bits < part2_3_end) GetBits(part2_3_end - num_bits); // Zero pDblOut rest if (mIndex < 576) m_arrNonZero[dwCh] = mIndex; else m_arrNonZero[dwCh] = 576; if(mIndex < 576) ZeroMemory(m_nArray+mIndex,(576-mIndex)*sizeof(int)); } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::DeqSample(double dbRectArr[32][18], DWORD dwCh, DWORD dwGr) { int nCountb PURE; int nextCbBound, nBeginCb, nWidthCb; int mIndex=0, tIndex, j; double dblGain; double* pDblRectArr = &dbRectArr[0][0]; STR_GRINFO *pGRLOCAL = &(m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr]); // choose correct scalefactor band per block type, initalize boundary if (pGRLOCAL->wndSwitchFlag && (pGRLOCAL->nBlockType == 2) ) { if (pGRLOCAL->mixedBlockFlag) nextCbBound=sfBandIndex[m_nFreqIdx].l[1]; // LONG blocks: 0,1,3 else { nWidthCb = sfBandIndex[m_nFreqIdx].s[1]; nextCbBound = (nWidthCb << 2) - nWidthCb; nBeginCb = 0; } } else { nextCbBound=sfBandIndex[m_nFreqIdx].l[1]; // LONG blocks: 0,1,3 } // Compute overall (global) scaling. dblGain = (double) pow(2.0 , (0.25 * (pGRLOCAL->glbGain - 210.0))); for (j=0; j 0) pDblRectArr[j] = dblGain * t_43[abv]; else pDblRectArr[j] = -dblGain * t_43[-abv]; } } // apply formula per block type for (j=0; j wndSwitchFlag && (pGRLOCAL->nBlockType == 2)) { if (pGRLOCAL->mixedBlockFlag) { if (mIndex == sfBandIndex[m_nFreqIdx].l[8]) { nextCbBound = sfBandIndex[m_nFreqIdx].s[4]; nextCbBound = (nextCbBound << 2) - nextCbBound; nCountb = 3; nWidthCb = sfBandIndex[m_nFreqIdx].s[4] - sfBandIndex[m_nFreqIdx].s[3]; nBeginCb = sfBandIndex[m_nFreqIdx].s[3]; nBeginCb = (nBeginCb << 2) - nBeginCb; } else if (mIndex < sfBandIndex[m_nFreqIdx].l[8]) { nextCbBound = sfBandIndex[m_nFreqIdx].l[(++nCountb)+1]; } else { nextCbBound = sfBandIndex[m_nFreqIdx].s[(++nCountb)+1]; nextCbBound = (nextCbBound << 2) - nextCbBound; nBeginCb = sfBandIndex[m_nFreqIdx].s[nCountb]; nWidthCb = sfBandIndex[m_nFreqIdx].s[nCountb+1] - nBeginCb; nBeginCb = (nBeginCb << 2) - nBeginCb; } } else { nextCbBound = sfBandIndex[m_nFreqIdx].s[(++nCountb)+1]; nextCbBound = (nextCbBound << 2) - nextCbBound; nBeginCb = sfBandIndex[m_nFreqIdx].s[nCountb]; nWidthCb = sfBandIndex[m_nFreqIdx].s[nCountb+1] - nBeginCb; nBeginCb = (nBeginCb << 2) - nBeginCb; } } else { // long blocks nextCbBound = sfBandIndex[m_nFreqIdx].l[(++nCountb)+1]; } } // Do long/short dependent scaling operations if (pGRLOCAL->wndSwitchFlag && (((pGRLOCAL->nBlockType == 2) && (pGRLOCAL->mixedBlockFlag == 0)) || ((pGRLOCAL->nBlockType == 2) && pGRLOCAL->mixedBlockFlag && (j >= 36)) )) { tIndex = (mIndex - nBeginCb) / nWidthCb; /* dbRectArr[sb][ss] *= pow(2.0, ((-2.0 * pGRLOCAL->arrSubBlockGain[tIndex]) -(0.5 * (1.0 + pGRLOCAL->scaleFactScale) * m_sCALEF[dwCh].s[tIndex][nCountb]))); */ DWORD idx = m_sCALEF[dwCh].s[tIndex][nCountb] << pGRLOCAL->scaleFactScale; idx += (pGRLOCAL->arrSubBlockGain[tIndex] << 2); pDblRectArr[j] *= two_to_negative_half_pow[idx]; } else { // LONG block types 0,1,3 & 1st 2 subbands of switched blocks /* dbRectArr[sb][ss] *= pow(2.0, -0.5 * (1.0+pGRLOCAL->scaleFactScale) * (m_sCALEF[dwCh].l[nCountb] + pGRLOCAL->preflag * pretab[nCountb])); */ DWORD idx = m_sCALEF[dwCh].l[nCountb]; if (pGRLOCAL->preflag) idx += pretab[nCountb]; idx = idx << pGRLOCAL->scaleFactScale; pDblRectArr[j] *= two_to_negative_half_pow[idx]; } mIndex++; } int nIndexx = m_arrNonZero[dwCh]; ZeroMemory(pDblRectArr+nIndexx,sizeof(double)*(576-nIndexx)); return; } void CLayerIII::SubBands(double dbRectArr[32][18]) { // 32 bands 18 samples/band } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::Reorder(double dbRectArr[32][18], DWORD dwCh, DWORD dwGr) { DWORD dFreq, dFrew3; int mIndex; int nSfb, nSfbStart, nSfbLines; int mSrcLine, iDesLine; STR_GRINFO* pGRLOCAL = &(m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr]); double* pDblRectArr = &dbRectArr[0][0]; if (pGRLOCAL->wndSwitchFlag && (pGRLOCAL->nBlockType == 2)) { ZeroMemory(m_dOutArr,sizeof(m_dOutArr)); if (pGRLOCAL->mixedBlockFlag) { // NO REORDER FOR LOW 2 SUBBANDS CopyMemory(m_dOutArr,pDblRectArr,sizeof(double)*36); // REORDERING FOR REST SWITCHED SHORT for(nSfb=3,nSfbStart=sfBandIndex[m_nFreqIdx].s[3], nSfbLines=sfBandIndex[m_nFreqIdx].s[4] - nSfbStart; nSfb < 13; nSfb++,nSfbStart = sfBandIndex[m_nFreqIdx].s[nSfb], (nSfbLines=sfBandIndex[m_nFreqIdx].s[nSfb+1] - nSfbStart)) { int nSfbStart3 = (nSfbStart << 2) - nSfbStart; for(dFreq = 0, dFrew3 = 0; dFreq < (DWORD)nSfbLines; dFreq++, dFrew3 += 3) { mSrcLine = nSfbStart3 + dFreq; iDesLine = nSfbStart3 + dFrew3; m_dOutArr[iDesLine] = pDblRectArr[mSrcLine]; mSrcLine += nSfbLines; iDesLine++; m_dOutArr[iDesLine] = pDblRectArr[mSrcLine]; mSrcLine += nSfbLines; iDesLine++; m_dOutArr[iDesLine] = pDblRectArr[mSrcLine]; } } } else { mIndex = 0; while(mIndex<576) { m_dOutArr[mIndex] = pDblRectArr[reorder_table[m_nFreqIdx][mIndex++]]; } } } else { CopyMemory(m_dOutArr,pDblRectArr,32*18*sizeof(DOUBLE));//sizeof(m_dOutArr)); } } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::IStereoKValues(DWORD dwIsPos, DWORD dwIoType, DWORD dw) { if (dwIsPos == 0) { m_theKArray[0][dw] = 1.0f; m_theKArray[1][dw] = 1.0f; } else if (dwIsPos & 1) { m_theKArray[0][dw] = io[dwIoType][(dwIsPos + 1) >> 1]; m_theKArray[1][dw] = 1.0f; } else { m_theKArray[0][dw] = 1.0f; m_theKArray[1][dw] = io[dwIoType][dwIsPos >> 1]; } } /////////////////////////////////////////////////////////////////////////////// // int CLayerIII::Stereo(DWORD dwGr) { int sb, ss; if (m_nChanels == 1) { memcpy(m_cubeLr[0], m_cubeRo[0], sizeof(m_cubeLr[0][0][0]) * 18 * 32); /* for(ss=0; ss < 32; ss++) for(sb=0; sb < 18; sb+=3) { m_cubeLr[0][ss][sb] = m_cubeRo[0][ss][sb]; m_cubeLr[0][ss][sb+1] = m_cubeRo[0][ss][sb+1]; m_cubeLr[0][ss][sb+2] = m_cubeRo[0][ss][sb+2]; } */ } else { DWORD dwIsPos[576]; double dRatio[576]; STR_GRINFO *pGRLOCAL = &(m_SIDEINF.sArrCH[0].sArrGRINF[dwGr]); DWORD dwExtensionMode = m_dwExtensionMode; int nSfb; int dw = 0; int lines, temp, temp2; BOOL bStereoMs = (m_flMode == 1) && (dwExtensionMode & 0x2); BOOL bIStereo = (m_flMode == 1) && (dwExtensionMode & 0x1); BOOL bLayerVers = (m_version == 0); DWORD dwIoType = (pGRLOCAL->scaleFactCompress & 1); // initialization while(dw < 576) dwIsPos[dw++] = 7; if (bIStereo) { if (pGRLOCAL->wndSwitchFlag && (pGRLOCAL->nBlockType == 2)) { if (pGRLOCAL->mixedBlockFlag) { int iSfbMax = 0; for (DWORD j=0; j<3; j++) { int nSfbcnt = 2; for( nSfb=12; nSfb >=3; nSfb-- ) { dw = sfBandIndex[m_nFreqIdx].s[nSfb]; lines = sfBandIndex[m_nFreqIdx].s[nSfb+1] - dw; dw = (dw << 2) - dw + (j+1) * lines - 1; while (lines > 0) { if (m_cubeRo[1][ss_div[dw]][ss_mod[dw]] != 0.0f) { nSfbcnt = nSfb; nSfb = -10; lines = -10; } lines--; dw--; } } nSfb = nSfbcnt + 1; if (nSfb > iSfbMax) iSfbMax = nSfb; while(nSfb < 12) { temp = sfBandIndex[m_nFreqIdx].s[nSfb]; sb = sfBandIndex[m_nFreqIdx].s[nSfb+1] - temp; dw = (temp << 2) - temp + j * sb; for ( ; sb > 0; sb--) { dwIsPos[dw] = m_sCALEF[1].s[j][nSfb]; if (dwIsPos[dw] != 7) if (bLayerVers) IStereoKValues(dwIsPos[dw], dwIoType, dw); else dRatio[dw] = TAN12[dwIsPos[dw]]; dw++; } // for (; sb>0... nSfb++; } // while (nSfb < 12) nSfb = sfBandIndex[m_nFreqIdx].s[10]; sb = sfBandIndex[m_nFreqIdx].s[11] - nSfb; nSfb = (nSfb << 2) - nSfb + j * sb; temp = sfBandIndex[m_nFreqIdx].s[11]; sb = sfBandIndex[m_nFreqIdx].s[12] - temp; dw = (temp << 2) - temp + j * sb; for (; sb > 0; sb--) { dwIsPos[dw] = dwIsPos[nSfb]; if (bLayerVers) { m_theKArray[0][dw] = m_theKArray[0][nSfb]; m_theKArray[1][dw] = m_theKArray[1][nSfb]; } else { dRatio[dw] = dRatio[nSfb]; } dw++; } } if (iSfbMax <= 3) { dw = 2; ss = 17; sb = -1; while (dw >= 0) { if (m_cubeRo[1][dw][ss] != 0.0f) { sb = (dw<<4) + (dw<<1) + ss; dw = -1; } else { ss--; if (ss < 0) { dw--; ss = 17; } } } dw = 0; while (sfBandIndex[m_nFreqIdx].l[dw] <= sb) dw++; nSfb = dw; dw = sfBandIndex[m_nFreqIdx].l[dw]; for (; nSfb<8; nSfb++) { sb = sfBandIndex[m_nFreqIdx].l[nSfb+1] - sfBandIndex[m_nFreqIdx].l[nSfb]; for (; sb>0; sb--) { dwIsPos[dw] = m_sCALEF[1].l[nSfb]; if (dwIsPos[dw] != 7) { if (bLayerVers) IStereoKValues(dwIsPos[dw], dwIoType, dw); } else dRatio[dw] = TAN12[dwIsPos[dw]]; dw++; } } } } else { for (DWORD j=0; j<3; j++) { int nSfbcnt = -1; for( nSfb=12; nSfb >=0; nSfb-- ) { temp = sfBandIndex[m_nFreqIdx].s[nSfb]; lines = sfBandIndex[m_nFreqIdx].s[nSfb+1] - temp; dw = (temp << 2) - temp + (j+1) * lines - 1; while (lines > 0) { if (m_cubeRo[1][ss_div[dw]][ss_mod[dw]] != 0.0f) { nSfbcnt = nSfb; nSfb = -10; lines = -10; } lines--; dw--; } } nSfb = nSfbcnt + 1; while(nSfb<12) { temp = sfBandIndex[m_nFreqIdx].s[nSfb]; sb = sfBandIndex[m_nFreqIdx].s[nSfb+1] - temp; dw = (temp << 2) - temp + j * sb; for ( ; sb > 0; sb--) { dwIsPos[dw] = m_sCALEF[1].s[j][nSfb]; if (dwIsPos[dw] != 7) if (bLayerVers) IStereoKValues(dwIsPos[dw], dwIoType, dw); else dRatio[dw] = TAN12[dwIsPos[dw]]; dw++; } nSfb++; } // while (nSfb<12) temp = sfBandIndex[m_nFreqIdx].s[10]; temp2 = sfBandIndex[m_nFreqIdx].s[11]; sb = temp2 - temp; nSfb = (temp << 2) - temp + j * sb; sb = sfBandIndex[m_nFreqIdx].s[12] - temp2; dw = (temp2 << 2) - temp2 + j * sb; for (; sb>0; sb--) { dwIsPos[dw] = dwIsPos[nSfb]; if (bLayerVers) { m_theKArray[0][dw] = m_theKArray[0][nSfb]; m_theKArray[1][dw] = m_theKArray[1][nSfb]; } else { dRatio[dw] = dRatio[nSfb]; } dw++; } } } } else { // if (pGRLOCAL->wndSwitchFlag ... dw = 31; ss = 17; sb = 0; while (dw >= 0) { if (m_cubeRo[1][dw][ss] != 0.0f) { sb = (dw<<4) + (dw<<1) + ss; dw = -1; } else { ss--; if (ss < 0) { dw--; ss = 17; } } } dw = 0; while (sfBandIndex[m_nFreqIdx].l[dw] <= sb) dw++; nSfb = dw; dw = sfBandIndex[m_nFreqIdx].l[dw]; for (; nSfb<21; nSfb++) { sb = sfBandIndex[m_nFreqIdx].l[nSfb+1] - sfBandIndex[m_nFreqIdx].l[nSfb]; for (; sb > 0; sb--) { dwIsPos[dw] = m_sCALEF[1].l[nSfb]; if (dwIsPos[dw] != 7) if (bLayerVers) IStereoKValues(dwIsPos[dw], dwIoType, dw); else dRatio[dw] = TAN12[dwIsPos[dw]]; dw++; } } nSfb = sfBandIndex[m_nFreqIdx].l[20]; for (sb = 576 - sfBandIndex[m_nFreqIdx].l[21]; (sb > 0) && (dw<576); sb--) { dwIsPos[dw] = dwIsPos[nSfb]; // error here : dw >=576 if (bLayerVers) { m_theKArray[0][dw] = m_theKArray[0][nSfb]; m_theKArray[1][dw] = m_theKArray[1][nSfb]; } else { dRatio[dw] = dRatio[nSfb]; } dw++; } // if (pGRLOCAL->mixedBlockFlag) } // if (pGRLOCAL->wndSwitchFlag ... } // if (bIStereo) dw = 0; for(sb=0;sb<32;sb++) for(ss=0;ss<18;ss++) { if (dwIsPos[dw] == 7) { if (bStereoMs) { m_cubeLr[0][sb][ss] = (m_cubeRo[0][sb][ss]+ m_cubeRo[1][sb][ss]) * 0.707106781f; m_cubeLr[1][sb][ss] = (m_cubeRo[0][sb][ss]- m_cubeRo[1][sb][ss]) * 0.707106781f; } else { m_cubeLr[0][sb][ss] = m_cubeRo[0][sb][ss]; m_cubeLr[1][sb][ss] = m_cubeRo[1][sb][ss]; } } else if (bIStereo) { if (bLayerVers) { m_cubeLr[0][sb][ss] = m_cubeRo[0][sb][ss] * m_theKArray[0][dw]; m_cubeLr[1][sb][ss] = m_cubeRo[0][sb][ss] * m_theKArray[1][dw]; } else { m_cubeLr[1][sb][ss] = m_cubeRo[0][sb][ss] / (double) (1 + dRatio[dw]); m_cubeLr[0][sb][ss] = m_cubeLr[1][sb][ss] * dRatio[dw]; } } else { TRACE("Error Stereo processing"); ASSERT(0); } dw++; } } return 0; } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::AntiAlias(DWORD dwCh, DWORD dwGr) { int iSb18, ss, sb18lim; STR_GRINFO *pGRLOCAL = &(m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr]); // 31 alias-reduction operations between each pair of sub-bands // with 8 butterflies between each pair if (pGRLOCAL->wndSwitchFlag && (pGRLOCAL->nBlockType == 2) && !pGRLOCAL->mixedBlockFlag ) return; if (pGRLOCAL->wndSwitchFlag && pGRLOCAL->mixedBlockFlag && (pGRLOCAL->nBlockType == 2)) { sb18lim = 18; } else { sb18lim = 558; } for (iSb18=0; iSb18 < sb18lim; iSb18+=18) { for (ss=0;ss<8;ss++) { int iDx1 = iSb18 + 17 - ss; int iDx2 = iSb18 + 18 + ss; double dBu = m_dOutArr[iDx1]; double dBd = m_dOutArr[iDx2]; m_dOutArr[iDx1] = (dBu * cs[ss]) - (dBd * ca[ss]); m_dOutArr[iDx2] = (dBd * cs[ss]) + (dBu * ca[ss]); } } } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::Hibrid(DWORD dwCh, DWORD dwGr) { double dOurRaw[36]; DWORD dwBt PURE; int iSb18 PURE; double* pdTsOut PURE; double* pdPrvBlok PURE; STR_GRINFO* pGRLOCAL = &(m_SIDEINF.sArrCH[dwCh].sArrGRINF[dwGr]); for(iSb18=0; iSb18<576; iSb18+=18) { dwBt = (pGRLOCAL->wndSwitchFlag && pGRLOCAL->mixedBlockFlag && (iSb18 < 36)) ? 0 : pGRLOCAL->nBlockType; pdTsOut = m_dOutArr + iSb18; InvMdcdt(pdTsOut, dOurRaw, dwBt); pdPrvBlok = &m_PreBlkArr[dwCh][iSb18]; pdTsOut[0] = dOurRaw[0] + pdPrvBlok[0]; pdPrvBlok[0] = dOurRaw[18]; pdTsOut[1] = dOurRaw[1] + pdPrvBlok[1]; pdPrvBlok[1] = dOurRaw[19]; pdTsOut[2] = dOurRaw[2] + pdPrvBlok[2]; pdPrvBlok[2] = dOurRaw[20]; pdTsOut[3] = dOurRaw[3] + pdPrvBlok[3]; pdPrvBlok[3] = dOurRaw[21]; pdTsOut[4] = dOurRaw[4] + pdPrvBlok[4]; pdPrvBlok[4] = dOurRaw[22]; pdTsOut[5] = dOurRaw[5] + pdPrvBlok[5]; pdPrvBlok[5] = dOurRaw[23]; pdTsOut[6] = dOurRaw[6] + pdPrvBlok[6]; pdPrvBlok[6] = dOurRaw[24]; pdTsOut[7] = dOurRaw[7] + pdPrvBlok[7]; pdPrvBlok[7] = dOurRaw[25]; pdTsOut[8] = dOurRaw[8] + pdPrvBlok[8]; pdPrvBlok[8] = dOurRaw[26]; pdTsOut[9] = dOurRaw[9] + pdPrvBlok[9]; pdPrvBlok[9] = dOurRaw[27]; pdTsOut[10] = dOurRaw[10] + pdPrvBlok[10]; pdPrvBlok[10] = dOurRaw[28]; pdTsOut[11] = dOurRaw[11] + pdPrvBlok[11]; pdPrvBlok[11] = dOurRaw[29]; pdTsOut[12] = dOurRaw[12] + pdPrvBlok[12]; pdPrvBlok[12] = dOurRaw[30]; pdTsOut[13] = dOurRaw[13] + pdPrvBlok[13]; pdPrvBlok[13] = dOurRaw[31]; pdTsOut[14] = dOurRaw[14] + pdPrvBlok[14]; pdPrvBlok[14] = dOurRaw[32]; pdTsOut[15] = dOurRaw[15] + pdPrvBlok[15]; pdPrvBlok[15] = dOurRaw[33]; pdTsOut[16] = dOurRaw[16] + pdPrvBlok[16]; pdPrvBlok[16] = dOurRaw[34]; pdTsOut[17] = dOurRaw[17] + pdPrvBlok[17]; pdPrvBlok[17] = dOurRaw[35]; } } void CLayerIII::InvMdcdt(double *pDblIn, double *pDblOut, int nBlockType) { double tmp[18]; double *win_bt; int dw; if(nBlockType == 2) { /* for(int p=0;p<36;p+=9) { pDblOut[p] = pDblOut[p+1] = pDblOut[p+2] = pDblOut[p+3] = pDblOut[p+4] = pDblOut[p+5] = pDblOut[p+6] = pDblOut[p+7] = pDblOut[p+8] = 0.0f; } */ ZeroMemory(pDblOut,sizeof(double)*36); int six_i = 0; for(dw=0;dw<3;dw++) { // 12 point IMDCT // Begin 12 point IDCT // Input aliasing for 12 pt IDCT pDblIn[15+dw] += pDblIn[12+dw]; pDblIn[12+dw] += pDblIn[9+dw]; pDblIn[9+dw] += pDblIn[6+dw]; pDblIn[6+dw] += pDblIn[3+dw]; pDblIn[3+dw] += pDblIn[0+dw]; // Input aliasing on odd indices (for 6 point IDCT) pDblIn[15+dw] += pDblIn[9+dw]; pDblIn[9+dw] += pDblIn[3+dw]; // 3 point IDCT on even indices { double pp1, pp2, sum; pp2 = pDblIn[12+dw] * 0.500000000f; pp1 = pDblIn[ 6+dw] * 0.866025403f; sum = pDblIn[0+dw] + pp2; tmp[1] = pDblIn[0+dw] - pDblIn[12+dw]; tmp[0] = sum + pp1; tmp[2] = sum - pp1; // End 3 point IDCT on even indices // 3 point IDCT on odd indices (for 6 point IDCT) pp2 = pDblIn[15+dw] * 0.500000000f; pp1 = pDblIn[ 9+dw] * 0.866025403f; sum = pDblIn[ 3+dw] + pp2; tmp[4] = pDblIn[3+dw] - pDblIn[15+dw]; tmp[5] = sum + pp1; tmp[3] = sum - pp1; } // End 3 point IDCT on odd indices // Twiddle factors on odd indices (for 6 point IDCT) tmp[3] *= 1.931851653f; tmp[4] *= 0.707106781f; tmp[5] *= 0.517638090f; // Output butterflies on 2 3 point IDCT's (for 6 point IDCT) { double save = tmp[0]; tmp[0] += tmp[5]; tmp[5] = save - tmp[5]; save = tmp[1]; tmp[1] += tmp[4]; tmp[4] = save - tmp[4]; save = tmp[2]; tmp[2] += tmp[3]; tmp[3] = save - tmp[3]; } // End 6 point IDCT // Twiddle factors on indices (for 12 point IDCT) tmp[0] *= 0.504314480f; tmp[1] *= 0.541196100f; tmp[2] *= 0.630236207f; tmp[3] *= 0.821339815f; tmp[4] *= 1.306562965f; tmp[5] *= 3.830648788f; // End 12 point IDCT // Shift to 12 point modified IDCT, multiply by nWnd type 2 tmp[8] = -tmp[0] * 0.793353340f; tmp[9] = -tmp[0] * 0.608761429f; tmp[7] = -tmp[1] * 0.923879532f; tmp[10] = -tmp[1] * 0.382683432f; tmp[6] = -tmp[2] * 0.991444861f; tmp[11] = -tmp[2] * 0.130526192f; tmp[0] = tmp[3]; tmp[1] = tmp[4] * 0.382683432f; tmp[2] = tmp[5] * 0.608761429f; tmp[3] = -tmp[5] * 0.793353340f; tmp[4] = -tmp[4] * 0.923879532f; tmp[5] = -tmp[0] * 0.991444861f; tmp[0] *= 0.130526192f; pDblOut[six_i + 6] += tmp[0]; pDblOut[six_i + 7] += tmp[1]; pDblOut[six_i + 8] += tmp[2]; pDblOut[six_i + 9] += tmp[3]; pDblOut[six_i + 10] += tmp[4]; pDblOut[six_i + 11] += tmp[5]; pDblOut[six_i + 12] += tmp[6]; pDblOut[six_i + 13] += tmp[7]; pDblOut[six_i + 14] += tmp[8]; pDblOut[six_i + 15] += tmp[9]; pDblOut[six_i + 16] += tmp[10]; pDblOut[six_i + 17] += tmp[11]; six_i += 6; } } else { // 36 point IDCT // input aliasing for 36 point IDCT pDblIn[17]+=pDblIn[16]; pDblIn[16]+=pDblIn[15]; pDblIn[15]+=pDblIn[14]; pDblIn[14]+=pDblIn[13]; pDblIn[13]+=pDblIn[12]; pDblIn[12]+=pDblIn[11]; pDblIn[11]+=pDblIn[10]; pDblIn[10]+=pDblIn[9]; pDblIn[9] +=pDblIn[8]; pDblIn[8] +=pDblIn[7]; pDblIn[7] +=pDblIn[6]; pDblIn[6] +=pDblIn[5]; pDblIn[5] +=pDblIn[4]; pDblIn[4] +=pDblIn[3]; pDblIn[3] +=pDblIn[2]; pDblIn[2] +=pDblIn[1]; pDblIn[1] +=pDblIn[0]; // 18 point IDCT for odd indices // input aliasing for 18 point IDCT pDblIn[17]+=pDblIn[15]; pDblIn[15]+=pDblIn[13]; pDblIn[13]+=pDblIn[11]; pDblIn[11]+=pDblIn[9]; pDblIn[9] +=pDblIn[7]; pDblIn[7] +=pDblIn[5]; pDblIn[5] +=pDblIn[3]; pDblIn[3] +=pDblIn[1]; { double tmp0,tmp1,tmp2,tmp3,tmp4,tmp0_,tmp1_,tmp2_,tmp3_; double tmp0o,tmp1o,tmp2o,tmp3o,tmp4o,tmp0_o,tmp1_o,tmp2_o,tmp3_o; // Fast 9 Point Inverse Discrete Cosine Transform // // By Francois-Raymond Boyer // mailto:boyerf@iro.umontdouble.ca // http://www.iro.umontdouble.ca/~boyerf // // The code has been optimized for Intel processors // (takes a lot of time to convert float to and from iternal FPU representation) // // It is a simple "factorization" of the IDCT matrix. // 9 point IDCT on even indices { // 5 points on odd indices (not doubley an IDCT) double i0 = pDblIn[0]+pDblIn[0]; double i0p12 = i0 + pDblIn[12]; tmp0 = i0p12 + pDblIn[4]*1.8793852415718f + pDblIn[8]*1.532088886238f + pDblIn[16]*0.34729635533386f; tmp1 = i0 + pDblIn[4] - pDblIn[8] - pDblIn[12] - pDblIn[12] - pDblIn[16]; tmp2 = i0p12 - pDblIn[4]*0.34729635533386f - pDblIn[8]*1.8793852415718f + pDblIn[16]*1.532088886238f; tmp3 = i0p12 - pDblIn[4]*1.532088886238f + pDblIn[8]*0.34729635533386f - pDblIn[16]*1.8793852415718f; tmp4 = pDblIn[0] - pDblIn[4] + pDblIn[8] - pDblIn[12] + pDblIn[16]; // 4 points on even indices double i6_ = pDblIn[6]*1.732050808f; // Sqrt[3] tmp0_ = pDblIn[2]*1.9696155060244f + i6_ + pDblIn[10]*1.2855752193731f + pDblIn[14]*0.68404028665134f; tmp1_ = (pDblIn[2] - pDblIn[10] - pDblIn[14])*1.732050808f; tmp2_ = pDblIn[2]*1.2855752193731f - i6_ - pDblIn[10]*0.68404028665134f + pDblIn[14]*1.9696155060244f; tmp3_ = pDblIn[2]*0.68404028665134f - i6_ + pDblIn[10]*1.9696155060244f - pDblIn[14]*1.2855752193731f; } // 9 point IDCT on odd indices { // 5 points on odd indices (not doubley an IDCT) double i0 = pDblIn[0+1]+pDblIn[0+1]; double i0p12 = i0 + pDblIn[12+1]; tmp0o = i0p12 + pDblIn[4+1]*1.8793852415718f + pDblIn[8+1]*1.532088886238f + pDblIn[16+1]*0.34729635533386f; tmp1o = i0 + pDblIn[4+1] - pDblIn[8+1] - pDblIn[12+1] - pDblIn[12+1] - pDblIn[16+1]; tmp2o = i0p12 - pDblIn[4+1]*0.34729635533386f - pDblIn[8+1]*1.8793852415718f + pDblIn[16+1]*1.532088886238f; tmp3o = i0p12 - pDblIn[4+1]*1.532088886238f + pDblIn[8+1]*0.34729635533386f - pDblIn[16+1]*1.8793852415718f; tmp4o = (pDblIn[0+1] - pDblIn[4+1] + pDblIn[8+1] - pDblIn[12+1] + pDblIn[16+1])*0.707106781f; // Twiddled // 4 points on even indices double i6_ = pDblIn[6+1]*1.732050808f; // Sqrt[3] tmp0_o = pDblIn[2+1]*1.9696155060244f + i6_ + pDblIn[10+1]*1.2855752193731f + pDblIn[14+1]*0.68404028665134f; tmp1_o = (pDblIn[2+1] - pDblIn[10+1] - pDblIn[14+1])*1.732050808f; tmp2_o = pDblIn[2+1]*1.2855752193731f - i6_ - pDblIn[10+1]*0.68404028665134f + pDblIn[14+1]*1.9696155060244f; tmp3_o = pDblIn[2+1]*0.68404028665134f - i6_ + pDblIn[10+1]*1.9696155060244f - pDblIn[14+1]*1.2855752193731f; } // Twiddle factors on odd indices // and // Butterflies on 9 point IDCT's // and // twiddle factors for 36 point IDCT double e, o; e = tmp0 + tmp0_; o = (tmp0o + tmp0_o)*0.501909918f; tmp[0] = e + o; tmp[17] = e - o; e = tmp1 + tmp1_; o = (tmp1o + tmp1_o)*0.517638090f; tmp[1] = e + o; tmp[16] = e - o; e = tmp2 + tmp2_; o = (tmp2o + tmp2_o)*0.551688959f; tmp[2] = e + o; tmp[15] = e - o; e = tmp3 + tmp3_; o = (tmp3o + tmp3_o)*0.610387294f; tmp[3] = e + o; tmp[14] = e - o; tmp[4] = tmp4 + tmp4o; tmp[13] = tmp4 - tmp4o; e = tmp3 - tmp3_; o = (tmp3o - tmp3_o)*0.871723397f; tmp[5] = e + o; tmp[12] = e - o; e = tmp2 - tmp2_; o = (tmp2o - tmp2_o)*1.183100792f; tmp[6] = e + o; tmp[11] = e - o; e = tmp1 - tmp1_; o = (tmp1o - tmp1_o)*1.931851653f; tmp[7] = e + o; tmp[10] = e - o; e = tmp0 - tmp0_; o = (tmp0o - tmp0_o)*5.736856623f; tmp[8] = e + o; tmp[9] = e - o; } // end 36 point IDCT */ // shift to modified IDCT win_bt = dblWin[nBlockType]; pDblOut[0] =-tmp[9] * win_bt[0]; pDblOut[1] =-tmp[10] * win_bt[1]; pDblOut[2] =-tmp[11] * win_bt[2]; pDblOut[3] =-tmp[12] * win_bt[3]; pDblOut[4] =-tmp[13] * win_bt[4]; pDblOut[5] =-tmp[14] * win_bt[5]; pDblOut[6] =-tmp[15] * win_bt[6]; pDblOut[7] =-tmp[16] * win_bt[7]; pDblOut[8] =-tmp[17] * win_bt[8]; pDblOut[9] = tmp[17] * win_bt[9]; pDblOut[10]= tmp[16] * win_bt[10]; pDblOut[11]= tmp[15] * win_bt[11]; pDblOut[12]= tmp[14] * win_bt[12]; pDblOut[13]= tmp[13] * win_bt[13]; pDblOut[14]= tmp[12] * win_bt[14]; pDblOut[15]= tmp[11] * win_bt[15]; pDblOut[16]= tmp[10] * win_bt[16]; pDblOut[17]= tmp[9] * win_bt[17]; pDblOut[18]= tmp[8] * win_bt[18]; pDblOut[19]= tmp[7] * win_bt[19]; pDblOut[20]= tmp[6] * win_bt[20]; pDblOut[21]= tmp[5] * win_bt[21]; pDblOut[22]= tmp[4] * win_bt[22]; pDblOut[23]= tmp[3] * win_bt[23]; pDblOut[24]= tmp[2] * win_bt[24]; pDblOut[25]= tmp[1] * win_bt[25]; pDblOut[26]= tmp[0] * win_bt[26]; pDblOut[27]= tmp[0] * win_bt[27]; pDblOut[28]= tmp[1] * win_bt[28]; pDblOut[29]= tmp[2] * win_bt[29]; pDblOut[30]= tmp[3] * win_bt[30]; pDblOut[31]= tmp[4] * win_bt[31]; pDblOut[32]= tmp[5] * win_bt[32]; pDblOut[33]= tmp[6] * win_bt[33]; pDblOut[34]= tmp[7] * win_bt[34]; pDblOut[35]= tmp[8] * win_bt[35]; } } DWORD CLayerIII::Bits(int nBits) { DWORD dwRetVal = 0; DWORD nSumBits = m_nBitsOffset + nBits; // update the bits index DWORD dwMask = 0xFFFFFFFF >> (32 - nBits ); // build the mask DWORD* ptoDW = (DWORD*)m_pbyWalk; DWORD dwValue = *ptoDW; // extract the pointed value if (nSumBits <= 32) { dwRetVal = (dwValue >> (32 - nSumBits)) & dwMask; if ((m_nBitsOffset += nBits) == 32) { m_nBitsOffset = 0; m_pbyWalk+=4; } } else { // walk half a long and get them dwRetVal = MAKELONG(HIWORD(*(ptoDW+1)),LOWORD(*(ptoDW))); m_pbyWalk+=4; m_nBitsOffset = nSumBits - 32; dwRetVal >>= 48 - nSumBits; dwRetVal &= dwMask; } return dwRetVal; } int CLayerIII::HuffmanDec(sHUFDECTAB *h, int *x, int *y, int *v, int *w) { DWORD level; int point = 0; int error = 1; level = 0x80000000; if (h->val == NULL) return 2; /* table 0 needs no bits */ if ( h->treelen == 0) { *x = *y = 0; return 0; } /* Lookup in Huffman table. */ do { if (h->val[point][0]==0) { /*end of tree*/ *x = h->val[point][1] >> 4; *y = h->val[point][1] & 0xf; error = 0; break; } if (GetFastOneBit()) { while (h->val[point][1] >= 250) point += h->val[point][1]; point += h->val[point][1]; } else { while (h->val[point][0] >= 250) point += h->val[point][0]; point += h->val[point][0]; } level >>= 1; } while (level || (point < (int)ht->treelen) ); // Check for error. /* if (error) { // set x and y to a medium value as a simple concealment printf("Illegal Huffman code in data.\n"); *x = (h->xlen-1 << 1); *y = (h->ylen-1 << 1); } */ /* Process sign encodings for quadruples tables. */ if (h->tablename[0] == '3' && (h->tablename[1] == '2' || h->tablename[1] == '3')) { *v = (*y>>3) & 1; *w = (*y>>2) & 1; *x = (*y>>1) & 1; *y = *y & 1; /* v, w, x and y are reversed in the bitstream. switch them around to make test bistream work. */ if (*v) if (GetFastOneBit()) *v = -*v; if (*w) if (GetFastOneBit()) *w = -*w; if (*x) if (GetFastOneBit()) *x = -*x; if (*y) if (GetFastOneBit()) *y = -*y; } else { // Process sign and escape encodings for dual tables. // x and y are reversed in the test bitstream. // Reverse x and y here to make test bitstream work. if (h->linbits) if ((h->xlen-1) == (DWORD)*x) *x += GetBits(h->linbits); if (*x) if (GetFastOneBit()) *x = -*x; if (h->linbits) if ((h->ylen-1) == (DWORD)*y) *y += GetBits(h->linbits); if (*y) if (GetFastOneBit()) *y = -*y; } return error; } ////////////////////////////////////////////////////////////////////////////////////// // the dbScale scales the calculated float pcm m_tdbSubSamples to short values // (raw pcm m_tdbSubSamples are in [-1.0, 1.0], if no violations occur) SynthesisFilter::SynthesisFilter(DWORD nChn):m_nCan(nChn),m_countIn(0),m_lastband(-1) { Reset(); } ////////////////////////////////////////////////////////////////////////////////////// // void SynthesisFilter::Reset() { ZeroMemory(m_tableA,sizeof(m_tableA)); ZeroMemory(m_tableB,sizeof(m_tableB)); ZeroMemory(m_tdbSubSamples,sizeof(m_tdbSubSamples)); m_pToTable = m_tableA; m_nWriteIndex = 15; for(int i=0;i<40;i++) m_gain[i]=1.0f; } ////////////////////////////////////////////////////////////////////////////////////// // Eliminated the old kilometric asignments lists (we have fast computers now) // void SynthesisFilter::CompNewTable() { // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 double tdbNewTbl[32]; double dbTemp1[16]; double dbTmp2[16]; int j = 0; double *pDbl1 = m_tdbSubSamples; while(j<16) { dbTemp1[j] = pDbl1[j] + pDbl1[31-j]; j++; } j = 0; while(j<8) { dbTmp2[j] = dbTemp1[j] + dbTemp1[15-j]; j++; } while(j<16) { dbTmp2[j] = (dbTemp1[j-8] - dbTemp1[23-j]) * dbCosTable[j+8]; j++; } for(j = 0 ; j< 4 ;j++) { dbTemp1[j] = dbTmp2[j] + dbTmp2[7-j]; dbTemp1[j+8] = dbTmp2[j+8] + dbTmp2[15-j]; dbTemp1[j+4] = (dbTmp2[j] - dbTmp2[7-j]) * dbCosTable[24+j]; dbTemp1[j+12] = (dbTmp2[j+8] - dbTmp2[15-j]) * dbCosTable[24+j];// cos1_16; } for(j = 0 ; j < 2 ;j++) { dbTmp2[j] = dbTemp1[j] + dbTemp1[3-j]; dbTmp2[4+j] = dbTemp1[4+j] + dbTemp1[7-j]; dbTmp2[8+j] = dbTemp1[8+j] + dbTemp1[11-j]; dbTmp2[12+j] = dbTemp1[12+j] + dbTemp1[15-j]; dbTmp2[2+j] = (dbTemp1[j] - dbTemp1[3-j]) * dbCosTable[28+j];//cos1_8; dbTmp2[6+j] = (dbTemp1[4+j] - dbTemp1[7-j]) * dbCosTable[28+j]; dbTmp2[10+j] = (dbTemp1[8+j] - dbTemp1[11-j]) * dbCosTable[28+j]; dbTmp2[14+j] = (dbTemp1[12+j] - dbTemp1[15-j]) * dbCosTable[28+j]; } for(j = 0; j < 16 ;j+=2) { dbTemp1[j] = dbTmp2[j] + dbTmp2[j+1]; dbTemp1[j+1] = (dbTmp2[j] - dbTmp2[j+1]) * dbCosTable[30]; } double dbTEmp; tdbNewTbl[19] = -(tdbNewTbl[4] = (tdbNewTbl[12] = dbTemp1[7]) + dbTemp1[5]) - dbTemp1[6]; tdbNewTbl[27] = -dbTemp1[6] - dbTemp1[7] - dbTemp1[4]; tdbNewTbl[6] = (tdbNewTbl[10] = (tdbNewTbl[14] = dbTemp1[15]) + dbTemp1[11]) + dbTemp1[13]; tdbNewTbl[17] = -(tdbNewTbl[2] = dbTemp1[15] + dbTemp1[13] + dbTemp1[9]) - dbTemp1[14]; tdbNewTbl[21] = (dbTEmp = -dbTemp1[14] - dbTemp1[15] - dbTemp1[10] - dbTemp1[11]) - dbTemp1[13]; tdbNewTbl[29] = -dbTemp1[14] - dbTemp1[15] - dbTemp1[12] - dbTemp1[8]; tdbNewTbl[25] = dbTEmp - dbTemp1[12]; tdbNewTbl[31] = -dbTemp1[0]; tdbNewTbl[0] = dbTemp1[1]; tdbNewTbl[23] = -(tdbNewTbl[8] = dbTemp1[3]) - dbTemp1[2]; pDbl1 = m_tdbSubSamples; for(j = 0 ;j < 16 ; j++) { dbTemp1[j] = (pDbl1[j] - pDbl1[31-j]) * dbCosTable[j]; } for(j = 0 ;j < 8 ; j++) { dbTmp2[j] = dbTemp1[j] + dbTemp1[15-j]; dbTmp2[j+8] = (dbTemp1[j] - dbTemp1[15-j]) * dbCosTable[j+16]; } for(j = 0 ;j < 4 ; j++) { dbTemp1[j] = dbTmp2[j] + dbTmp2[7-j]; dbTemp1[8+j] = dbTmp2[8+j] + dbTmp2[15-j]; dbTemp1[4+j] = (dbTmp2[j] - dbTmp2[7-j]) * dbCosTable[j+24]; dbTemp1[12+j] = (dbTmp2[8+j] - dbTmp2[15-j]) * dbCosTable[j+24]; } for(j = 0 ; j < 2 ;j++) { dbTmp2[j] = dbTemp1[j] + dbTemp1[3-j]; dbTmp2[4+j] = dbTemp1[4+j] + dbTemp1[7-j]; dbTmp2[8+j] = dbTemp1[8+j] + dbTemp1[11-j]; dbTmp2[12+j] = dbTemp1[12+j] + dbTemp1[15-j]; dbTmp2[2+j] = (dbTemp1[j] - dbTemp1[3-j]) * dbCosTable[28+j];//cos1_8; dbTmp2[6+j] = (dbTemp1[4+j] - dbTemp1[7-j]) * dbCosTable[28+j]; dbTmp2[10+j] = (dbTemp1[8+j] - dbTemp1[11-j]) * dbCosTable[28+j]; dbTmp2[14+j] = (dbTemp1[12+j] - dbTemp1[15-j]) * dbCosTable[28+j]; } for(j = 0; j < 16 ;j+=2) { dbTemp1[j] = dbTmp2[j] + dbTmp2[j+1]; dbTemp1[j+1] = (dbTmp2[j] - dbTmp2[j+1]) * dbCosTable[30]; } // manually doing something that a compiler should handle sucks // coding like this is hard to read double dbDbTmp2Val; tdbNewTbl[5] = (tdbNewTbl[11] = (tdbNewTbl[13] = (tdbNewTbl[15] = dbTemp1[15]) + dbTemp1[7]) + dbTemp1[11]) + dbTemp1[5] + dbTemp1[13]; tdbNewTbl[7] = (tdbNewTbl[9] = dbTemp1[15] + dbTemp1[11] + dbTemp1[3]) + dbTemp1[13]; tdbNewTbl[16] = -(tdbNewTbl[1] = (dbTEmp = dbTemp1[13] + dbTemp1[15] + dbTemp1[9]) + dbTemp1[1]) - dbTemp1[14]; tdbNewTbl[18] = -(tdbNewTbl[3] = dbTEmp + dbTemp1[5] + dbTemp1[7]) - dbTemp1[6] - dbTemp1[14]; tdbNewTbl[22] = (dbTEmp = -dbTemp1[10] - dbTemp1[11] - dbTemp1[14] - dbTemp1[15]) - dbTemp1[13] - dbTemp1[2] - dbTemp1[3]; tdbNewTbl[20] = dbTEmp - dbTemp1[13] - dbTemp1[5] - dbTemp1[6] - dbTemp1[7]; tdbNewTbl[24] = dbTEmp - dbTemp1[12] - dbTemp1[2] - dbTemp1[3]; tdbNewTbl[26] = dbTEmp - dbTemp1[12] - (dbDbTmp2Val = dbTemp1[4] + dbTemp1[6] + dbTemp1[7]); tdbNewTbl[30] = (dbTEmp = -dbTemp1[8] - dbTemp1[12] - dbTemp1[14] - dbTemp1[15]) - dbTemp1[0]; tdbNewTbl[28] = dbTEmp - dbDbTmp2Val; // insert V[0-15] (== tdbNewTbl[0-15]) into actual v: double *pDblA = tdbNewTbl; double *pDblB = m_pToTable + m_nWriteIndex; for(j=0;j<16;j++) pDblB[j*16] = pDblA[j]; pDblB[256] = 0.0f; for(j=1;j<16;j++) { pDblB[256+(16*j)] = -pDblA[16-j]; } pDblB = (m_pToTable == m_tableA ? m_tableB : m_tableA) + m_nWriteIndex; pDblB[0] = -pDblA[0]; for(j=1;j < 17;j++) pDblB[j*16] = pDblA[j+15]; // insert V[49-63] (== tdbNewTbl[30-16]) into other v: for(j=1;j<16;j++) { pDblB[256+(16*j)] = pDblA[31-j]; } } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::GoBackBits(int nBits) { m_PlayedBits -= nBits; m_restBits += nBits; while(m_restBits >= 8) { m_restBits -= 8; m_playedOctets--; } } /////////////////////////////////////////////////////////////////////////////// // void CLayerIII::GoBackOctets(int nOctets) { m_PlayedBits -= (nOctets*8); m_playedOctets -= nOctets; } /////////////////////////////////////////////////////////////////////////////// // // DWORD CLayerIII::GetBits(DWORD nBits) { m_PlayedBits += nBits; DWORD dwRetVal = 0; int contor = nBits; while (contor > 0) { if (m_restBits == 0) { m_restBits = 8; m_playedOctets++; } int minBidx = min((int)m_restBits,contor); DWORD xmask = 0xFFFFFFFF >> (32 - m_restBits); int tempVal = m_pDwBuff[m_playedOctets & 0xfff]; tempVal&= xmask; m_restBits -= minBidx; tempVal = tempVal >> m_restBits; contor -= minBidx; dwRetVal |= tempVal << contor; } return dwRetVal; }