请问WMA9 Pro编码的音频文件,能用DMO来解码吗~~?

howehowe 2010-04-08 05:20:41
请问WMA9 Pro编码的音频文件,能用DMO来解码吗~~?如果不可以应该怎样解码啊~??有源码更好~~再另外给分!!!
...全文
219 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhishudaren 2010-04-13
  • 打赏
  • 举报
回复
真的没人知道吗~?
tufaqing 2010-04-09
  • 打赏
  • 举报
回复
可以,WMAudio Decoder DMO filter能解的都能解。一般支持WMA1,2,3(7,8,9),WMA lossless,format tag分别为0x160,0x161,0x162,0x163。

给你一份参考代码,有些定义找不到,你应该猜的出是什么意思。

static CLSID CLSID_WMAudio_DMO = { 0x2EEB4ADF, 0x4578, 0x4D10, { 0xBC, 0xA7, 0xBB, 0x95, 0x5F, 0x56, 0x32, 0x0A } };
static CLSID CLSID_WMSpeech_DMO = { 0x874131CB, 0x4ECC, 0x443B, { 0x89, 0x48, 0x74, 0x6B, 0x89, 0x59, 0x5D, 0x20 } };

CWMDMODecoder::CWMDMODecoder()
: m_pAudioParser(NULL)
, m_pSample(NULL)
, m_dwSample(0)
, m_pDMO(NULL)
, m_pInputBuffer(NULL)
, m_pOutputBuffer(NULL)
, m_pFrameBuffer(NULL)
, m_dwFrameLen(0)
{
memset(&m_pcmFrame, 0, sizeof(m_pcmFrame));
memset(&m_mtIn, 0, sizeof(DMO_MEDIA_TYPE));
memset(&m_mtOut, 0, sizeof(DMO_MEDIA_TYPE));

CoInitialize(NULL);
}

CWMDMODecoder::~CWMDMODecoder()
{
UnInitDMO();

CoUninitialize();
}

BOOL CWMDMODecoder::InitDMO(BOOL bWMAudio)
{
if(m_pAudioParser == NULL)
return FALSE;

AUDIOFORMAT *pAudioFormat = m_pAudioParser->GetAudioFormat();
if(pAudioFormat == NULL)
return FALSE;

if(FAILED(CoCreateInstance(bWMAudio ? CLSID_WMAudio_DMO : CLSID_WMSpeech_DMO, NULL, CLSCTX_INPROC_SERVER, IID_IMediaObject, (void**)&m_pDMO)))
return FALSE;

int nSize = sizeof(WAVEFORMATEX) + pAudioFormat->cbSize;
WAVEFORMATEX *pwfex = (WAVEFORMATEX *)CoTaskMemAlloc(nSize);
memcpy(pwfex + 1, pAudioFormat + 1, pAudioFormat->cbSize);
pwfex->wFormatTag = pAudioFormat->wFormatTag;
pwfex->nChannels = pAudioFormat->nChannels;
pwfex->nSamplesPerSec = pAudioFormat->nSamplesPerSec;
pwfex->nAvgBytesPerSec = pAudioFormat->nAvgBytesPerSec;
pwfex->nBlockAlign = pAudioFormat->nBlockAlign;
pwfex->wBitsPerSample = pAudioFormat->wBitsPerSample;
pwfex->cbSize = pAudioFormat->cbSize;

m_mtIn.majortype = MEDIATYPE_Audio;
m_mtIn.subtype = FOURCCMap(pAudioFormat->wFormatTag);
m_mtIn.bFixedSizeSamples = FALSE;
m_mtIn.bTemporalCompression = TRUE;
m_mtIn.lSampleSize = pAudioFormat->nBlockAlign;
m_mtIn.formattype = FORMAT_WaveFormatEx;
m_mtIn.cbFormat = nSize;
m_mtIn.pbFormat = (BYTE*)pwfex;

if(FAILED(m_pDMO->SetInputType(0, &m_mtIn, 0)))
return FALSE;

pwfex = (WAVEFORMATEX *)CoTaskMemAlloc(sizeof(WAVEFORMATEX));
pwfex->wFormatTag = WAVE_FORMAT_PCM;
pwfex->nChannels = pAudioFormat->nChannels;
pwfex->nSamplesPerSec = pAudioFormat->nSamplesPerSec;
pwfex->nAvgBytesPerSec = pAudioFormat->nChannels * pAudioFormat->nSamplesPerSec * pAudioFormat->wBitsPerSample / 8;
pwfex->nBlockAlign = pAudioFormat->nChannels * pAudioFormat->wBitsPerSample / 8;
pwfex->wBitsPerSample = pAudioFormat->wBitsPerSample;
pwfex->cbSize = 0;

m_mtOut.majortype = MEDIATYPE_Audio;
m_mtOut.subtype = MEDIASUBTYPE_PCM;
m_mtOut.bFixedSizeSamples = FALSE;
m_mtOut.bTemporalCompression = FALSE;
m_mtOut.lSampleSize = pwfex->nBlockAlign;
m_mtOut.formattype = FORMAT_WaveFormatEx;
m_mtOut.cbFormat = sizeof(WAVEFORMATEX);
m_mtOut.pbFormat = (BYTE*)pwfex;

if(FAILED(m_pDMO->SetOutputType(0, &m_mtOut, 0)))
return FALSE;

m_pInputBuffer = new CHandlingMediaBuffer;
m_pOutputBuffer = new CHandlingMediaBuffer;

return TRUE;
}

