VC++5.0下MIDI、WAV及CD的播放 (轉)

worldblog發表於2007-12-06
VC++5.0下MIDI、WAV及CD的播放 (轉)[@more@]

VC++5.0下MIDI、WAV及CD的

武漢石化設計院電算室
周紅漢

---- 加入是增強應用功能的所有方法中最簡單的一個。幾乎每個遊戲或多 程式都以某種MIDI或CD音樂為背景。音樂可以使心情愉快;在合適的場合播 放恰當的音樂能夠使程式設計師和他的VC++程式煥發光彩。

第一部分 MIDI的播放

---- 樂器數字化介面(MIDI)是由音樂界的一些大公司(包括生產電子音樂合成器的公司) 制訂的一項,後來被計算機產業所採用併成為多媒體音樂的標準格式。MIDI檔案 一般較小,對裝置的要求高。

---- 一、 原理

---- 雖然支援MIDI檔案,然而Visual C++或MFC並沒有建立任何來實現 這種支援,但是MicroSoft 提供了三種不同的方法來實現MIDI的播放:

  • MCI(The Media Control Interface)。這是最基本的方法,本文將詳細討論這種方法。
  • 流緩衝器。這種格式允許應用程式為MIDI資料分配緩衝器。在需要精確控制MIDI播放的時候,流緩衝器將很有用處。
  • 低階MIDI裝置。需要完全控制MIDI資料的應用程式可以使用這種方法。

---- MCI可以透過mciSendCommand()和mciSendString()來完成,本文僅使用mciSendCommand()。

---- 原型:D mciSendCommand(UINT wDeviceID,UINT wMessage,DWORD dwParam1,DWORD dwParam2);

引數: wDeviceID:接受訊息的裝置ID wMessage:MCI命令訊息 dwParam1:命令的標誌位 dwParam2:所使用引數塊的指標


---- 返值:成功,返回零;否則,返回雙字中的低字存放有錯誤資訊。

二MIDI的播放控制

---- 1. 開啟裝置

MCI_OPEN_PARMS OpenParms; OpenParms.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_SEQUENCER;//MIDI型別 OpenParms.lpstrElementName = (LPCSTR) Filename; OpenParms.wDeviceID = 0; mciSendCommand (NULL, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT, (DWORD)(LPVOID) &OpenParms)


---- MCI裝置ID指明開啟了哪個裝置,當傳送了MCI_OPEN命令時,這個值在引數塊中返回——應被儲存備用。

---- 2. 關閉裝置

mciSendCommand (m_wDeviceID, MCI_CLOSE, NULL, NULL);


---- 3. 播放

MCI_PLAY_PARMS PlayParms; PlayParms.dwFrom = 0; // 指定從什麼地方(時間)播放 mciSendCommand (m_wDeviceID, MCI_PLAY, MCI_FROM, (DWORD)(LPVOID) &PlayParms));


---- 4. 暫停

MCI_PLAY_PARMS PlayParms; mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &PlayParms);


---- 5. 停止

mciSendCommand (m_wDeviceID, MCI_STOP, NULL, NULL);


---- 6. 跳躍

* 跳轉到任意地方 MCI_SEEK_PARMS SeekParms; SeekParms.dwTo = (nMinute * 60 + nSecond) * 1000; //跳轉的目標時間,時間單位為毫秒 mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO | MCI_WAIT,(DWORD)(LPVOID) &SeekParms); * 跳到檔案頭 mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_START, NULL); * 跳到檔案尾 mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_END, NULL);


---- 7. 查詢當前資訊

MCI_STATUS_PARMS StatusParms; StatusParms.dwItem = MCI_SEQ_STATUS_DIVTYPE; mciSendCommand (m_wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)(LPVOID) &StatusParms);返回資訊存放於StatusParms.dwReturn中。 MCI_STATUS標誌 MCI_STATUS_LENGTH 獲得檔案長度 MCI_STATUS_MODE 獲得檔案播放的當前狀態 MCI_STATUS_POSITION 獲得檔案播放的當前位置 MCI_STATUS_TIME_FORMAT 獲得當前的時間格式 MCI_SEQ_STATUS_DIVTYPE 判斷檔案是PPQN型別還是SMPTE型別 MCI_SEQ_STATUS_TEMPO 獲得當前播放速度,PQRN型別,此值為節拍/分,SMPTE型別,此值為禎/秒


