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

📄 codec.cpp

📁 faac-1.25.rar音频编解码器demo
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    stream* pstr=(stream*)pStream->dwDriver;
    return pstr->size(pSize);
}

HRESULT codec::unprepare(ACMDRVSTREAMINSTANCE* pStream, ACMDRVSTREAMHEADER* pHeader)
{
    return MMSYSERR_NOTSUPPORTED;
}

HRESULT codec::convert(ACMDRVSTREAMINSTANCE* pStream, ACMDRVSTREAMHEADER* pHeader)
{
    stream* pstr=(stream*)pStream->dwDriver;
    return pstr->convert(pHeader);
}

HRESULT codec::close(ACMDRVSTREAMINSTANCE* pStream)
{
    stream* pstr=(stream*)pStream->dwDriver;
    delete pstr;
    return MMSYSERR_NOERROR;
}

#include "faac.h"

codec::encoder::encoder(WAVEFORMATEX* pF, WAVEFORMATEX* pFDest) : m_sFormat(*pF)
{
    m_iOutputBytesPerSec=pFDest->nAvgBytesPerSec; 
	
    m_pHandle=faacEncOpen(pF->nSamplesPerSec, pF->nChannels, &m_iInputSamples, &m_iMaxOutputBytes);
	
    faacEncConfiguration conf;
    conf.mpegVersion = MPEG4;
    conf.aacObjectType = MAIN;
    conf.allowMidside = 1;
    conf.useLfe = 1;
    conf.useTns = 1;
    conf.bitRate = m_iOutputBytesPerSec/pFDest->nChannels; // bits/second per channel
    conf.bandWidth = 18000; //Hz
    conf.outputFormat = 1; // ADTS
    faacEncSetConfiguration(m_pHandle, &conf);    
}

HRESULT codec::encoder::reset()
{
    // fixme (?)
    return MMSYSERR_NOERROR;
}

HRESULT codec::encoder::size(ACMDRVSTREAMSIZE* pSize)
{
    double dwInputBitRate=m_sFormat.nSamplesPerSec * m_sFormat.wBitsPerSample * m_sFormat.nChannels;
    double dwOutputBitRate=m_iOutputBytesPerSec;// kbytes/s    
	
    if(pSize->fdwSize == ACM_STREAMSIZEF_SOURCE)
    {
		if(pSize->cbSrcLength<2*m_iInputSamples)
			pSize->cbSrcLength=2*m_iInputSamples;
		pSize->cbDstLength = pSize->cbSrcLength * 2 * dwOutputBitRate/dwInputBitRate;
		if(pSize->cbDstLength<m_iMaxOutputBytes)
			pSize->cbDstLength=m_iMaxOutputBytes;
		
    }
    else
    {
		if(pSize->cbDstLength<m_iMaxOutputBytes)
			pSize->cbDstLength=m_iMaxOutputBytes;
		pSize->cbSrcLength = pSize->cbDstLength * 2 * dwInputBitRate/dwOutputBitRate;;
		if(pSize->cbSrcLength<2*m_iInputSamples)
			pSize->cbSrcLength=2*m_iInputSamples;
    }
    
    return MMSYSERR_NOERROR;
}

#include <stdio.h>

