📄 codec.cpp
字号:
#include "codec.h"#include <assert.h>// we must register these by emailing to mmreg@microsoft.comconst 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 3static 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 + -