.wavを再生する(DirectMusic)

DirectInput の時と同じようにウインドウハンドルさえ取得できれば
DirectMusic を freeglut と組み合わせて使用できます。
DirectMusic は現在は更新されておらず廃止予定?だそうです。
Windows7 では 32bit 版では DirectMusic を使用できますが
64bit 版にはありません。(XPモードなら使用できる?)
いずれにしても、DirectMusic を使い続ける事は推奨できません。

今回のプログラムは DirectX SDK August2007 の参照設定を
使用しています。

*(2014.3.28追記)
Windows8においてもWindows7同様の状態です。
尚、Visual Studio 2010からはディレクトリの参照設定を
プロジェクト毎に個別に設定しないといけないようになってしまいました。
面倒くさいですね。(^ω^;)
プロジェクトのプロパティで「C/C++」の「追加のインクルードディレクトリ」に
$(DXSDK_DIR)Include を追加するとビルドが通るようです。

ファイル
main.cpp
sample.wav (自分で用意して下さい)

main.cpp

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib,"dxguid.lib")
#include <windows.h>
#include <dmusici.h>

#include <GL/freeglut/freeglut.h>
#include <stdio.h>

#define FileName "sample.wav"
#define SAFE_RELEASE(p) {if(p){(p)->Release();(p)=NULL;}}//安全に解放する

#define WIDTH 320
#define HEIGHT 240

BYTE KeyTbl[256];

HWND hWnd2=NULL;        //ウィンドウハンドル
HINSTANCE hinstance;       //インスタンスのハンドル

// DirectMusicの変数
IDirectMusicPerformance8* Performance = NULL; // パフォーマンス
IDirectMusicLoader8* Loader = NULL;    // ローダー

// DirectMusicのセグメント
IDirectMusicSegment8* Segment = NULL;   // セグメント
MUSIC_TIME SegLength = 0;      // セグメントの長さ

//ウィンドウを検索してHWNDとHINSTANCEを得る
BOOL CALLBACK enumWindowsProc(HWND hWnd,LPARAM lParam)
{
 HANDLE hModule=(HANDLE)GetWindowLong(hWnd,GWL_HINSTANCE);

 if(GetModuleHandle(NULL)==hModule){
  wchar_t ClassName[256];
  GetClassNameW(hWnd,ClassName,sizeof(ClassName)/sizeof(ClassName[0]));
  if(wcsncmp(ClassName,L"FREEGLUT",wcslen(ClassName))==0){
   hWnd2=hWnd;
   hinstance=(HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE);
   return FALSE;
  }
 }
 return TRUE;
}

//フォントクラス
class GLFONT
{
public:
 HFONT Hfont;
 HDC Hdc;
 GLFONT(wchar_t *fontname, int size);
 void DrawStringW(int x,int y,wchar_t *format, ...);
};
//コンストラクタ フォント作成
GLFONT::GLFONT(wchar_t *fontname, int size)
{
 Hfont = CreateFontW(
        size,      //フォント高さ
        0,       //文字幅
        0,       //テキストの角度
        0,       //ベースラインとx軸との角度
        FW_REGULAR,     //フォントの太さ
        FALSE,      //イタリック体
        FALSE,      //アンダーライン
        FALSE,      //打ち消し線
        SHIFTJIS_CHARSET,   //文字セット
        OUT_DEFAULT_PRECIS,   //出力精度
        CLIP_DEFAULT_PRECIS,  //クリッピング精度
        ANTIALIASED_QUALITY,  //出力品質
        FIXED_PITCH | FF_MODERN, //ピッチとファミリー
        fontname);     //書体名

 Hdc = wglGetCurrentDC();
 SelectObject(Hdc, Hfont);
}
//ワイド文字列の描画
void GLFONT::DrawStringW(int x,int y,wchar_t *format, ...)
{
 wchar_t buf[256];
 va_list ap;
 int Length=0;
 int list=0;
 
 //ポインタがNULLの場合は終了
 if ( format == NULL )
  return;

 //文字列変換
 va_start(ap, format);
 vswprintf_s(buf, format, ap);
 va_end(ap);

 Length = wcslen(buf);
 list = glGenLists(Length);
 for( int i=0; i<Length; i++ ){
  wglUseFontBitmapsW(Hdc, buf[i], 1, list + (DWORD)i);
 }

 glDisable(GL_LIGHTING);
 glRasterPos2i(x, y);
 //ディスプレイリストで描画
 for( int i=0; i<Length; i++ )
 {
  glCallList(list + i);
 }
 glEnable(GL_LIGHTING);
 //ディスプレイリスト破棄
 glDeleteLists(list, Length);
 list = 0;
 Length = 0;
}

GLFONT *font;

//DirectMusic初期化
void DMInit()
{
 // パフォーマンスの作成
 CoCreateInstance(CLSID_DirectMusicPerformance, NULL,
        CLSCTX_INPROC, IID_IDirectMusicPerformance8,(void**)&Performance );

 // パフォーマンスの初期化
 Performance->InitAudio(
  NULL,      // IDirectMusicインターフェイスは不要
  NULL,      // IDirectSoundインターフェイスは不要
  hWnd2,      // ウィンドウのハンドル
  DMUS_APATH_SHARED_STEREOPLUSREVERB,  // デフォルトのオーディオパス・タイプ
  32,     // パフォーマンス・チャンネルの数
  DMUS_AUDIOF_ALL,    // シンセサイザの機能
  NULL);     // オーディオ・パラメータにはデフォルトを使用

 // デフォルト・オーディオパスの取得
// Performance->GetDefaultAudioPath(&DefAudioPath);

 // ローダーの作成
 CoCreateInstance(CLSID_DirectMusicLoader, NULL,
        CLSCTX_INPROC, IID_IDirectMusicLoader8,(void**)&Loader);

 // ローダーの初期化(検索パスをカレント・ディレクトリに設定)
 CHAR strPath[MAX_PATH];
 DWORD i = GetCurrentDirectoryA(MAX_PATH, strPath);

 // マルチ・バイト文字をUNICODEに変換
 WCHAR wstrSearchPath[MAX_PATH];
 MultiByteToWideChar(CP_ACP, 0, strPath, -1, wstrSearchPath, MAX_PATH);

 // ローダーに検索パスを設定
 Loader->SetSearchDirectory(GUID_DirectMusicAllTypes,wstrSearchPath, FALSE);
}

//セグメント初期化
void InitSegment()
{
 // セグメント作成
 WCHAR wstrFileName[MAX_PATH];
 MultiByteToWideChar(CP_ACP, 0, FileName, -1, wstrFileName, MAX_PATH);
 Loader->LoadObjectFromFile(CLSID_DirectMusicSegment,
            IID_IDirectMusicSegment8,wstrFileName,(LPVOID*)&Segment);
 
 // セグメントの長さを取得
 Segment->GetLength(&SegLength);

 // バンドのダウンロード(手動)
 Segment->Download( Performance );
}

void display(void)
{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
 font->DrawStringW(10,120,L"スペースキーで再生");
 glutSwapBuffers();
}
void idle(void)
{
 GetKeyboardState(KeyTbl);
 if(KeyTbl[VK_SPACE] & 0x80){
  Performance->Stop(NULL, NULL, 0, 0);
  Performance->PlaySegmentEx(Segment, NULL, NULL, 0, 0, NULL, NULL, NULL);
 }

 glutPostRedisplay();
}
void Init(){
 glClearColor(1.0, 1.0, 1.0, 1.0);
 glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);
 font = new GLFONT(L"MS明朝", 24);
 EnumWindows(enumWindowsProc,0);
 //COM初期化
 CoInitialize( NULL );
 DMInit();
 InitSegment();
}
void Release(){
  // 演奏停止
 Performance->Stop(NULL, NULL, 0, 0);

 // 音色データのアンロード
 Segment->Unload(Performance);

 // セグメントを開放
 SAFE_RELEASE(Segment);

 // ローダを開放
 SAFE_RELEASE(Loader);

 // パフォーマンスを開放
 SAFE_RELEASE(Performance);
 CoUninitialize();
 MessageBox(NULL,L"解放して終了します。",L"END",MB_OK);
    PostQuitMessage(0);
}

int main(int argc, char *argv[])
{
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(WIDTH, HEIGHT);
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
 glutCreateWindow("wavを再生");
 glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS);//メインループから戻ってくる設定
 glutDisplayFunc(display);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 Release();
 return 0;
}

 

最終更新:2015年01月02日 15:20
添付ファイル