HRESULT codec::encoder::convert(ACMDRVSTREAMHEADER* pHeader)
{
#if 0
    short* pSrc, *pDst;
    pSrc=(short*)(pHeader->pbSrc);
    pDst=(short*)(pHeader->pbDst);
    int iSrc=0, iDst=0;
    int block_size=m_sFormat.nChannels * 64;
    int samples_to_process=pHeader->cbSrcLength / (2 * block_size);
	
    for(int j=0; j<samples_to_process; j++)
    {
		if(m_sFormat.nChannels==1)
		{
			pDst[0]=pSrc[0];
			for(int i=1; i<64; i++)
				pDst[i]=(int)pSrc[i]-(int)pSrc[i-1];
			pSrc+=block_size;
			pDst+=block_size;
		}
		else
		{
			pDst[0]=pSrc[0];
			pDst[1]=pSrc[1];
			for(int i=1; i<64; i++)
			{
				pDst[2*i]=(int)pSrc[2*i]-(int)pSrc[2*i-2];
				pDst[2*i+1]=(int)pSrc[2*i+1]-(int)pSrc[2*i-1];
			}
			pSrc+=block_size;
			pDst+=block_size;
		}
    }
    FILE* f=fopen("c:\\enc.log", "ab");
    fwrite(pHeader->pbSrc, 2 * block_size * samples_to_process, 1, f);
    fclose(f);
    f=fopen("c:\\enc2.log", "ab");
    fwrite(pHeader->pbDst, 2 * block_size * samples_to_process, 1, f);
    fclose(f);
    pHeader->cbDstLengthUsed=2 * block_size * samples_to_process;
    pHeader->cbSrcLengthUsed=2 * block_size * samples_to_process;
    return MMSYSERR_NOERROR;
#else
    short* buffer=0;
    int length=pHeader->cbSrcLength;
    if(m_sFormat.wBitsPerSample!=16)
    {
		buffer = new short[length];
		for(int i=0; i<length; i++)
		{
			short s=(short)(((unsigned char*)pHeader->pbSrc)[i]);
			s-=128;
			s*=256;
			buffer[i]=s;
		}
    }
    short* pointer = buffer ? buffer : (short*)(pHeader->pbSrc);
    pHeader->cbSrcLengthUsed=0;
    pHeader->cbDstLengthUsed=0;
    while(1)
    {
		if(length-pHeader->cbSrcLengthUsed<2*m_iInputSamples)
			break;
		if(pHeader->cbDstLength-pHeader->cbDstLengthUsed<m_iMaxOutputBytes)
			break;
		int result=faacEncEncode(m_pHandle, pointer+pHeader->cbSrcLengthUsed,
			m_iInputSamples, 
			(short*)(pHeader->pbDst+pHeader->cbDstLengthUsed),
			pHeader->cbDstLength-pHeader->cbDstLengthUsed);
		if(result<0)
		{
			reset();
			break;
		}
        pHeader->cbDstLengthUsed+=result;
        pHeader->cbSrcLengthUsed+=2*m_iInputSamples;
    }    
    if(buffer)
    {
		pHeader->cbSrcLengthUsed/=2;
		delete[] buffer;
    }
    return MMSYSERR_NOERROR;
#endif
}

codec::decoder::decoder(WAVEFORMATEX* pF) : m_sFormat(*pF), m_bInitialized(false), m_pCache(0)
{
    m_pHandle=faacDecOpen();
}

HRESULT codec::decoder::reset()
{
    faacDecClose(m_pHandle);
    m_pHandle=faacDecOpen();
    m_bInitialized=false;
    delete[] m_pCache;
    m_pCache=0;
    return MMSYSERR_NOERROR;
}

HRESULT codec::decoder::size(ACMDRVSTREAMSIZE* pSize)
{
    double dwInputBitRate=m_sFormat.nAvgBytesPerSec;
    double dwOutputBitRate=m_sFormat.nSamplesPerSec * m_sFormat.wBitsPerSample * m_sFormat.nChannels;
	
    if(pSize->fdwSize == ACM_STREAMSIZEF_SOURCE)
    {
		if(pSize->cbSrcLength<768*m_sFormat.nChannels)
			pSize->cbSrcLength=768*m_sFormat.nChannels;
		pSize->cbDstLength = pSize->cbSrcLength * 2 * dwOutputBitRate/dwInputBitRate;
		if(pSize->cbDstLength<4096)
			pSize->cbDstLength=4096;
    }
    else
    {
		if(pSize->cbDstLength<4096)
			pSize->cbDstLength=4096;
		pSize->cbSrcLength = pSize->cbDstLength * 2 * dwInputBitRate/dwOutputBitRate;;
		if(pSize->cbSrcLength<768*m_sFormat.nChannels)
			pSize->cbSrcLength=768*m_sFormat.nChannels;
    }
    
    return MMSYSERR_NOERROR;
}

