www.pudn.com > VC写的MP3播放器源代码.zip > LayerIII.h


//	LayerIII.h : Declaration of the CLayerIII 
//	See Readme.txt 
// 
// 
////////////////////////////////////////////////////////////////////////////// 
#ifndef __LAYERIII_H_ 
#define __LAYERIII_H_ 
 
#include "resource.h"       // main symbols 
#include "datatables.h"		// PROM DATA 
 
 
#define EIGHTEEN 18 
#define SBLIMIT 32 
#define BUFSIZE 4096 
 
// call back in the main thread for each sample Marius C. 
typedef unsigned long (*PFN)(double* pSample,double* spec ,int nChannel); 
 
/////////////////////////////////////////////////////////////////////////////// 
// 
//       
class SynthesisFilter 
{ 
   
public: 
	 
	SynthesisFilter(DWORD nChn); 
 
	int	PrepPCMSampleX(BYTE *pMciBuff,int& samples,int& nOffset, 
						PFN pFn = 0,void* pData = 0); 
 
	// triger (bad limitation) of overlimit samples 
   	_inline WORD Clip(double dbSamlpe) 
	{ 
	  return ((dbSamlpe > 32767.0f) ? 32767 : 
	         ((dbSamlpe < -32768.0f) ? -32768 : 
			 (WORD) dbSamlpe)); 
	} 
 
 
	_inline double	InSample(double dbSamlpe, DWORD nSubBand) 
	{  
		 
//int	m_countIn; 
//int m_lastband; 
		m_tdbSubSamples[nSubBand] = dbSamlpe * m_gain[nSubBand];   
 
		// Marius C 
		if(dbSamlpe < 0.0f) 
			return (dbSamlpe*-1.0); 
		return dbSamlpe; 
    }; 
 
 
	// Marius C 
    _inline void SetGain(double byGain,int idx) 
	{ 
		switch(idx) 
        { 
            case 0: 
            case 1: 
            case 2: 
            case 3: 
            case 4: 
            case 5: 
            case 6: 
            case 7: 
                m_gain[idx]= byGain;		 
                break; 
            case 8: 
                m_gain[8]= byGain;		 
                m_gain[9]= byGain;		 
                m_gain[10]= byGain;		 
                 
                break; 
            case 9: 
                m_gain[11]= byGain;		 
                m_gain[12]= byGain;		 
                m_gain[13]= byGain;		 
                m_gain[14]= byGain;		 
                break; 
            case 10: 
                m_gain[15]= byGain;		 
                m_gain[16]= byGain;		 
                m_gain[17]= byGain;		 
                m_gain[18]= byGain;		 
                m_gain[19]= byGain;		 
                m_gain[20]= byGain;		 
                 
                break; 
            case 11: 
                m_gain[21]= byGain;		 
                m_gain[22]= byGain;		 
                m_gain[23]= byGain;		 
                m_gain[24]= byGain;		 
                m_gain[25]= byGain;		 
                m_gain[26]= byGain;		 
                m_gain[27]= byGain;		 
                m_gain[28]= byGain;		 
                m_gain[29]= byGain;		 
                m_gain[30]= byGain;		 
                m_gain[31]= byGain;		 
 
                break; 
 
        } 
         
	} 
 
    void	Reset(); 
//// 
private: 
	 
	// Marius C 
	_inline void Append(int channel, int& offset,int& samples ,double dblv,WORD* pBuff) 
	{ 
		pBuff[channel + (offset<<1)] = Clip(dblv); 
		offset++; 
		samples++; 
 
	} 
	 
	void	CompNewTable(); 
private: 
 
	double	m_tableA[512], m_tableB[512]; 
	double	m_tdbSubSamples[32];			// 32 new subband m_tdbSubSamples 
	double*	m_pToTable;			 
	DWORD	m_nWriteIndex;					// 0-15 
	DWORD	m_nCan; 
    double	m_gain[40]; 
 
	int	m_countIn; 
	int m_lastband; 
 
}; 
 
///////////////////////////////////////////////////////////////////////////// 
// CLayerIII 
// 
class CLayerIII 
{ 
 
public: 
	 
	void	Reset(); 
	BOOL	DecodeBlock(BYTE* pVarIn, DWORD nLength,  
						BYTE* pvOut, DWORD* outLevel, 
                            DWORD mpVersion, 
                            DWORD nMode, 
                            DWORD freqIdx, 
                            DWORD modeExtension); 
	BOOL	Init(	DWORD mpVersion, 
                    DWORD nMode, 
					DWORD modeExtension,  
                    DWORD freqIdx,  
					long pFnCallBack = 0); 
 
    void SetGain(double byGain,int idx) 
	{ 
		if(m_pFilterX == 0 ) 
			return; 
 
		m_pFilterX->SetGain(byGain, idx); 
		m_pFilterY->SetGain(byGain, idx); 
 
	} 
 
 
    CLayerIII():m_pfnCallback(0), 
	m_offset(0), 
	m_PlayedBits(0), 
	m_playedOctets(0), 
	m_restBits(8), 
	m_InWordAcumulated(0), 
	m_pDwBuff(0) 
	{ 
		// Marius C 
			VERIFY(m_pDwBuff = new DWORD[BUFSIZE]); 
	} 
 
