关于WAVE文件的播放。

zpie_30 2009-05-28 12:35:15
请问,对于WAVE文件,直接用WINDOWS API(CreateFile等)与用MMIO(mmioOpen等)有什么区别吗?
麻烦看一下下面两个代码,对于一个WAVEFORMATEX的formatTag为1(PCM)的文件,两者都可以正常播放,为什么当tagFormat为2的时候,第一个可以播放,而第二个却在waveOutOpen()时返回错误:WAVERR_BADFORMAT,还是什么其他地方有问题?调试的时候发现,他们读到的数据都是一样的。
代码一:

*wErr = 0;
if(!(m_hmmio = mmioOpen(lpszFileName, NULL, MMIO_READ | MMIO_ALLOCBUF)))
{
*wErr = 1; // Unable to open file
return FALSE;
}
mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if(mmioDescend(m_hmmio, (LPMMCKINFO)&mmckinfoParent, NULL, MMIO_FINDRIFF))
{
*wErr = 2; // File format not surported
return FALSE;
}
mmckinfoSubChunk.ckid = mmioFOURCC('f','m','t',' ');
if(mmioDescend(m_hmmio, &mmckinfoSubChunk, &mmckinfoParent, MMIO_FINDCHUNK))
{
*wErr = 3; // Cannot find fmt chunk
return FALSE;
}
dwFmtSize = mmckinfoSubChunk.cksize;
m_hFormat = LocalAlloc(LMEM_MOVEABLE, LOWORD(dwFmtSize));
if(!m_hFormat)
{
*wErr = 4; // Error when apply memory
return FALSE;
}
lpFormat = (WAVEFORMATEX *)LocalLock(m_hFormat);
if(!lpFormat)
{
*wErr = 4; // Error when apply memory
LocalFree(m_hFormat);
return FALSE;
}
if((unsigned long)mmioRead(m_hmmio, (HPSTR)lpFormat, dwFmtSize) != dwFmtSize)
{
*wErr = 5; // Unable to read format chunk
LocalUnlock(m_hFormat);
LocalFree(m_hFormat);
return FALSE;
}
mmioAscend(m_hmmio, &mmckinfoSubChunk, 0);
mmckinfoSubChunk.ckid = mmioFOURCC('d','a','t','a');
if(mmioDescend(m_hmmio, &mmckinfoSubChunk, &mmckinfoParent, MMIO_FINDCHUNK))
{
*wErr = 6; // Cannot find data chunk
LocalUnlock(m_hFormat);
LocalFree(m_hFormat);
return FALSE;
}
dwDataSize = mmckinfoSubChunk.cksize;
dwDataOffset = mmckinfoSubChunk.dwDataOffset;
if(dwDataSize == 0L)
{
*wErr = 7; // No data in data chunk
LocalUnlock(m_hFormat);
LocalFree(m_hFormat);
return FALSE;
}
lpData = new char[dwDataSize];
// DWORD dwReadSize;
// ReadFile(m_hmmio, lpData, dwDataSize, &dwReadSize, NULL);
if(!lpData)
{
*wErr = 4;
LocalUnlock(m_hFormat);
LocalFree(m_hFormat);
return FALSE;
}
if(mmioSeek(m_hmmio, dwDataOffset, SEEK_SET)<0)
{
LBE8: *wErr = 8; // Fail to read data chunk
LBE8T: delete [dwDataSize]lpData;
LocalUnlock(m_hFormat);
LocalFree(m_hFormat);
return FALSE;
}
if(mmioRead(m_hmmio, (HPSTR)lpData, dwDataSize) != dwDataSize)
{
goto LBE8; return FALSE;
}
if(waveOutGetDevCaps(WAVE_MAPPER, &pwoc, sizeof(WAVEOUTCAPS))!=0)
{
*wErr = 9; goto LBE8T;
}
if(waveOutOpen(&hWaveOut, WAVE_MAPPER, lpFormat, NULL, NULL, CALLBACK_NULL)!=0)
{
*wErr = 9; goto LBE8T; // Device not ready;
}

