📄 layeriii.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "LayerIII.h"
#include <math.h>
/////////////////////////////////////////////////////////////////////////////
//
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<PFN>(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<nChanels; dwCh++)
{
pToCel = &m_SIDEINF.sArrCH[dwCh].sArrGRINF[0];
pToCel->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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -