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

📄 codec.cpp

📁 faac-1.25.rar音频编解码器demo
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "codec.h"
#include <assert.h>

// we must register these by emailing to mmreg@microsoft.com
const int codec::m_iCompressedFormatTag = 0x1234;
const int codec::m_iManufacturerID = MM_GADGETLABS;
const int codec::m_iProductID = 7;

const wchar_t g_sCodecName[]=L"MPEG-2/4 AAC audio codec";
const wchar_t g_sLongCodecName[]=L"Very special audio codec";
const wchar_t g_sFormatName[]=L"MPEG-2/4 AAC";

codec::codec()
{
}

codec::~codec()
{
}

HRESULT codec::formattag_details(ACMFORMATTAGDETAILSW* lParam1, DWORD lParam2)
{
    bool bCompressedFormat;
    switch(lParam2)
    {
    case ACM_FORMATTAGDETAILSF_INDEX:
		if(lParam1->dwFormatTagIndex>=2)
			return ACMERR_NOTPOSSIBLE;
		bCompressedFormat=(lParam1->dwFormatTagIndex==1);
		break;
    case ACM_FORMATTAGDETAILSF_FORMATTAG:
		if(lParam1->dwFormatTag==1)
			bCompressedFormat=false;
		else if(lParam1->dwFormatTag==m_iCompressedFormatTag)
			bCompressedFormat=true;
		else
			return ACMERR_NOTPOSSIBLE;
    case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
		bCompressedFormat=true;
		break;
    default:
		return ACMERR_NOTPOSSIBLE;
    }
    lParam1->cbStruct=sizeof(ACMFORMATTAGDETAILSW);    
    lParam1->cbFormatSize=bCompressedFormat ? 20 : 16;    
    lParam1->fdwSupport=ACMDRIVERDETAILS_SUPPORTF_CODEC;
    if(bCompressedFormat)
		lParam1->cStandardFormats=8; // 44 & 48 khz 16 bit, mono & stereo, 64 & 128 kbps
    else
		lParam1->cStandardFormats=8; // 44 & 48 khz 8 & 16 bit, mono & stereo
    if(bCompressedFormat)
    {
		wcscpy(lParam1->szFormatTag, g_sFormatName);
		lParam1->dwFormatTag=m_iCompressedFormatTag;
    }
    else
    {
		wcscpy(lParam1->szFormatTag, L"PCM");
		lParam1->dwFormatTag=1;
    }
    return MMSYSERR_NOERROR;
}

void codec::fill_pcm_format(WAVEFORMATEX* pwfx, int rate, int bits, int channels)
{
    pwfx->wFormatTag=1;
    pwfx->nSamplesPerSec=rate;
    pwfx->wBitsPerSample=bits;
    pwfx->nChannels=channels;
    pwfx->nAvgBytesPerSec=rate * bits * channels / 8;
    pwfx->nBlockAlign=channels * bits / 8;
    pwfx->cbSize=0;
}

#define MAIN 0
#define LOW  1
#define SSR  2
#define LTP  3

static unsigned int aacSamplingRates[16] = {
    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
		16000, 12000, 11025, 8000, 7350, 0, 0, 0
};

void codec::fill_compressed_format(WAVEFORMATEX* pwfx, int rate, int bits, int channels, int bitrate)
{
    pwfx->wFormatTag=m_iCompressedFormatTag;
    pwfx->nSamplesPerSec=rate;
    pwfx->wBitsPerSample=bits;
    pwfx->nChannels=channels;
    pwfx->nAvgBytesPerSec=bitrate / 8;
    pwfx->nBlockAlign=1024;
    pwfx->cbSize=2;
	
    unsigned char* ext=(unsigned char*)(&pwfx[1]);
    int profile = MAIN;
    int samplerate_index=-1;
    for(int i=0; i<16; i++)
		if(aacSamplingRates[i]==rate)
		{
			samplerate_index=i;
			break;
		}
		if(samplerate_index<0)
			return;
		ext[0] = ((profile + 1) << 3) | ((samplerate_index & 0xe) >> 1);
		ext[1] = ((samplerate_index & 0x1) << 7) | (channels << 3);
		// 960 byte frames not used
}