代码二:

hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if(hFile == INVALID_HANDLE_VALUE)
return WAVEERR_FILEOPEN;
bSuccess = ReadFile(hFile, &wi, sizeof(wi), &dwBytesRead, NULL);
if(!bSuccess || dwBytesRead != sizeof(wi))
{
CloseHandle(hFile);
return WAVEERR_FILEOPEN;
}
if(wi.wfh.RiffTag != RIFFTAG || wi.wfh.WaveTag != WAVETAG ||
wi.ch.ChunkTag != FMTTAG)
{
CloseHandle(hFile);
return WAVEERR_FORMAT;
}
char *Temp = new char[wi.ch.ChunkSize];
bSuccess = ReadFile(hFile, Temp, wi.ch.ChunkSize, &dwBytesRead, NULL);
if(!bSuccess || (long)dwBytesRead != wi.ch.ChunkSize)
{
CloseHandle(hFile);
return WAVEERR_FILEOPEN;
}
m_wfx = *(WAVEFORMATEX *)Temp;
delete [wi.ch.ChunkSize]Temp;
do{
bSuccess = ReadFile(hFile, &ch, sizeof(ch), &dwBytesRead, NULL);
if(!bSuccess || dwBytesRead != sizeof(ch))
{
CloseHandle(hFile);
return WAVEERR_FILEOPEN;
}
if(ch.ChunkTag == DATATAG)
break;
bSuccess = SetFilePointer(hFile, ch.ChunkSize, NULL, FILE_CURRENT);
}while(bSuccess);

m_dwDataSize = ch.ChunkSize;
m_pData = new char[m_dwDataSize];
if(m_pData == NULL)
{
CloseHandle(hFile);
return WAVEERR_ALLOC;
}
bSuccess = ReadFile(hFile, m_pData, m_dwDataSize, &dwBytesRead, NULL);
CloseHandle(hFile);
if(!bSuccess || m_dwDataSize != dwBytesRead)
return WAVEERR_FILEOPEN;
if(MMSYSERR_NOERROR != waveOutGetDevCaps(WAVE_MAPPER, &m_woc, sizeof(m_woc)))
return WAVEERR_DEVICE;
if(MMSYSERR_NOERROR != waveOutOpen(&m_hwo, WAVE_MAPPER, &m_wfx, NULL, NULL, CALLBACK_NULL))
return WAVEERR_DEVICE;

...全文
134 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jian_tian_yang 2009-05-28
  • 打赏
  • 举报
回复
帮楼主顶一下
瓶盒 2009-05-28
  • 打赏
  • 举报
回复
MMIO没怎么用过,看来应该是这样,MMIO兼容性更强些,它能播放多种音频格式。
waveOutOpen只能播放原始的音频数据,即PCM格式。
zpie_30 2009-05-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 bottlebox 的回复:]
MMIO打开文件是为了播放,所以它要判断文件格式是否为支持的播放文件,formatTag为2的文件是它不支持的文件,所以无法打开。
第二种方式打开文件并不检查,但直接使用也是无法播放的,如果你能播放,我想应该是
m_wfx = *(WAVEFORMATEX *)Temp;
这一句你重载了操作符=,使m_wfx.formatTag=1;
[/Quote]
可是用MMIO的时候,formatTag为2的时候能打开的,而且可以播放,只是第二个代码不能打开。而且我没有重载=,
m_wfx = *(WAVEFORMATEX *)Temp;
只是为了将内存中的数据转化为WAVEFORMATEX结构。
也就是说在waveOutOpen时,两种代码传递的参数值是一样的,可是第二个返回失败。
瓶盒 2009-05-28
  • 打赏
  • 举报
回复
MMIO打开文件是为了播放,所以它要判断文件格式是否为支持的播放文件,formatTag为2的文件是它不支持的文件,所以无法打开。
第二种方式打开文件并不检查,但直接使用也是无法播放的,如果你能播放,我想应该是
m_wfx = *(WAVEFORMATEX *)Temp;
这一句你重载了操作符=,使m_wfx.formatTag=1;

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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