//static int iBytesProcessed=0;
HRESULT codec::decoder::convert(ACMDRVSTREAMHEADER* pHeader)
{
#if 0
    short *pSrc, *pDst;
    pSrc=(short*)pHeader->pbSrc;
    pDst=(short*)pHeader->pbDst;
    int iSrc=0, iDst=0;
    int block_size=m_sFormat.nChannels * 64;
    int samples_to_process=pHeader->cbSrcLength / (2 * block_size);
    for(int j=0; j<samples_to_process; j++)
    {
		if(m_sFormat.nChannels==1)
		{
			pDst[0]=pSrc[0];
			for(int i=1; i<64; i++)
				pDst[i]=(int)pSrc[i]+(int)pDst[i-1];
			pSrc+=block_size;
			pDst+=block_size;
		}
		else
		{
			pDst[0]=pSrc[0];
			pDst[1]=pSrc[1];
			for(int i=1; i<64; i++)
			{
				pDst[2*i]=(int)pSrc[2*i]+(int)pDst[2*i-2];
				pDst[2*i+1]=(int)pSrc[2*i+1]+(int)pDst[2*i-1];
			}
			pSrc+=block_size;
			pDst+=block_size;
		}
    }
    FILE* f=fopen("c:\\dec.log", "ab");
    fwrite(pHeader->pbDst, 2 * block_size * samples_to_process, 1, f);
    fclose(f);
    pHeader->cbDstLengthUsed=2 * block_size * samples_to_process;
    pHeader->cbSrcLengthUsed=2 * block_size * samples_to_process;
    return MMSYSERR_NOERROR;
#else
    // fixme: check fdwConvert contents
	
    const int iMinInputSize = 768*m_sFormat.nChannels;
    pHeader->cbSrcLengthUsed=0;
    pHeader->cbDstLengthUsed=0;
    int decoded_bytes=0;
    if(!m_bInitialized)
    {
		unsigned long samplerate;
		unsigned long channels;
		//assert(!m_pCache);
		// we don't really need this call
		// and it is done only because i am not sure if it's necessary for faac functionality
		pHeader->cbSrcLengthUsed=faacDecInit(m_pHandle, pHeader->pbSrc, &samplerate, &channels);
		m_bInitialized=true;
    }
    unsigned long bytesconsumed;
    unsigned long samples;    
    if(pHeader->cbDstLength<4096)
		goto finish;

    int iSrcDataLeft=pHeader->cbSrcLength;
	
    while(m_pCache)
    {
		int iFillSize = iMinInputSize - m_iCacheSize;
		if(iFillSize > iSrcDataLeft)
			iFillSize = iSrcDataLeft;
		memcpy(&m_pCache[m_iCacheSize], pHeader->pbSrc+pHeader->cbSrcLengthUsed, iFillSize);
		m_iCacheSize += iFillSize;
		iSrcDataLeft -= iFillSize;
		pHeader->cbSrcLengthUsed += iFillSize;
		if(m_iCacheSize < iMinInputSize)
			goto finish;
		int result=faacDecDecode(m_pHandle, m_pCache, &bytesconsumed, 
			(short*)(pHeader->pbDst+pHeader->cbDstLengthUsed), &samples); // no way to prevent output buffer overrun???
		if(result==FAAD_FATAL_ERROR)
		{
			reset();
			goto finish;
		}
		if(result==FAAD_OK)
			pHeader->cbDstLengthUsed+=sizeof(short)*samples;
		assert(bytesconsumed <= iMinInputSize);
		if(bytesconsumed < iMinInputSize)
			memmove(m_pCache, &m_pCache[bytesconsumed], iMinInputSize-bytesconsumed);
		m_iCacheSize-=bytesconsumed;
		if(m_iCacheSize==0)
		{
			delete[] m_pCache;
			m_pCache=0;
		}
    }

    if(iSrcDataLeft == 0)
		goto finish;
	
    if(iSrcDataLeft < iMinInputSize)
    {
		m_pCache = new unsigned char[iMinInputSize];
		memcpy(m_pCache, pHeader->pbSrc + pHeader->cbSrcLengthUsed, iSrcDataLeft);
		m_iCacheSize = iSrcDataLeft;
		pHeader->cbSrcLengthUsed = pHeader->cbSrcLength;
		goto finish;
    }
    
    while(iSrcDataLeft>=iMinInputSize)
    {
		if(pHeader->cbDstLength-pHeader->cbDstLengthUsed<4096)
			break;
		int result=faacDecDecode(m_pHandle, pHeader->pbSrc+pHeader->cbSrcLengthUsed, &bytesconsumed, 
			(short*)(pHeader->pbDst+pHeader->cbDstLengthUsed), &samples); // no way to prevent output buffer overrun???
		if(result==FAAD_FATAL_ERROR)
		{
			pHeader->cbSrcLengthUsed=pHeader->cbSrcLength;
			reset();
			goto finish;
		}
		if(result==FAAD_OK)
			pHeader->cbDstLengthUsed+=sizeof(short)*samples;
        pHeader->cbSrcLengthUsed+=bytesconsumed;
		iSrcDataLeft-=bytesconsumed;
    }    
finish:
    FILE* f=fopen("c:\\aac_acm.bin", "ab");
    fwrite(pHeader->pbSrc, pHeader->cbSrcLengthUsed, 1, f);
    fclose(f);
	//    iBytesProcessed+=pHeader->cbSrcLengthUsed;
    return MMSYSERR_NOERROR;
#endif
}

⌨️ 快捷键说明

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