HRESULT codec::format_details(ACMFORMATDETAILSW* lParam1, DWORD lParam2)
{
    lParam1->cbStruct=sizeof(ACMFORMATDETAILSW);
    lParam1->szFormat[0]=0;
    lParam1->fdwSupport=ACMDRIVERDETAILS_SUPPORTF_CODEC;
	
    if(lParam1->dwFormatTag==1)
    {
		if(lParam2==ACM_FORMATDETAILSF_INDEX)
		{
			switch(lParam1->dwFormatIndex)
			{
			case 0:
				fill_pcm_format(lParam1->pwfx, 44100, 16, 1);
				break;
			case 1:
				fill_pcm_format(lParam1->pwfx, 44100, 16, 2);
				break;
			case 2:
				fill_pcm_format(lParam1->pwfx, 44100, 8, 1);
				break;
			case 3:
				fill_pcm_format(lParam1->pwfx, 44100, 8, 2);
				break;
			case 4:
				fill_pcm_format(lParam1->pwfx, 48000, 16, 1);
				break;
			case 5:
				fill_pcm_format(lParam1->pwfx, 48000, 16, 2);
				break;
			case 6:
				fill_pcm_format(lParam1->pwfx, 48000, 8, 1);
				break;
			case 7:
				fill_pcm_format(lParam1->pwfx, 48000, 8, 2);
				break;
			default:
				return ACMERR_NOTPOSSIBLE;
			}
		}   
		else if(lParam2==ACM_FORMATDETAILSF_FORMAT)
		{
			if((lParam1->pwfx->nSamplesPerSec != 44100) && (lParam1->pwfx->nSamplesPerSec != 48000))
				return ACMERR_NOTPOSSIBLE;
		}
		else
			return ACMERR_NOTPOSSIBLE;
    }
    else if(lParam1->dwFormatTag==m_iCompressedFormatTag)
    {
		if(lParam2==ACM_FORMATDETAILSF_INDEX)
		{
			switch(lParam1->dwFormatIndex)
			{
			case 0:
				fill_compressed_format(lParam1->pwfx, 44100, 16, 1, 128000);
				break;
			case 1:
				fill_compressed_format(lParam1->pwfx, 44100, 16, 2, 128000);
				break;
			case 2:
				fill_compressed_format(lParam1->pwfx, 44100, 16, 1, 64000);
				break;
			case 3:
				fill_compressed_format(lParam1->pwfx, 44100, 16, 2, 64000);
				break;
			case 4:
				fill_compressed_format(lParam1->pwfx, 48000, 16, 1, 128000);
				break;
			case 5:
				fill_compressed_format(lParam1->pwfx, 48000, 16, 2, 128000);
				break;
			case 6:
				fill_compressed_format(lParam1->pwfx, 48000, 16, 1, 64000);
				break;
			case 7:
				fill_compressed_format(lParam1->pwfx, 48000, 16, 2, 64000);
				break;
			default:
				return ACMERR_NOTPOSSIBLE;
			}
		}
		else if(lParam2==ACM_FORMATDETAILSF_FORMAT)
		{
			if((lParam1->pwfx->nSamplesPerSec != 44100) && (lParam1->pwfx->nSamplesPerSec != 48000))
				return ACMERR_NOTPOSSIBLE;
		}
		else
			return ACMERR_NOTPOSSIBLE;
    }
    else
		return ACMERR_NOTPOSSIBLE;
    return MMSYSERR_NOERROR;
}