	~CLayerIII() 
	{ 
		delete[] m_pDwBuff; 
	    delete m_pFilterX; 
		delete m_pFilterY; 
		m_pFilterX = 0; 
		m_pFilterY = 0; 
//        TRACE("~CLayerIII()\r\n"); 
	} 
 
 
// ILayerIII 
private: 
    	typedef	struct { 
			int p23Len; 
			int bigVal; 
			int glbGain; 
			int scaleFactCompress; 
			int wndSwitchFlag; 
			int nBlockType; 
			int mixedBlockFlag; 
			int arrSelect[3]; 
			int arrSubBlockGain[3]; 
			int region0Count; 
			int region1Count; 
			int preflag; 
			int scaleFactScale; 
			int countTblSelect; 
		} STR_GRINFO; 
 
	typedef struct { 
			  int l[23];            // [cb]  
           int s[3][13];			// [window][cb]  
		  } STR_3SCALEFACT[2]; 
 
	typedef struct { 
		  int dataMainStart; 
 		  int privBits; 
 		  struct  
		  { 
			  int arrScfSi[4]; 
			  STR_GRINFO sArrGRINF[2]; 
		  } sArrCH[2]; 
	  } STR_3SIDEINFO; 
 
 
 
private: 
    void    ResolveChannels(int nMode); 
	BOOL    GetSideInfo(); 
	void    GetScaleFact(DWORD dwCh, DWORD dwGr); 
	void    GetLSFScaleData(DWORD dwCh, DWORD dwGr); 
	void    GetLSFScaleFactor(DWORD dwCh, DWORD dwGr); 
	void    HuffmanDecode(DWORD dwCh, DWORD dwGr); 
	void    IStereoKValues(DWORD nIsPos, DWORD dwIoType, DWORD i); 
	void    DeqSample(double dbRectArr[32][18], DWORD dwCh, DWORD dwGr); 
	void    Reorder(double dbRectArr[32][18], DWORD dwCh, DWORD dwGr); 
	int     Stereo(DWORD dwGr); 
	void    AntiAlias(DWORD dwCh, DWORD dwGr); 
	void    Hibrid(DWORD dwCh, DWORD dwGr); 
	void    InvMdcdt(double *pDblIn, double *pDblOut, int nBlockType); 
	DWORD   Bits(int nCount); 
    int     HuffmanDec(sHUFDECTAB *h, int *x, int *y, int *v,int *w); 
    void     SubBands(double dbRectArr[32][18]); 
	DWORD	GetReadBits() const { return(m_PlayedBits); } 
	DWORD	GetBits(DWORD dwBits); 
	_inline DWORD	GetFastOneBit() 
	{ 
		DWORD dwRetVal PURE; 
		m_PlayedBits++; 
		if (m_restBits == 0)  
		{ 
			m_restBits = 8; 
			m_playedOctets++; 
		} 
		DWORD xmask = 0xFFFFFFFF >> (32 - m_restBits); 
		dwRetVal = m_pDwBuff[m_playedOctets & 0xfff] & xmask; 
		m_restBits--; 
		dwRetVal = dwRetVal >> m_restBits; 
		return dwRetVal; 
	} 
 
	_inline void AddTail(int dwRetVal) 
	{ 
		m_pDwBuff[m_offset] = (BYTE)dwRetVal; 
		m_offset = (m_offset + 1) & 0xfff; 
	} 
 
	void	GoBackBits(int dwBits); 
	void	GoBackOctets(int bites = BUFSIZE); 
 
private: 
    int					m_nArray[SBLIMIT*EIGHTEEN]; 
	double				m_cubeRo[2][SBLIMIT][EIGHTEEN]; 
	double				m_cubeLr[2][SBLIMIT][EIGHTEEN]; 
	double				m_dOutArr[SBLIMIT*EIGHTEEN]; 
	double				m_PreBlkArr[2][SBLIMIT*EIGHTEEN]; 
	double				m_theKArray[2][SBLIMIT*EIGHTEEN]; 
	int					m_arrNonZero[2]; 
	DWORD				m_dwScale[54]; 
 
private: 
	int					m_nChanels; 
    int                 m_nChanel; 
    int                 m_chFirst; 
    int                 m_chLast; 
 
	DWORD				m_dwMaxGr; 
	int					m_nFrmStart; 
	int					m_nPart2Start; 
	DWORD				m_nFreqIdx; 
 
	STR_3SIDEINFO		m_SIDEINF; 
	STR_3SCALEFACT		m_sCALEF; 
 
private: 
 
	SynthesisFilter*	m_pFilterX;  
	SynthesisFilter*	m_pFilterY; 
 
private: 
    BYTE*				m_pbyWalk; 
    int					m_nBitsOffset;	 
	int					m_flMode; 
	DWORD				m_dwExtensionMode; 
    PFN                 m_pfnCallback; 
    DWORD               m_version;	 
	//bit pool reservoir data 
	DWORD		m_offset; 
	DWORD		m_PlayedBits; 
	DWORD		m_playedOctets; 
	DWORD		m_restBits; 
	DWORD		m_InWordAcumulated; 
	DWORD*		m_pDwBuff; 
 
}; 
 
#endif //__LAYERIII_H_