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

📄 layeriii.cpp

📁 完整的MP3播放器源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////

#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 + -