HRESULT codec::format_suggest(ACMDRVFORMATSUGGEST* pFormat)
{
    bool bEncode;
    if(pFormat->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG)
    {
		if((pFormat->pwfxDst->wFormatTag == 1) && (pFormat->pwfxSrc->wFormatTag == m_iCompressedFormatTag))
			bEncode=false;
		else
			if((pFormat->pwfxDst->wFormatTag == m_iCompressedFormatTag) && (pFormat->pwfxSrc->wFormatTag == 1))
				bEncode=true;
			else
				return ACMERR_NOTPOSSIBLE;
    }
    else
    {
		if(pFormat->pwfxSrc->wFormatTag == m_iCompressedFormatTag)
		{
			pFormat->pwfxDst->wFormatTag=1; 
			bEncode=false;
		}
		else
			if(pFormat->pwfxSrc->wFormatTag == 1)
			{
				pFormat->pwfxDst->wFormatTag=m_iCompressedFormatTag; 
				bEncode=true;
			}
			else
				return ACMERR_NOTPOSSIBLE;
    }
    if(pFormat->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS)
    {
		if(pFormat->pwfxDst->nChannels != pFormat->pwfxSrc->nChannels)
			return ACMERR_NOTPOSSIBLE;
    }
    int iChannels = pFormat->pwfxSrc->nChannels;
    if(pFormat->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC)
    {
		if(pFormat->pwfxDst->nSamplesPerSec != pFormat->pwfxSrc->nSamplesPerSec)
			return ACMERR_NOTPOSSIBLE;
    }
    int iSamplesPerSec = pFormat->pwfxSrc->nSamplesPerSec;
	
    if(pFormat->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE)
    {
		if(pFormat->pwfxDst->wBitsPerSample != pFormat->pwfxSrc->wBitsPerSample)
			return ACMERR_NOTPOSSIBLE;
    }
    int iBitsPerSample = pFormat->pwfxSrc->wBitsPerSample;
	
    if(bEncode)
		fill_compressed_format(pFormat->pwfxDst, iSamplesPerSec, iBitsPerSample, iChannels, 128000);
    else
		fill_pcm_format(pFormat->pwfxDst, iSamplesPerSec, iBitsPerSample, iChannels);
	
    return MMSYSERR_NOERROR;
}

HRESULT codec::details(ACMDRIVERDETAILSW* pDetails)
{
    memset(pDetails, 0, sizeof(ACMDRIVERDETAILSW));
    pDetails->cbStruct=sizeof(ACMDRIVERDETAILSW);
    pDetails->fccType=ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
    pDetails->fccComp=ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
    pDetails->wMid=m_iManufacturerID;
    pDetails->wPid=m_iProductID;
    pDetails->vdwACM=0x3320000;
    pDetails->vdwDriver=0x1000000;
    pDetails->fdwSupport=ACMDRIVERDETAILS_SUPPORTF_CODEC;
    pDetails->cFormatTags=2;
    pDetails->cFilterTags=0;
    wcscpy(pDetails->szShortName, g_sCodecName);
    wcscpy(pDetails->szLongName, g_sLongCodecName);
    return MMSYSERR_NOERROR;
}

HRESULT codec::about(DWORD h)
{
    if(h==(DWORD)-1)
		return MMSYSERR_NOERROR;
    MessageBoxW((HWND)h, g_sLongCodecName, L"About", MB_OK);
    return MMSYSERR_NOERROR;
}

HRESULT codec::open(ACMDRVSTREAMINSTANCE* pStream)
{
    if(pStream->pwfxDst->nChannels != pStream->pwfxSrc->nChannels)
		return ACMERR_NOTPOSSIBLE;
    if(pStream->pwfxDst->nSamplesPerSec != pStream->pwfxSrc->nSamplesPerSec)
		return ACMERR_NOTPOSSIBLE;
    bool bDecode = (pStream->pwfxDst->wFormatTag == 1);
    if(bDecode)
    {
		if(pStream->pwfxDst->wBitsPerSample!=16)
			return ACMERR_NOTPOSSIBLE;
		if(pStream->pwfxSrc->wFormatTag!=m_iCompressedFormatTag)
			return ACMERR_NOTPOSSIBLE;
    }
    else
    {
		//	if(pStream->pwfxSrc->wBitsPerSample!=16)
		//	    return ACMERR_NOTPOSSIBLE;
		if(pStream->pwfxDst->wFormatTag!=m_iCompressedFormatTag)
			return ACMERR_NOTPOSSIBLE;
		if(pStream->pwfxSrc->wFormatTag!=1)
			return ACMERR_NOTPOSSIBLE;
    }
	
    if(pStream->fdwOpen & ACM_STREAMOPENF_QUERY)
		return MMSYSERR_NOERROR;
	
    if(bDecode)
		pStream->dwDriver=(DWORD)new decoder(pStream->pwfxSrc);
    else
		pStream->dwDriver=(DWORD)new encoder(pStream->pwfxSrc, pStream->pwfxDst);
    return MMSYSERR_NOERROR;
}

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

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

HRESULT codec::size(ACMDRVSTREAMINSTANCE* pStream, ACMDRVSTREAMSIZE* pSize)
{

⌨️ 快捷键说明

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