大型WAV檔案的播放 (轉)
大型WAV的
在多的設計中經常要處理檔案,用提供的sndPlaySound可以實現小型WAV檔案的播放。但是當WAV檔案大於可用時,sndPlaySound函式就不能進行播放,那麼如何利用MCI播放大型檔案呢?本文將介紹一種方法。
Windows支援兩種RIFF(re interchange file format,“資源互動檔案格式”)音訊檔案:MIDI的D檔案和波形音訊檔案格式WAV檔案,本文將介紹如何用MCI命令播放大型WAV檔案。
用sndPlaySound播放音訊檔案只需要一行程式碼。比如實現非同步播放的方法為
sndPlaySound("c:windowsding.wav",SND_ASYNC);
由此可以看到,sndPlaySound的使用是很簡單的。但是用sndPlaySound播放音訊檔案有一個限制,即整個音訊檔案必須全部調入可用的實體記憶體。因此應用sndPlaySound播放的音訊檔案相對較小,最大約100K。要播放大一些的音訊檔案(在多媒體設計中是經常要遇到的情況)需要使用MCI的功能。
本文建立了一個Cwave類,可以處理播放音訊的MCI命令,因為該類能夠很多的MCI命令和建立了資料結構,所以只需要簡單的成員函式(如OpenDevice, CloseDevice, Play和Stop)。在CWave類中抽象了特定的MCI命令和資料結構,只含幾個簡單的成員函式OpenDevice, CloseDevice, Play和Stop。波形音訊裝置是一個複合裝置,如果開啟波形裝置,然後開啟並關閉每個波形元素,最後關閉波形裝置,這樣可以使得播放更好。Cwave::OpenDevice就可以開啟波形裝置,OpenDevice將MCI_OPEN命令傳遞給mciSendCommand函式,如果呼叫成功,就用資料結構MCI_OPEN_PARMS的wDeviceID成員返回波形裝置的識別符號,該識別符號儲存在一個供以後使用的私有資料成員中。
一旦開啟了Cwace,透過Cwace::Play播放WAV檔案就就緒了,WAV檔名和一個視窗指標被傳遞給Play方法以便將MCI通知訊息傳送到制定的視窗。
WAV檔案的播放分為兩步。首先要透過分配一個MCI_OPEN_PARMS結構並給所要播放的WAV檔案設定lpstrElementName成員開啟WAV檔案。將該結構和MCI_OPEN傳遞給mciSendCommand,開啟WAV檔案並用MCI_OPEN_PARMS結構的wDeviceID成員返回元素識別符號。
第二步是命令波形音訊裝置播放WAV檔案。分配了MCI_PLAY_PARMS結構並將dwCallback成員設定為視窗控制程式碼。如果要同步播放音訊波形檔案,就增加MCI_WAIT標誌並跳過視窗控制程式碼。這樣做會使應用在mciSendCommand函式返回之前等待WAV檔案播放完畢。最可能的情況是非同步播放大型WAV檔案,可以象下面那樣指定MCI_NOTIFY標誌並設定dwCallback成員做到這一點。
MCI_PLAY_PARMS mciPlayParms;
MciPlayParms.dwCallback=(D)pWnd->m_hWnd;
DwResult=mciSendCommand(m_nDevice,MCI_PLAY,MCI_NOTIFY,
(DWORD)(LPVOID)&mciPlayParms);
這樣就開始了WAV檔案的播放,並且在播放完畢後,MM_MCINOTIFY訊息會傳送到指定的視窗,圖1給出了一個WAV檔案播放所發生的事件序列:(1)命令播放WAV檔案並立即返回;(2)播放WAV檔案;(3)完成後傳送通知訊息。
圖1 播放WAV檔案
完成播放後關閉WAV檔案元素是程式設計師的責任,簡單的呼叫Cwave類的Stop成員函式就可以了。Stop成員函式將WAV檔案識別符號和MCI_CLOSE命令傳遞給mciSendCommand函式,不必為該命令分配一個MCI結構,下述程式碼關閉了WAV檔案
mciSendCommand(m)nElement,MCI_CLOSE,NULL,NULL);
播放完所有的WAV檔案後必須關閉波形音訊裝置,Cwave類的解構函式呼叫Cwave::CloseDevice自動完成。
將本文中介紹的CWave類加入到自己的程式中,就可以方便的應用它播放音訊檔案了。
//建立Cwave類,放在Wave.h檔案中
class CWave:public C
{
//Construction
public:
CWave();
virtual ~CWave();
//Operations
public:
DWORD OpenDevice();
DWORD CloseDevice();
DWORD Play(CWnd *pParentWnd,LPCSTR pFileName);
DWORD Stop();
//Implementation
protected:
void DisrorMsg(DWORD dwError);
//Members
protected:
MCVICEID m_nDeviceID;
MCIDEVICEID m_nElementID;
};
//Cwave類的實現程式碼,Cwave.cpp
#include
#include "cwave.h"
CWave::CWave()
{
m_nDeviceID=0;
m_nElementID=0;
}
CWave::~CWave()
{
if(m_nElementID)
Stop();
if(m_nDeviceID)
CloseDevice();
}
DWORD CWave::OpenDevice()
{
DWORD dwResult=0;
if (m_nDeviceID)
MCI_OPEN_PARMS mciOpenParms;
mciOpenParms.lpstrDeviceType=(LPSTR)MCI_DEVTYPE_WAVEFORM_AUDIO;
//open the wave device
dwResult=mciSendCommand(NULL,MCI_OPEN,
MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_WAIT,
(DWORD)(LPVOID)&mciOpenParms);
//save device identifier,will use eith other MCI commands
m_nDeviceID=mciOpenParms.wDeviceID;
//display error message if failed
if(dwResult)
DisplayErrorMsg(dwResult);
}
//return result of MCI operation
return dwResult;
}
DWORD CWave::CloseDevice()
{
DWORD dwResult=0;
//close if currently open
if(m_nDeviceID)
{
//close the MCI device
dwResult=mciSendCommand(m_nDeviceID,MCI_CLOSE,NULL,NULL);
//display error message if failed
if(dwResult)
DisplayErrorMsg(dwResult);
//set identifier to close state
else
m_nDeviceID=0;
}
//return result of MCI operation
return dwResult;
}
DWORD CWave::Play(CWnd* pWnd,LPCSTR pFileName)
{
MCI_OPEN_PARMS mciOpenParms;
//initialize structure
memset(&mciOpenParms,0,sizeof(MCI_OPEN_PARMS));
//set the WAV file name to be played
mciOpenParms.lpstrElementName=pFileName;
//first open the device
DWORD dwResult=mciSendCommand(m_nDeviceID,MCI_OPEN,
MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOpenParms);
//display error message if failed
if(dwResult)
DisplayErrorMsg(dwResult);
//if succesul,instruct the device to play the WAV file
else
{
//save element indentifier
m_nElementID=mciOpenParms.wDeviceID;
MCI_PLAY_PARMS mciPlayParms;
//set the window that will receive notification message
mciPlayParms.dwCallback=(DWORD)pWnd->m_hWnd;
//instruct device to play file
dwResult=mciSendCommand(m_nElementID,MCI_PLAY,
MCI_NOTIFY,(DWORD)(LPVOID)&mciPlayParms);
//display error and close element if failed
if(dwResult)
{
DisplayErrorMsg(dwResult);
Stop();
}
}
//return result of MCI operation
return dwResult;
}
DWORD CWave::Stop()
{
DWORD dwResult=0;
//close if element is currently open
if(m_nElementID)
{
dwResult=mciSendCommand(m_nElementID,MCI_CLOSE,NULL,NULL);
//display error message if failed
if(dwResult)
DisplayErrorMsg(dwResult);
//set identifier to closed state
else
m_nElementID=0;
}
return dwResult;
}
void CWave::DisplayErrorMsg(DWORD dwError)
{
//check if there was an error
if(dwError)
{
//character string that contains error message
char szErrorMsg[MAXERRORLENGTH];
//retrieve string associated error message
if(!mciGetErrorString(dwError,szErrorMsg,sizeof(szErrorMsg)))
strcpy(szErrorMsg,"Unknown Error");
//display error string in message box
AfxMessageBox(szErrorMsg);
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988069/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何播放 WAV 檔案?
- 【C#學習筆記】播放wav檔案C#筆記
- wav檔案的檔案頭
- 將WAV檔案做到EXE檔案的方法及注意事項 (轉)
- VC++5.0下MIDI、WAV及CD的播放 (轉)C++
- Laravel 專案中 PCM 音波檔案轉 WAV 音訊檔案案例【經驗分享】Laravel音訊
- WAV音訊檔案按秒切片段音訊
- pcm 轉 wav 工具
- VCD結構與Mplayer播放.DAT檔案(轉)
- 大型檔案去重
- 基於MFC的大型資料檔案處理方法 (轉)
- 【秒懂音視訊開發】12_播放WAV
- WAV音訊檔案中隱藏惡意軟體音訊
- 在網頁中使用realplayer播放rm檔案 (轉)網頁
- android播放swf檔案Android
- ape轉wav音質會損失嗎 怎麼將ape格式轉換成wav
- 播放嵌入資源的聲音檔案
- 藉助XNA Framework,讓Silverlight播放wav音訊Framework音訊
- 用Media Player 播放 mpg檔案
- 利用ATL實現QuickTime多媒體檔案播放 (轉)UI
- 超大型的檔案資料如何傳輸?
- 大型專案開發: 標頭檔案順序
- Win10系統怎麼播放AVI格式檔案_win10如何使用自帶播放器播放avi格式檔案Win10播放器
- 如何在Android上播放swf檔案Android
- 播放SD卡上全部音訊檔案SD卡音訊
- 多平臺大型檔案系統比較
- ASM 檔案與本地檔案的轉換ASM
- 解決MPLAYER播放不了多媒體檔案的方法。
- win10 xv檔案用什麼播放器開啟_win10系統xv檔案用哪個播放器可以播放Win10播放器
- win10自帶的播放器不可以播放rmvb檔案的解決方法Win10播放器
- PCM與WAV
- COFF檔案的格式 (轉)
- 大型SI類系統研發中的專案管理(轉)專案管理
- 分析:大型ERP專案實施的組織方法(轉)
- 設計一個健壯的大型檔案下載系統
- GBFF檔案轉GFF檔案
- (線上等)請問怎樣才能將WAV聲音檔案存入MYSQL資料庫中?MySql資料庫
- python mp3 轉 wav 以及 FFmpeg 媒體轉換神器Python