|
描画ができたら次は音を再生したいと思うのが自然な流れです #pragma comment(lib,"winmm.lib") ただ鳴らすだけなら PlaySound(WAVEファイル名, NULL, SND_FILENAME | SND_ASYNC); ファイルの読み込みを毎回行うせいで遅い上 細かい制御やmp3やAVIなどのマルチメディアを取り扱うには 今回は3つのコードファイルが必要です MCI.hです //--------------------------------------------//
// ファイル名:MCI.h
// 概要: 音ファイル再生関係
//
// 作成者:Daiki Terai
// 作成日:2010/10/23
// 修正履歴:
//--------------------------------------------//
#ifndef _MCI_H_
#define _MCI_H_
#include <windows.h>
#include <tchar.h>
#pragma comment(lib, "winmm.lib")
// メディアタイプ
enum EMEDIA
{
WAVE,
MIDI,
MP3,
CD_AUDIO,
AVI
};
// MCIクラス
class CMCI
{
private:
MCIDEVICEID m_ID; // ID
public:
CMCI();
virtual ~CMCI();
// メディアを開く
bool Open(const TCHAR* FileName,EMEDIA Media);
//-------------------------------------------------------------------//
// 再生
// ループ再生するときは通知メッセージ処理するので
// ウィンドウハンドルを渡すこと
//
// 引数: bLoop ループ再生フラグ
// hWnd 処理終了通知メッセージを受け取るウィンドウハンドル
//-------------------------------------------------------------------//
void Play(bool bLoop = false,HWND hWnd = NULL);
// 停止
void Stop();
// 巻き戻し
void Rewind();
// 一時停止
void Pause();
// 一時停止解除
void Resume();
// 現在位置取得
DWORD GetPos();
// 再生時間取得
DWORD GetLength();
// 閉じる
void Close();
};
#endif
MCI.cppです // MCI.cpp
#define _CRT_SECURE_NO_WARNINGS // 警告抑制用
#define _CRT_NON_CONFORMING_SWPRINTFS // 警告抑制用
#include "MCI.h"
CMCI::CMCI():m_ID(0)
{}
CMCI::~CMCI(){
this->Stop();
this->Close();
}
// メディアを開く
bool CMCI::Open(const TCHAR* FileName,EMEDIA Media){
MCI_OPEN_PARMS MCIOpen = {}; // 開く用
switch(Media){
case WAVE:
{
MCIOpen.lpstrDeviceType = _T("WaveAudio");
break;
}
case MIDI:
{
MCIOpen.lpstrDeviceType = _T("Sequencer");
break;
}
case MP3:
{
MCIOpen.lpstrDeviceType = _T("MPEGVideo");
break;
}
case CD_AUDIO:
{
MCIOpen.lpstrDeviceType = _T("CDAudio");
break;
}
case AVI:
{
MCIOpen.lpstrDeviceType = _T("avivideo");
break;
}
}
MCIOpen.lpstrElementName = FileName;
if(mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD_PTR)&MCIOpen) != 0){
TCHAR Buf[MAX_PATH] = {};
_stprintf(Buf,_T("%sが開けませんでした"),FileName);
MessageBox(NULL,Buf,NULL,MB_OK);
return false;
}
m_ID = MCIOpen.wDeviceID;
// ミリ秒単位に設定
MCI_SET_PARMS MCISet = {};
MCISet.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
mciSendCommand(m_ID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&MCISet);
return true;
}
//-------------------------------------------------------------------//
// 再生
// ループ再生するときは通知メッセージ処理するので
// ウィンドウハンドルを渡すこと
//
// 引数: bLoop ループ再生フラグ
// hWnd 処理終了通知メッセージを受け取るウィンドウハンドル
//-------------------------------------------------------------------//
void CMCI::Play(bool bLoop,HWND hWnd)
{
if(bLoop){
MCI_PLAY_PARMS MCIPlay = {}; // MCI再生設定
MCIPlay.dwCallback = (DWORD_PTR)hWnd;// MM_NOTIFYメッセージを受け取るウィンドウ
mciSendCommand(m_ID,MCI_PLAY, MCI_NOTIFY,(DWORD_PTR)&MCIPlay);
}
else{
mciSendCommand(m_ID,MCI_PLAY, 0,0);
}
}
// 停止
void CMCI::Stop(){
mciSendCommand(m_ID,MCI_STOP,0,0);
}
// 巻き戻し
void CMCI::Rewind(){
mciSendCommand(m_ID,MCI_SEEK,MCI_SEEK_TO_START,0);
}
// 一時停止
void CMCI::Pause(){
mciSendCommand(m_ID,MCI_PAUSE,0,0);
}
// 一時停止解除
void CMCI::Resume(){
mciSendCommand(m_ID,MCI_RESUME,0,0);
}
// 閉じる
void CMCI::Close(){
MCI_GENERIC_PARMS MCIGeneric = {}; // データ
mciSendCommand( m_ID, MCI_CLOSE, 0, (DWORD_PTR)&MCIGeneric);
}
MCIを制御するにはmciSendCommand関数を使います MCIERROR mciSendCommand( MCIDEVICEID IDDevice, // デバイス識別子 UINT uMsg, // コマンドメッセージ DWORD fdwCommand, // フラグ DWORD dwParam // パラメータを保持している構造体 ); デバイス識別子というのはメディアのIDのことです メディアを開くには if(mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD_PTR)&MCIOpen) != 0){
TCHAR Buf[MAX_PATH] = {};
_stprintf(Buf,_T("%sが開けませんでした"),FileName);
MessageBox(NULL,Buf,NULL,MB_OK);
return false;
}
オープンに成功したら一意なIDが m_ID = MCIOpen.wDeviceID; 時間の単位をミリ秒に設定します // ミリ秒単位に設定
MCI_SET_PARMS MCISet = {};
MCISet.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
mciSendCommand(m_ID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&MCISet);
再生箇所は次のようになっています //-------------------------------------------------------------------//
// 再生
// ループ再生するときは通知メッセージ処理するので
// ウィンドウハンドルを渡すこと
//
// 引数: bLoop ループ再生フラグ
// hWnd 処理終了通知メッセージを受け取るウィンドウハンドル
//-------------------------------------------------------------------//
void CMCI::Play(bool bLoop,HWND hWnd)
{
if(bLoop){
MCI_PLAY_PARMS MCIPlay = {}; // MCI再生設定
MCIPlay.dwCallback = (DWORD_PTR)hWnd;// MM_NOTIFYメッセージを受け取るウィンドウ
mciSendCommand(m_ID,MCI_PLAY, MCI_NOTIFY,(DWORD_PTR)&MCIPlay);
}
else{
mciSendCommand(m_ID,MCI_PLAY, 0,0);
}
}
ここでループ再生させるときは、ウィンドウにメディアの再生が終了したときを知らせなければなりません main.cppです #include "MCI.h" #include <tchar.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <windowsx.h> #include <commctrl.h> #pragma comment(lib,"comctl32.lib") #pragma comment(lib,"winmm.lib") // MCI CMCI g_Media[2]; メッセージ処理部分です //------------------------------------------------------//
// ウィンドウ作成メッセージ処理
//
// 引数: hWnd ウィンドウハンドル
// lpCreateStruct ウィンドウ作成情報
//------------------------------------------------------//
BOOL OnCreate(HWND hWnd,LPCREATESTRUCT lpCreateStruct){
g_Media[0].Open(_T("あぶないおにいちゃんです.mp3"),MP3);
g_Media[1].Open(_T("ゆっくりしていってね.wav"),WAVE);
g_Media[0].Play(true,hWnd);
g_Media[1].Play();
return TRUE;
}
//------------------------------------------------------//
// ウィンドウ破棄メッセージ処理
//
// 引数: hWnd ウィンドウハンドル
//------------------------------------------------------//
void OnDestroy(HWND hWnd){
PostQuitMessage(0);
}
//-----------------------------------------------------//
// ウィンドウプロシージャ
// デフォルトの処理はDefWindowProc関数で行う
//
// 引数: hWnd ウィンドウハンドル
// msg メッセージ
// wParam パラメータ
// lParam パラメータ
//
// 戻り値:処理結果
//-----------------------------------------------------//
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
HANDLE_MSG(hWnd,WM_CREATE,OnCreate);
// MCI処理終了通知メッセージ
case MM_MCINOTIFY:{
MCI_PLAY_PARMS mciPlay;
// 通知メッセージ失敗
if (wParam != MCI_NOTIFY_SUCCESSFUL)
return 0;
// 初期位置に戻す
mciSendCommand((MCIDEVICEID)lParam, MCI_SEEK, MCI_SEEK_TO_START, 0);
mciPlay.dwCallback = (DWORD_PTR)hWnd;
// ループ再生
mciSendCommand((MCIDEVICEID)lParam, MCI_PLAY, MCI_NOTIFY, (DWORD_PTR)&mciPlay);
return 0;
}
HANDLE_MSG(hWnd,WM_DESTROY,OnDestroy);
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
ウィンドウ作成時にWM_CREATEというメッセージが1度だけ送られてきます HANDLE_MSG(hWnd,WM_CREATE,OnCreate); 今回は初期化時にメディアをオープンし、再生してます g_Media[0].Open(_T("あぶないおにいちゃんです.mp3"),MP3);
g_Media[1].Open(_T("ゆっくりしていってね.wav"),WAVE);
g_Media[0].Play(true,hWnd);
g_Media[1].Play();
再生終了したときループ再生フラグを立てているメディアには // MCI処理終了通知メッセージ
case MM_MCINOTIFY:{
MCI_PLAY_PARMS mciPlay;
// 通知メッセージ失敗
if (wParam != MCI_NOTIFY_SUCCESSFUL)
return 0;
// 初期位置に戻す
mciSendCommand((MCIDEVICEID)lParam, MCI_SEEK, MCI_SEEK_TO_START, 0);
mciPlay.dwCallback = (DWORD_PTR)hWnd;
// ループ再生
mciSendCommand((MCIDEVICEID)lParam, MCI_PLAY, MCI_NOTIFY, (DWORD_PTR)&mciPlay);
return 0;
}
全ソースコードと音ファイルは下からダウンロードしてください ソースファイルと音ファイルは
|