BOOL CWMDMODecoder::UnInitDMO()
{
if(m_pDMO != NULL)
{
m_pDMO->Flush();
m_pDMO->Release();
m_pDMO = NULL;
}

if(m_mtIn.pbFormat != NULL)
{
CoTaskMemFree(m_mtIn.pbFormat);
m_mtIn.pbFormat = NULL;
}

if(m_mtOut.pbFormat != NULL)
{
CoTaskMemFree(m_mtOut.pbFormat);
m_mtOut.pbFormat = NULL;
}

SAFE_DELETE(m_pInputBuffer);
SAFE_DELETE(m_pOutputBuffer);
SAFE_ARRAY_DELETE(m_pSample);

m_pFrameBuffer = NULL;
m_dwFrameLen = 0;

return TRUE;
}

BOOL CWMDMODecoder::SetParser(IBaseAudioParser *pAudioParser)
{
if(pAudioParser == NULL)
return FALSE;

AUDIOFORMAT *pAudioFormat = pAudioParser->GetAudioFormat();
if((pAudioFormat == NULL) ||
(pAudioFormat->wFormatTag != AUDIO_FORMAT_WMSP1 &&
pAudioFormat->wFormatTag != AUDIO_FORMAT_WMSP2 &&
pAudioFormat->wFormatTag != AUDIO_FORMAT_WMA1 &&
pAudioFormat->wFormatTag != AUDIO_FORMAT_WMA2 &&
pAudioFormat->wFormatTag != AUDIO_FORMAT_WMA3 &&
pAudioFormat->wFormatTag != AUDIO_FORMAT_WMAL))
return FALSE;

m_pAudioParser = pAudioParser;

BOOL bWMAudio = TRUE;
if(pAudioFormat->wFormatTag == AUDIO_FORMAT_WMSP1 || pAudioFormat->wFormatTag == AUDIO_FORMAT_WMSP2)
bWMAudio = FALSE;

UnInitDMO();
if(InitDMO(bWMAudio))
return TRUE;

UnInitDMO();
m_pAudioParser = NULL;
return FALSE;
}

PCMFRAME *CWMDMODecoder::GetNextFrame()
{
if(m_pAudioParser == NULL)
return NULL;

while(1)
{
if(m_dwFrameLen == 0)
{
AUDIOFRAME *pFrame = m_pAudioParser->GetNextFrame();
if(pFrame == NULL)
return NULL;

m_pFrameBuffer = pFrame->pbSample + pFrame->cbDataOffset;
m_dwFrameLen = pFrame->cbSample - pFrame->cbDataOffset;
}

AUDIOFORMAT *pFormat = m_pAudioParser->GetAudioFormat();
if(m_pSample == NULL)
{
m_dwSample = pFormat->nChannels * pFormat->nSamplesPerSec; // 1s
m_pSample = new SHORT[m_dwSample];
}

DWORD dwFrameLen = min(m_dwFrameLen, pFormat->nBlockAlign);

m_pInputBuffer->set_Buffer(m_pFrameBuffer, dwFrameLen, dwFrameLen);

m_pFrameBuffer += dwFrameLen;
m_dwFrameLen -= dwFrameLen;

DWORD dwFlags = DMO_INPUT_DATA_BUFFERF_SYNCPOINT /*| DMO_INPUT_DATA_BUFFERF_TIME | DMO_INPUT_DATA_BUFFERF_TIMELENGTH*/;
if(SUCCEEDED(m_pDMO->ProcessInput(0, m_pInputBuffer, dwFlags, 0, 0)))
{
m_pOutputBuffer->set_Buffer((BYTE*)m_pSample, 0, m_dwSample * sizeof(SHORT));

DWORD dwStatus = 0;
DMO_OUTPUT_DATA_BUFFER OutputBufferStructs[1];
OutputBufferStructs[0].pBuffer = m_pOutputBuffer;
OutputBufferStructs[0].dwStatus = 0;
if(SUCCEEDED(m_pDMO->ProcessOutput(0, 1, OutputBufferStructs, &dwStatus)))
{
DWORD dwLen = 0;
m_pOutputBuffer->GetLength(&dwLen);
if(dwLen > 0)
{
m_pcmFrame.nChannels = pFormat->nChannels;
m_pcmFrame.nSamplesPerSec = pFormat->nSamplesPerSec;
m_pcmFrame.cbSample = dwLen / sizeof(SHORT);
m_pcmFrame.pbSample = m_pSample;
return &m_pcmFrame;
}
}
}
else
{
m_pDMO->Flush();
}
}

return NULL;
}
howehowe 2010-04-09
  • 打赏
  • 举报
回复
format tag为0x161的wma文件是正常的啊~~~但0x162就不正确了....
howehowe 2010-04-09
  • 打赏
  • 举报
回复
但为什么我的ProcessInput()返回的却是E_FAIL~??
msdn2100 2010-04-09
  • 打赏
  • 举报
回复
1楼正解
howehowe 2010-04-09
  • 打赏
  • 举报
回复
第一次在这里提问,发现不能上传附件的....
howehowe 2010-04-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 tufaqing 的回复:]
可以,WMAudio Decoder DMO filter能解的都能解。一般支持WMA1,2,3(7,8,9),WMA lossless,format tag分别为0x160,0x161,0x162,0x163。

给你一份参考代码,有些定义找不到,你应该猜的出是什么意思。
[/Quote]

谢谢你的回答~~但是我的m_mtIn 和m_mtOut赋的值跟你的都是一样的,ProcessInput()返回的却是E_FAIL......
或者你可不可以试1下我附件那个音频文件,我用windows media player是能播的~

2,554

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