ドラムリズム音をMIDI音源で鳴らす(C/C++版)
ドラムリズム音をMIDI音源で鳴らすサンプルです。
サンプルの実行画面
ソースコード
[Sample5.c]
//-------------------------------------------------------------------------------------- // ■ドラムリズム音をMIDI音源で鳴らす■ Sample NO.5 // //-------------------------------------------------------------------------------------- //リンクの設定 //リンクにwinmm.libを追加して下さい。 //MIDIファイルを作成したい場合はDelphiコーナーの「裏テクニック&貴重なプログラム」の //「MIDIセーバー」をご覧下さい。(Delphi言語が必要) 当然フリーソフトです。 #include <windows.h> //ボタンのID #define ID_Open_Hi_Hat 1500 #define ID_Close_Hi_Hat 1502 #define ID_Pedal_Hi_Hat 1503 #define ID_Crash_Cymbal1 1504 #define ID_Crash_Cymbal2 1505 #define ID_Ride_Cymbal1 1506 #define ID_Ride_Cymbal2 1507 #define ID_Splash_Cymbal 1508 #define ID_Side_Stick 1509 #define ID_Hi_Tom 1510 #define ID_Midle_Hi_Tom 1511 #define ID_Midle_Lo_Tom 1512 #define ID_Lo_Tom 1513 #define ID_Hi_Floor_Tom 1514 #define ID_Lo_Floor_Tom 1515 #define ID_Sunea1 1516 #define ID_Sunea2 1517 #define ID_Bass_Dora1 1518 #define ID_Bass_Dora2 1519 //グローバル変数 HMIDIOUT *hMIDI; //MIDIポートハンドル //コールバックプロシージャ LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam); //------------------------------------------------------ //■関数 MIDIPaly //■用途 MIDI音源を使用して音を鳴らす(リズム音色マップ編) //■引数 // Value...楽器NO.35-81まで(GMレベル1規格) //------------------------------------------------------ void MIDIPaly(DWORD Value) { DWORD _Time; //出力リセット midiOutReset(hMIDI); //音を発音 midiOutShortMsg(hMIDI, 0x7F0099 + (Value * 0x100)); //音を伸ばす(本当はマウスイベントなどでやる方が良いが面倒なのでこれにする) _Time= GetTickCount(); while (300>=GetTickCount()-_Time); midiOutShortMsg(hMIDI, 0x7F0089 + (Value*0x100)); } //------------------------------------------------------ //■関数 ScreenCenterX(ローカル) //■用途 ウインドウを中央にする為にX座標(LEFT)を算出する //■引数 // Width ...ウインドウの横幅 //------------------------------------------------------ int ScreenCenterX(int Width) { int X; X = (GetSystemMetrics(SM_CXSCREEN)- Width) / 2; if (X<0) X=0; return(X); } //------------------------------------------------------ //■関数 ScreenCenterY(ローカル) //■用途 ウインドウを中央にする為にY座標(TOP)を算出する //■引数 // Height ...ウインドウの縦幅 //------------------------------------------------------ int ScreenCenterY(int Height) { int Y; Y= (GetSystemMetrics(SM_CYSCREEN)- Height) / 2; if (Y<0) Y=0; return(Y); } //------------------------------------------------------ //■関数 CreateMainWindow(ローカル) //■用途 メインウインドウを作成する //■引数 // Width ...ウインドウの横幅 // Height ...ウインドウの縦幅 // Caption ...タイトル名 // hInstance ...インスタンスハンドル // nCmdShow ...ウインドウの表示形態 // lpfnWndProc...コールバックプロシージャ // dwstyle ...ウインドウスタイル // dwExstyle ...拡張ウインドウスタイル // MenuID ...メニューのID // hIcon ...アイコン //■戻り値 // ウインドウのハンドル //------------------------------------------------------ HWND CreateMainWindow(int Width,int Height,LPCTSTR Caption,HINSTANCE hInstance,int nCmdShow,WNDPROC lpfnWndProc, DWORD dwstyle,DWORD dwExstyle,LPCTSTR MenuID,HICON hIcon) { HWND hWnd; //メインウインドウのハンドル WNDCLASS myClass; //WNDCLASS構造体 //WNDCLASS構造体を0で初期化 ZeroMemory(&myClass,sizeof(WNDCLASS)); //--->WNDCLASS構造体の設定&ウインドウクラスの登録 //ウインドウスタイルを設定 myClass.style =CS_HREDRAW | CS_VREDRAW; //コールバックプロシージャへのポインタ myClass.lpfnWndProc = lpfnWndProc; //インスタンスハンドルを設定 myClass.hInstance =hInstance; //カーソルの設定(Windows標準リソースを使用) myClass.hCursor =LoadCursor(NULL, IDC_ARROW); //ウインドウの背景を設定(デフォルトカラー) myClass.hbrBackground =(HBRUSH)COLOR_WINDOW; //クラス名の設定(Borland Delphi風) myClass.lpszClassName ="TForm"; //アイコンの指定 myClass.hIcon =hIcon; //メニューの設定 myClass.lpszMenuName=MenuID; //ウィンドウ クラスを登録 RegisterClass(&myClass); //--->ウインドウの作成&表示 //メインウインドウの生成 hWnd = CreateWindowEx( //拡張ウインドウスタイル dwExstyle, //登録されたクラス名のアドレス "TForm", //ウインドウ名 Caption, //ウインドウスタイルを設定 dwstyle, //X座標の位置設定 ScreenCenterX(Width), //Y座標の位置設定 ScreenCenterY(Height), //横幅を設定 Width, //縦幅を設定 Height, //親ウインドウを設定 NULL, //メニューを設定 NULL, //インスタンスを識別 hInstance, //作成したウインドウに渡すデータへのポインタ NULL); //ウインドウの表示(表示方法はnCmdShowに従う) ShowWindow(hWnd, nCmdShow); return(hWnd); } //------------------------------------------------------ //■関数名 ControlCreate //■用途 ウインドウ(コントロール)を作成 //■引数 // hwndParent ...親ウインドウのハンドル // Left ...作成するウインドウの左隅のX座標 // Top ...作成するウインドウの左隅のY座標 // Width ...作成するウインドウの横幅 // Height ...作成するウインドウの縦幅 // dwExStyle ...ウインドウの拡張フラグ // dwFlag ...ウインドウの作成フラグ // Caption ...作成するウインドウのキャプション // ClassName ...作成するウインドウクラス名 // ChildID ...子ウインドウの識別子 // hInstance ...インスタンスハンドル //■戻り値 // 子ウインドウのハンドル //------------------------------------------------------ HWND CreateControlWindow(HWND hwndParent, int Left, int Top,int Width, int Height,int dwExStyle ,int dwFlag ,LPCTSTR Caption, LPCTSTR ClassName,HMENU ChildID,HINSTANCE hInstance) { return CreateWindowEx(dwExStyle,ClassName,Caption,WS_CHILD | WS_VISIBLE | dwFlag , Left, Top, Width, Height, hwndParent, ChildID, hInstance, NULL); } //-------------------------------------------------------- //■関数 WinMain //■用途 メインの関数 //■引数 // hInstance ...現在のインスタンスのハンドル // hPrevInstance...以前のインスタンスのハンドル // pszCmdLine ...コマンド ラインのアドレス // nCmdShow ...ウィンドウの表示状態 //-------------------------------------------------------- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { MSG msg; //メインウインドウを作成 CreateMainWindow(420,420,"ドラムリズム音をMIDI音源で鳴らす。",hInstance,nCmdShow,(WNDPROC)WindowProc, WS_OVERLAPPEDWINDOW,WS_EX_CONTROLPARENT | WS_EX_WINDOWEDGE,NULL,LoadIcon(NULL,MAKEINTRESOURCE(IDI_APPLICATION))); //送られてくるメッセージを翻訳してプロシージャに渡す while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (msg.wParam); } //------------------------------------------------------ // ■関数 WindowProc // ■用途 メインウインドウに送られるメッセージを処理 // ■引数 // hwnd ...ウインドウのハンドル // uMsg ...メッセージID // wParam ...第1メッセージ パラメータ // lParam ...第2メッセージ パラメータ //------------------------------------------------------ LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { switch (uMsg) { case WM_CREATE: //ボタン作成 CreateControlWindow(hwnd,20,10,180,30,0,BS_PUSHBUTTON,"オープンハイハット","BUTTON",(HMENU)ID_Open_Hi_Hat,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,40,180,30,0,BS_PUSHBUTTON,"クローズハイハット","BUTTON",(HMENU)ID_Close_Hi_Hat,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,70,180,30,0,BS_PUSHBUTTON,"ペダルハイハット","BUTTON",(HMENU)ID_Pedal_Hi_Hat,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,100,180,30,0,BS_PUSHBUTTON,"クラッシュシンバル2","BUTTON",(HMENU)ID_Crash_Cymbal1,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,130,180,30,0,BS_PUSHBUTTON,"クラッシュシンバル2","BUTTON",(HMENU)ID_Crash_Cymbal2,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,160,180,30,0,BS_PUSHBUTTON,"ライドシンバル1","BUTTON",(HMENU)ID_Ride_Cymbal1,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,190,180,30,0,BS_PUSHBUTTON,"ライドシンバル2","BUTTON",(HMENU)ID_Ride_Cymbal2,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,220,180,30,0,BS_PUSHBUTTON,"スプラッシュシンバル","BUTTON",(HMENU)ID_Splash_Cymbal,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,250,180,30,0,BS_PUSHBUTTON,"サイドスティック","BUTTON",(HMENU)ID_Side_Stick,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,280,180,30,0,BS_PUSHBUTTON,"高タム","BUTTON",(HMENU)ID_Hi_Tom,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,310,180,30,0,BS_PUSHBUTTON,"中高タム","BUTTON",(HMENU)ID_Midle_Hi_Tom,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,20,340,180,30,0,BS_PUSHBUTTON,"中低タム","BUTTON",(HMENU)ID_Midle_Lo_Tom,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,220,10,180,30,0,BS_PUSHBUTTON,"低タム","BUTTON",(HMENU)ID_Lo_Tom,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,220,40,180,30,0,BS_PUSHBUTTON,"高フロアタム","BUTTON",(HMENU)ID_Hi_Floor_Tom,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,220,70,180,30,0,BS_PUSHBUTTON,"低フロアタム","BUTTON",(HMENU)ID_Lo_Floor_Tom,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,220,100,180,30,0,BS_PUSHBUTTON,"スネア1","BUTTON",(HMENU)ID_Sunea1,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,220,130,180,30,0,BS_PUSHBUTTON,"スネア2","BUTTON",(HMENU)ID_Sunea2,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,220,160,180,30,0,BS_PUSHBUTTON,"バスドラ1","BUTTON",(HMENU)ID_Bass_Dora1,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); CreateControlWindow(hwnd,220,190,180,30,0,BS_PUSHBUTTON,"バスドラ2","BUTTON",(HMENU)ID_Bass_Dora2,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); //MIDIポートを開く if (midiOutGetNumDevs<=0) MessageBox(hwnd,"あなたの環境ではMIDI音源が使用できません。","エラー",MB_OK); else midiOutOpen((LPHMIDIOUT)&hMIDI,0, NULL, NULL, CALLBACK_NULL); break; //コマンドメッセージ case WM_COMMAND: switch LOWORD(wParam) { case ID_Open_Hi_Hat : MIDIPaly(46);break; case ID_Close_Hi_Hat : MIDIPaly(42);break; case ID_Pedal_Hi_Hat : MIDIPaly(44);break; case ID_Crash_Cymbal1 : MIDIPaly(49);break; case ID_Crash_Cymbal2 : MIDIPaly(57);break; case ID_Ride_Cymbal1 : MIDIPaly(51);break; case ID_Ride_Cymbal2 : MIDIPaly(59);break; case ID_Splash_Cymbal : MIDIPaly(55);break; case ID_Side_Stick : MIDIPaly(37);break; case ID_Hi_Tom : MIDIPaly(50);break; case ID_Midle_Hi_Tom : MIDIPaly(48);break; case ID_Midle_Lo_Tom : MIDIPaly(47);break; case ID_Lo_Tom : MIDIPaly(45);break; case ID_Hi_Floor_Tom : MIDIPaly(43);break; case ID_Lo_Floor_Tom : MIDIPaly(41);break; case ID_Sunea1 : MIDIPaly(38);break; case ID_Sunea2 : MIDIPaly(40);break; case ID_Bass_Dora1 : MIDIPaly(35);break; case ID_Bass_Dora2 : MIDIPaly(36);break; } break; case WM_DESTROY: midiOutReset(hMIDI); //MIDI出力リセット midiOutClose(hMIDI); //MIDIポートを閉じる PostQuitMessage(0); break; //その他のメッセージはWindowsに任せる default:return(DefWindowProc(hwnd, uMsg, wParam, lParam)); } return (0); }
ソースコード一式のダウンロード
capi_sample5.zip 3,720 バイト
動作環境
このサンプルは 「Windows98」及び「Microsoft Visual C++5.0」「Borland C++ Compiler 5.5」で確認しております。環境が異なる場合は正常に動作しない場合もございますのでご了承下さい。
Visual C++5.0でのコンパイル
VC5.0でサンプルをコンパイルする場合は新規プロジェクト(Win32Application)を作成後、各ファイルを追加してビルドしてください。
Borland C++ Compiler 5.5でのコンパイル
BCC5.5でサンプルをコンパイルする場合は「bcc32.exe」で*.c又は*.cppファイルをコンパイルします。リソースがある場合は「brc32.exe」で*resファイルを付与してください。
サンプルについて
このWindows APIサンプル集(C/C++版)は2000年頃にC/C++言語の学習の為に作成したものです。コードはエレガントではなく「初心者レベルのコーディング」です。仕事などの業務で利用する際にはエラー処理やメモリ解放などの再確認を必ずして下さい。
スポンサーリンク
関連記事
公開日:2015年03月19日
記事NO:00461