---- 8. 設定時間格式及播放速度

MCI_SET_PARMS SetParms; SetParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS; //設定時間單位為毫秒 mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &SetParms); MCI_SEQ_SET_TEMPO 設定播放速度, PQRN型別,此值為節拍/分, SMPTE型別,此值為禎/秒


第二部分 WAV檔案的播放

---- 一、原理

---- MicroSoft API提供了三種不同的方法來實現WAV的播放:

  • PlaySound()函式。它可以透過單行編碼來播放Wave格式的。此函式有兩個限制:必須將聲音資料完整地載入物理;資料格式必須被所的某一器支 持。根據,PlaySound()適用於100K以下的檔案。
  • MCI(The Media Control Interface),與上一章播放MIDI檔案相似,可以播放100K 以上的檔案。
  • 低階Wave音訊裝置。用這些裝置可以執行完全控制Wave資料的應用檔案。

---- 二、 WAV檔案播放控制

---- 因為同樣使用MCI,與上一章相同,只列出不同的部分。

---- 1. 開啟裝置

---- 將MIDI的MCI_DEVTYPE_SEQUENCER 改為"waveaudio"

---- 2. 錄音

MCI_RECORD_PARMS RecordParms; mciSendCommand (m_wDeviceID, MCI_RECORD, NULL, (DWORD)(LPVOID) &RecordParms);


---- 3. 儲存錄音

MCI_SAVE_PARMS SaveParms; SaveParms.lpfilename = (LPCSTR) Filename; mciSendCommand (m_wDeviceID, MCI_SAVE, MCI_SAVE_FILE | MCI_WAIT, (DWORD)(LPVOID) &SaveParms);


第三部分 CD的播放

---- CD的獨特優勢在於,它由作曲家設計,並由音樂廠家生產。不同的計算機播放MIDI 檔案時,聲音效果也不一樣,但是CD的聲音效果總是相同的。高品質的音訊對計算機用 戶產生的效果會使你感到吃驚。 我們依然採用MCI播放CD,大部分的播放控制與前兩部分相同,只列出不同的部分

---- 1. 開門

mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, NULL);


---- 2. 關光碟機門

mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, NULL);


---- 3. 開啟裝置

將MIDI的MCI_DEVTYPE_SEQUENCER 改為MCI_DEVTYPE_CD_AUDIO


---- 4. 播放

---- 指定播放起點必須經過MCI_MAKE_TM(Track,Minute,Second,Frame)轉化

---- 5. 查詢當前資訊

MCI_STATUS_CURRENT_TRACK 得到當前曲目 MCI_STATUS_LENGTH 得到CD或指定曲目長度 MCI_STATUS_MODE 得到驅動器的當前狀態 MCI_STATUS_NUMBER_OF_TRACKS 得到CD曲目的數目 MCI_STATUS_POSITION 得到當前格式下的位置 MCI_STATUS_READY 檢查裝置是否就緒 MCI_STATUS_TIME_FORMAT 得到當前時間格式 MCI_STATUS_MEDIA_PRESENT 檢查以確認CD是否在驅動器內 MCI_CDA_STATUS_TYPE_TRACK 檢查已確認某曲目是否為音訊曲目


---- 注意:

  • 使用MCI_STATUS_LENGTH引數查詢CD 及曲目長度,返回值透過呼叫MCI_MSF_MINUTE(),MCI_MSF_SECOND()轉換為分、秒。
  • MCI_STATUS_POSITION引數返回值呼叫MCI_TMSF_TRACK(), MCI_TMSF_MINUTE(), MCI_TMSF_SECOND(),MCI_TMSF_FRAME才能得到當前的位置的道、分、秒、幀。

---- 6. 跳躍

---- 跳轉的目標必須經過MCI_MAKE_TMSF(Track,Minute,Second,Frame)轉化最好將上述三種格式分開建類,或做成動態連線庫。在 Project-- >Setting-- >Link-- >/library modules中加入winmm.lib,源程式中包含

---- MCI呼叫簡單,功能強大,可以滿足日常多媒體的基本需要。但是,MCI一次只能播放一個檔案,使用DirectSound技術可以實現八個以上WAV檔案的同時播放。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988957/,如需轉載,請註明出處,否則將追究法律責任。

相關文章