📄 audiodecoderacm.cpp
字号:
/**************************************************************************************
* *
* *
**************************************************************************************/
#include "AudioDecoderACM.h"
/*
* ACM封装器类
*
*/
MediaAudioDecoderACM::MediaAudioDecoderACM()
{
this->out_buffer = NULL;
this->in_buffer = NULL;
this->oFormat = NULL;
this->ring = new MediaRingBuffer();
}
MediaAudioDecoderACM::~MediaAudioDecoderACM()
{
delete this->ring;
}
/*
* 媒体项函数
*/
media_type_t MediaAudioDecoderACM::GetType()
{
return MEDIA_TYPE_AUDIO_DECODER;
}
char *MediaAudioDecoderACM::GetName()
{
if(this->hacm != NULL) {
char *name;
HACMDRIVERID dId;
ACMDRIVERDETAILS details;
name = (char *) new char[128];
if(acmDriverID((HACMOBJ) this->hacm, &dId, 0) > 0) {
return NULL;
}
memset(&details, 0, sizeof(ACMDRIVERDETAILS));
details.cbStruct = sizeof(ACMDRIVERDETAILS);
if(acmDriverDetails(dId, &details, 0) == MMSYSERR_INVALHANDLE) {
return NULL;
}
strcpy(name, details.szLongName);
return name;
}
return "ACM Wrapper";
}
MP_RESULT MediaAudioDecoderACM::Connect(MediaItem *item)
{
MMRESULT mmres;
WAVEFORMATEX *inFormat;
DWORD dwOutputFormatSize;
if(item && item->GetType() == MEDIA_TYPE_DECAPS) {
this->decaps = (MediaItemDecaps *) item;
inFormat = this->decaps->GetAudioFormat(0);
if(inFormat->wFormatTag == 85 && inFormat->cbSize != 12) {
MPEGLAYER3WAVEFORMAT *format;
format = (MPEGLAYER3WAVEFORMAT *) inFormat;
format->wfx.cbSize = 12;
format->wID = 1;
format->fdwFlags = 2;
format->nBlockSize = 313;
format->nFramesPerBlock = 1;
format->nCodecDelay = 1393;
}
if (acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (LPVOID)&dwOutputFormatSize)) {
return MP_RESULT_ERROR;
}
this->oFormat = (WAVEFORMATEX *) new WAVEFORMATEX;
this->oFormat->wFormatTag = WAVE_FORMAT_PCM;
if (acmFormatSuggest(NULL, inFormat, this->oFormat, dwOutputFormatSize, ACM_FORMATSUGGESTF_WFORMATTAG)) {
}
if (oFormat->wBitsPerSample!=8 && oFormat->wBitsPerSample!=16)
oFormat->wBitsPerSample=16;
if (oFormat->nChannels!=1 && oFormat->nChannels!=2)
oFormat->nChannels = 2;
oFormat->nBlockAlign = (oFormat->wBitsPerSample/8) * oFormat->nChannels;
oFormat->nAvgBytesPerSec = oFormat->nBlockAlign * oFormat->nSamplesPerSec;
oFormat->cbSize = 0;
mmres = acmStreamOpen(&hacm, NULL, inFormat,
this->oFormat, NULL, NULL, 0, ACM_STREAMOPENF_NONREALTIME);
if(mmres != 0) {
return MP_RESULT_ERROR;
}
this->inputSize = max(2048 - (2048 % inFormat->nBlockAlign), 8*inFormat->nBlockAlign);
this->outputSize = 0;
if (acmStreamSize(this->hacm, this->inputSize, &this->outputSize, ACM_STREAMSIZEF_SOURCE))
return MP_RESULT_ERROR;
this->ring->Init();
this->in_buffer = (char *) new char[this->inputSize];
this->out_buffer = (char *) new char[this->outputSize];
this->acmInLeft = 0;
this->acmLeft = 0;
return MP_RESULT_OK;
}
return MP_RESULT_ERROR;
}
MP_RESULT MediaAudioDecoderACM::ReleaseConnections()
{
this->decaps = NULL;
free(this->in_buffer);
this->in_buffer = NULL;
free(this->out_buffer);
this->out_buffer = NULL;
free(this->oFormat);
this->oFormat = NULL;
acmStreamClose(this->hacm, 0);
return MP_RESULT_OK;
}
DWORD MediaAudioDecoderACM::GetCaps()
{
return 0;
}
MP_RESULT MediaAudioDecoderACM::Configure(HINSTANCE hInstance, HWND hwnd)
{
return MP_RESULT_ERROR;
}
WAVEFORMATEX *MediaAudioDecoderACM::GetAudioFormat()
{
return this->oFormat;
}
MP_RESULT MediaAudioDecoderACM::EmptyAudioBuffer()
{
if(this->ring)
this->ring->Init();
this->acmLeft = 0;
this->acmInLeft = 0;
return MP_RESULT_OK;
}
unsigned int MediaAudioDecoderACM::Decompress(void *buffer, unsigned int size)
{
DWORD i, done;
MMRESULT res;
done = 0;
if(this->hacm) {
if(size < 16384) {
if(this->acmLeft > 0 && !this->ring->IsFullFor(this->acmLeft)) {
this->ring->Write((char *) this->out_buffer, this->acmLeft);
this->acmLeft = 0;
}
if(this->acmLeft > 0)
goto done;
if(!this->acmInLeft) {
if(this->decaps->ReadAudioData(0, this->in_buffer, this->inputSize) != this->inputSize) {
return done;
}
}
memset(&this->acmHeader, 0, sizeof(ACMSTREAMHEADER));
this->acmHeader.cbStruct = sizeof(ACMSTREAMHEADER);
if(this->acmInLeft > 0) {
memcpy(this->in_buffer, ((char *) this->in_buffer) + this->inputSize - this->acmInLeft, this->acmInLeft);
if(this->decaps->ReadAudioData(0, ((char *) this->in_buffer) + this->acmInLeft, this->inputSize - this->acmInLeft) != (this->inputSize - this->acmInLeft) ) {
return done;
}
this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
this->acmHeader.cbSrcLength = this->inputSize;
this->acmInLeft = 0;
}
else {
this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
this->acmHeader.cbSrcLength = this->inputSize;
}
this->acmHeader.pbDst = (unsigned char *) this->out_buffer;
this->acmHeader.cbDstLength = this->outputSize;
res = acmStreamPrepareHeader(this->hacm, &this->acmHeader, 0);
if(res > 0) {
return done;
}
res = acmStreamConvert(this->hacm, &this->acmHeader, 0);
if(res > 0) {
acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
return done;
}
while(!this->ring->IsFullFor(this->acmHeader.cbDstLengthUsed)) {
this->ring->Write((char *) this->acmHeader.pbDst, this->acmHeader.cbDstLengthUsed);
acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
if(!this->acmInLeft) {
if(this->decaps->ReadAudioData(0, this->in_buffer, this->inputSize) != this->inputSize) {
return done;
}
}
memset(&this->acmHeader, 0, sizeof(ACMSTREAMHEADER));
this->acmHeader.cbStruct = sizeof(ACMSTREAMHEADER);
if(this->acmInLeft > 0) {
memcpy(this->in_buffer, ((char *) this->in_buffer) + this->inputSize - this->acmInLeft, this->acmInLeft);
if(this->decaps->ReadAudioData(0, ((char *) this->in_buffer) + this->acmInLeft, this->inputSize - this->acmInLeft) != (this->inputSize - this->acmInLeft) ) {
return done;
}
this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
this->acmHeader.cbSrcLength = this->inputSize;
this->acmInLeft = 0;
}
else {
this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
this->acmHeader.cbSrcLength = this->inputSize;
}
this->acmHeader.pbDst = (unsigned char *) this->out_buffer;
this->acmHeader.cbDstLength = this->outputSize;
res = acmStreamPrepareHeader(this->hacm, &this->acmHeader, 0);
if(res > 0) {
return done;
}
res = acmStreamConvert(this->hacm, &this->acmHeader, 0);
if(res > 0) {
acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
return done;
}
this->acmInLeft = this->inputSize - this->acmHeader.cbSrcLengthUsed;
}
this->acmLeft = this->acmHeader.cbDstLengthUsed;
acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
done:
this->ring->Read((char *) buffer, size);
done += size;
return done;
}
else {
unsigned int blocks = size / 16384;
for(i = 0; i < blocks; i++) {
if(this->acmLeft > 0 && !this->ring->IsFullFor(this->acmLeft)) {
this->ring->Write((char *) this->out_buffer, this->acmLeft);
this->acmLeft = 0;
}
if(this->acmLeft > 0)
goto done2;
if(!this->acmInLeft) {
if(this->decaps->ReadAudioData(0, this->in_buffer, this->inputSize) != this->inputSize) {
return done;
}
}
memset(&this->acmHeader, 0, sizeof(ACMSTREAMHEADER));
this->acmHeader.cbStruct = sizeof(ACMSTREAMHEADER);
if(this->acmInLeft > 0) {
memcpy(this->in_buffer, ((char *) this->in_buffer) + this->inputSize - this->acmInLeft, this->acmInLeft);
if(this->decaps->ReadAudioData(0, ((char *) this->in_buffer) + this->acmInLeft, this->inputSize - this->acmInLeft) != (this->inputSize - this->acmInLeft) ) {
return done;
}
this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
this->acmHeader.cbSrcLength = this->inputSize;
this->acmInLeft = 0;
}
else {
this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
this->acmHeader.cbSrcLength = this->inputSize;
}
this->acmHeader.pbDst = (unsigned char *) this->out_buffer;
this->acmHeader.cbDstLength = this->outputSize;
res = acmStreamPrepareHeader(this->hacm, &this->acmHeader, 0);
if(res > 0) {
return done;
}
res = acmStreamConvert(this->hacm, &this->acmHeader, 0);
if(res > 0) {
acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
return done;
}
while(!this->ring->IsFullFor(this->acmHeader.cbDstLengthUsed)) {
this->ring->Write((char *) this->acmHeader.pbDst, this->acmHeader.cbDstLengthUsed);
acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
if(!this->acmInLeft) {
if(this->decaps->ReadAudioData(0, this->in_buffer, this->inputSize) != this->inputSize) {
return done;
}
}
memset(&this->acmHeader, 0, sizeof(ACMSTREAMHEADER));
this->acmHeader.cbStruct = sizeof(ACMSTREAMHEADER);
if(this->acmInLeft > 0) {
memcpy(this->in_buffer, ((char *) this->in_buffer) + this->inputSize - this->acmInLeft, this->acmInLeft);
if(this->decaps->ReadAudioData(0, ((char *) this->in_buffer) + this->acmInLeft, this->inputSize - this->acmInLeft) != (this->inputSize - this->acmInLeft) ) {
return done;
}
this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
this->acmHeader.cbSrcLength = this->inputSize;
this->acmInLeft = 0;
}
else {
this->acmHeader.pbSrc = (unsigned char *) this->in_buffer;
this->acmHeader.cbSrcLength = this->inputSize;
}
this->acmHeader.pbDst = (unsigned char *) this->out_buffer;
this->acmHeader.cbDstLength = this->outputSize;
res = acmStreamPrepareHeader(this->hacm, &this->acmHeader, 0);
if(res > 0) {
return done;
}
res = acmStreamConvert(this->hacm, &this->acmHeader, 0);
if(res > 0) {
acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
return done;
}
this->acmInLeft = this->inputSize - this->acmHeader.cbSrcLengthUsed;
}
this->acmLeft = this->acmHeader.cbDstLengthUsed;
acmStreamUnprepareHeader(this->hacm, &this->acmHeader, 0);
done2:
this->ring->Read(((char *) buffer) + i*16384, 16384);
done += 16384;
}
int left = size - (blocks * 16384);
if(left > 0) {
this->Decompress((void *) ((char *) buffer + size - left), left);
done += left;
}
return done;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -