#include <d3dx9.h>
#include <dmusici.h>
#define SAFE_RELEASE(p)
{if(p){(p)->Release();(p)=NULL;}}//安全に解放する
//#define FileName "test.mid"
#define FileName "test.wav"
LPDIRECT3D9 g_pD3D = NULL;//Direct3D9
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;//レンダリングデバイス
LPD3DXFONT g_pFont = NULL;//フォント
// DirectMusicの変数
IDirectMusicPerformance8* g_pPerformance = NULL; // パフォーマンス
IDirectMusicLoader8* g_pLoader = NULL; // ローダー
IDirectMusicAudioPath8* g_pDefAudioPath = NULL; // デフォルト・オーディオパス
// DirectMusicのセグメント
IDirectMusicSegment8* g_pSegment = NULL; // セグメント
IDirectMusicSegmentState8* g_pSegmentState = NULL; // セグメントの状態
IDirectMusicSegmentState* ppSegmentState = NULL;
MUSIC_TIME g_SegLength = 0; // セグメントの長さ
//テキスト描画
void TextDraw(LPD3DXFONT pFont,char* text,int X,int Y)
{
RECT rect={X,Y,0,0};//描画位置
//スプライトポインタ(無くても良し),描画文字,文字数(-1で全部),描画範囲,フォーマット,色
pFont->DrawText(NULL, text, -1, &rect, DT_LEFT | DT_NOCLIP,
D3DCOLOR_ARGB(255, 0, 0, 0));
}
//Direct3D初期化
HRESULT InitD3D( HWND hWnd )
{
//Direct3Dを生成する
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION))){return E_FAIL;}
//デバイス生成用のパラメーター
D3DPRESENT_PARAMETERS d3dpp;//パラメーター構造体
ZeroMemory( &d3dpp, sizeof(d3dpp) );//ゼロで初期化
d3dpp.Windowed = TRUE;//ウインドウモードで起動
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//バックバッファのスワップエフェクト
Direct3Dにスワップエフェクトをまかせる
d3dpp.BackBufferFormat =
D3DFMT_UNKNOWN;//バックバッファのフォーマット今表示されているモニタの設定と同じ
d3dpp.BackBufferCount = 1;//バックバッファの数
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;//マルチサンプリングは行わない
d3dpp.MultiSampleQuality = 0;//マルチサンプリングは行わないので0
d3dpp.EnableAutoDepthStencil = TRUE;//Direct3Dに深度バッファの管理をまかせる
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;//深度バッファのフォーマット(通常はこの値で問題ない)
d3dpp.hDeviceWindow = hWnd;//カバーウィンドウ=アプリケーションのウィンドウ
d3dpp.Flags = 0;//フラグは使わない
d3dpp.FullScreen_RefreshRateInHz =
D3DPRESENT_RATE_DEFAULT;//今のリフレッシュレートをそのまま使う
d3dpp.PresentationInterval =
D3DPRESENT_INTERVAL_DEFAULT;//モニタの垂直回帰を待つ
//Direct3Dデバイスの生成 HAL(ハードウェアアクセラレーション)
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){
//HALが駄目ならHEL(ソフトウェアエミュレーション)
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){
//駄目なら終了
return(E_FAIL);
}
}
//フォントの生成 MSゴシック
//デバイス,文字高さ,文字幅,フォントスタイル,ミップマップのレベル,斜体にするかどうか,文字セット,出力精度,出力品質,フォントピッチとファミリ,フォント名,フォントポインタ
HRESULT hr = D3DXCreateFont( g_pd3dDevice, 20, 0, FW_HEAVY, 1, false,
SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS,
ANTIALIASED_QUALITY, FF_DONTCARE, "MS ゴシック", &g_pFont );
if FAILED(hr){return(E_FAIL);}
return S_OK;
}
//終了時解放処理
VOID Cleanup()
{
SAFE_RELEASE(g_pFont);
SAFE_RELEASE(g_pd3dDevice);
SAFE_RELEASE(g_pD3D);
CoUninitialize();
}
//レンダリング
VOID Render()
{
//デバイスが無いなら終了
if(NULL==g_pd3dDevice){return;}
//バックバッファのクリア
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );
//シーンの開始
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
//ここに処理内容を書く
MUSIC_TIME seg_seek = 0;
if(g_pSegmentState){g_pSegmentState->GetSeek(&seg_seek);}
char buf[255];
TextDraw(g_pFont,"MIDI,WAVEの再生:キーダウンで再生開始",0,0);
TextDraw(g_pFont,ltoa(seg_seek,buf,10),0,40);
//シーンの終了
g_pd3dDevice->EndScene();
}
//バックバッファを表画面に反映させる
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
//DirectMusic初期化
void DMInit(HWND* hWnd)
{
// パフォーマンスの作成
CoCreateInstance(CLSID_DirectMusicPerformance, NULL,
CLSCTX_INPROC, IID_IDirectMusicPerformance8,
(void**)&g_pPerformance );
// パフォーマンスの初期化
g_pPerformance->InitAudio(
NULL, // IDirectMusicインターフェイスは不要
NULL, // IDirectSoundインターフェイスは不要
*hWnd, // ウィンドウのハンドル
DMUS_APATH_SHARED_STEREOPLUSREVERB, // デフォルトのオーディオパス・タイプ
64, // パフォーマンス・チャンネルの数
DMUS_AUDIOF_ALL, // シンセサイザの機能
NULL); // オーディオ・パラメータにはデフォルトを使用
// デフォルト・オーディオパスの取得
g_pPerformance->GetDefaultAudioPath(&g_pDefAudioPath);
// ローダーの作成
CoCreateInstance(CLSID_DirectMusicLoader, NULL,
CLSCTX_INPROC, IID_IDirectMusicLoader8,
(void**)&g_pLoader);
// ローダーの初期化(検索パスをカレント・ディレクトリに設定)
CHAR strPath[MAX_PATH];
DWORD i = GetCurrentDirectory(MAX_PATH, strPath);
// マルチ・バイト文字をUNICODEに変換
WCHAR wstrSearchPath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, strPath, -1, wstrSearchPath,
MAX_PATH);
// ローダーに検索パスを設定
g_pLoader->SetSearchDirectory(GUID_DirectMusicAllTypes,
wstrSearchPath, FALSE);
}
//セグメント初期化
void InitSegment()
{
// セグメント作成
WCHAR wstrFileName[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, FileName, -1, wstrFileName, MAX_PATH);
g_pLoader->LoadObjectFromFile(CLSID_DirectMusicSegment,
IID_IDirectMusicSegment8,
wstrFileName,
(LPVOID*)&g_pSegment);
// セグメントの長さを取得
g_pSegment->GetLength(&g_SegLength);
// バンドのダウンロード(手動)
g_pSegment->Download( g_pPerformance );
}
//セグメント解放
void ReleaseSegment(void)
{
// 演奏停止
if(g_pPerformance){g_pPerformance->Stop(NULL, NULL, 0, 0);}
// 音色データのアンロード
if(g_pSegment){g_pSegment->Unload(g_pPerformance);}
// セグメントを開放
SAFE_RELEASE(g_pSegmentState);
SAFE_RELEASE(g_pSegment);
}
//DirectMusic解放
void ReleaseDMusic(void)
{
// ローダを開放
SAFE_RELEASE(g_pLoader);
// デフォルト・オーディオパスを開放
SAFE_RELEASE(g_pDefAudioPath);
// パフォーマンスを開放
SAFE_RELEASE(g_pPerformance);
}
//メッセージプロシージャ
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_KEYDOWN: // キーが押された
g_pPerformance->StopEx(g_pSegment,0,0);
g_pPerformance->PlaySegmentEx(g_pSegment, NULL, NULL,
NULL, 0, &ppSegmentState, NULL, g_pDefAudioPath);
ppSegmentState->QueryInterface(IID_IDirectMusicSegmentState8,(LPVOID
*)&g_pSegmentState);
break;
case WM_DESTROY://終了時
Cleanup();
PostQuitMessage(0);
return 0;
case WM_PAINT://ウインドウ描画時
Render();
return 0;
case WM_SIZE://ウインドウサイズ変更時
InvalidateRect(hWnd,NULL,true);//画面更新
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//メイン関数
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
//COM初期化
CoInitialize( NULL );
//ウインドウクラスの登録
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"Window1", NULL };
RegisterClassEx( &wc );
//タイトルバーとウインドウ枠の分を含めてウインドウサイズを設定
RECT rect;
SetRect(&rect,0,0,640,480);
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
rect.right=rect.right-rect.left;
rect.bottom=rect.bottom-rect.top;
rect.top=0;
rect.left=0;
//ウインドウの生成
HWND hWnd = CreateWindow( "Window1", "Hello DirectX9 World !!",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right,
rect.bottom,
NULL, NULL, wc.hInstance, NULL );
//Direct3D初期化
if(SUCCEEDED(InitD3D(hWnd)))
{
DMInit(&hWnd);
InitSegment();
//ウインドウ表示
ShowWindow(hWnd,SW_SHOWDEFAULT);
UpdateWindow(hWnd);
//メッセージループ
MSG msg;
while( GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
ReleaseSegment();
ReleaseDMusic();
UnregisterClass("Window1",wc.hInstance);
return 0;
}
|