|開発環境|Microsoft Visual C++ 2010 Express (SP1)| |実行環境|Microsoft Windows XP Home Edition (SP3)| |プロジェクトの種類|Win32 プロジェクト| |プロジェクト名|GeneralMidi| |アプリケーションの種類|Windows アプリケーション| |追加のオプション|空のプロジェクト| -[[GM1 Sound Set>http://www.midi.org/techspecs/gm1sound.php]] GeneralMidi.cpp #highlight(cpp){{ #pragma comment(lib, "winmm") #include <stdio.h> #include <Windows.h> #include <WindowsX.h> #include <CommCtrl.h> #include "resource.h" // 定義 #define MAKESMSG(st,ch,d1,d2) st<<4|(ch)|(d1)<<8|(d2)<<16 struct NumName { int num; LPCTSTR name; }; // タブ int tab0[] = { IDC_FAMILY_NAME, IDC_FAMILY, IDC_INSTRUMENT_NAME, IDC_INSTRUMENT, 0 }; int tab1[] = { IDC_PERCUSSION1, IDC_PERCUSSION2, IDC_PERCUSSION3, 0 }; int *tab[] = {tab0, tab1}; // 楽器ファミリー LPCTSTR family[] = { L"Piano", L"Chromatic Percussion", L"Organ", L"Guitar", L"Bass", L"Strings", L"Ensemble", L"Brass", L"Reed", L"Pipe", L"Synth Lead", L"Synth Pad", L"Synth Effects", L"Ethnic", L"Percussive", L"Sound Effects", }; // 楽器 NumName instrument[][8] = { { // Piano {1, L"Acoustic Grand Piano"}, {2, L"Bright Acoustic Piano"}, {3, L"Electric Grand Piano"}, {4, L"Honky-tonk Piano"}, {5, L"Electric Piano 1"}, {6, L"Electric Piano 2"}, {7, L"Harpsichord"}, {8, L"Clavi"}, }, { // Chromatic Percussion {9, L"Celesta"}, {10, L"Glockenspiel"}, {11, L"Music Box"}, {12, L"Vibraphone"}, {13, L"Marimba"}, {14, L"Xylophone"}, {15, L"Tubular Bells"}, {16, L"Dulcimer"}, }, { // Organ {17, L"Drawbar Organ"}, {18, L"Percussive Organ"}, {19, L"Rock Organ"}, {20, L"Church Organ"}, {21, L"Reed Organ"}, {22, L"Accordion"}, {23, L"Harmonica"}, {24, L"Tango Accordion"}, }, { // Guitar {25, L"Acoustic Guitar (nylon)"}, {26, L"Acoustic Guitar (steel)"}, {27, L"Electric Guitar (jazz)"}, {28, L"Electric Guitar (clean)"}, {29, L"Electric Guitar (muted)"}, {30, L"Overdriven Guitar"}, {31, L"Distortion Guitar"}, {32, L"Guitar harmonics"}, }, { // Bass {33, L"Acoustic Bass"}, {34, L"Electric Bass (finger)"}, {35, L"Electric Bass (pick)"}, {36, L"Fretless Bass"}, {37, L"Slap Bass 1"}, {38, L"Slap Bass 2"}, {39, L"Synth Bass 1"}, {40, L"Synth Bass 2"}, }, { // Strings {41, L"Violin"}, {42, L"Viola"}, {43, L"Cello"}, {44, L"Contrabass"}, {45, L"Tremolo Strings"}, {46, L"Pizzicato Strings"}, {47, L"Orchestral Harp"}, {48, L"Timpani"}, }, { // Ensemble {49, L"String Ensemble 1"}, {50, L"String Ensemble 2"}, {51, L"SynthStrings 1"}, {52, L"SynthStrings 2"}, {53, L"Choir Aahs"}, {54, L"Voice Oohs"}, {55, L"Synth Voice"}, {56, L"Orchestra Hit"}, }, { // Brass {57, L"Trumpet"}, {58, L"Trombone"}, {59, L"Tuba"}, {60, L"Muted Trumpet"}, {61, L"French Horn"}, {62, L"Brass Section"}, {63, L"SynthBrass 1"}, {64, L"SynthBrass 2"}, }, { // Reed {65, L"Soprano Sax"}, {66, L"Alto Sax"}, {67, L"Tenor Sax"}, {68, L"Baritone Sax"}, {69, L"Oboe"}, {70, L"English Horn"}, {71, L"Bassoon"}, {72, L"Clarinet"}, }, { // Pipe {73, L"Piccolo"}, {74, L"Flute"}, {75, L"Recorder"}, {76, L"Pan Flute"}, {77, L"Blown Bottle"}, {78, L"Shakuhachi"}, {79, L"Whistle"}, {80, L"Ocarina"}, }, { // Synth Lead {81, L"Lead 1 (square)"}, {82, L"Lead 2 (sawtooth)"}, {83, L"Lead 3 (calliope)"}, {84, L"Lead 4 (chiff)"}, {85, L"Lead 5 (charang)"}, {86, L"Lead 6 (voice)"}, {87, L"Lead 7 (fifths)"}, {88, L"Lead 8 (bass + lead)"}, }, { // Synth Pad {89, L"Pad 1 (new age)"}, {90, L"Pad 2 (warm)"}, {91, L"Pad 3 (polysynth)"}, {92, L"Pad 4 (choir)"}, {93, L"Pad 5 (bowed)"}, {94, L"Pad 6 (metallic)"}, {95, L"Pad 7 (halo)"}, {96, L"Pad 8 (sweep)"}, }, { // Synth Effects {97, L"FX 1 (rain)"}, {98, L"FX 2 (soundtrack)"}, {99, L"FX 3 (crystal)"}, {100, L"FX 4 (atmosphere)"}, {101, L"FX 5 (brightness)"}, {102, L"FX 6 (goblins)"}, {103, L"FX 7 (echoes)"}, {104, L"FX 8 (sci-fi)"}, }, { // Ethnic {105, L"Sitar"}, {106, L"Banjo"}, {107, L"Shamisen"}, {108, L"Koto"}, {109, L"Kalimba"}, {110, L"Bag pipe"}, {111, L"Fiddle"}, {112, L"Shanai"}, }, { // Percussive {113, L"Tinkle Bell"}, {114, L"Agogo"}, {115, L"Steel Drums"}, {116, L"Woodblock"}, {117, L"Taiko Drum"}, {118, L"Melodic Tom"}, {119, L"Synth Drum"}, {120, L"Reverse Cymbal"}, }, { // Sound Effects {121, L"Guitar Fret Noise"}, {122, L"Breath Noise"}, {123, L"Seashore"}, {124, L"Bird Tweet"}, {125, L"Telephone Ring"}, {126, L"Helicopter"}, {127, L"Applause"}, {128, L"Gunshot"}, }, }; // 打楽器 NumName percussion[] = { {35, L"Acoustic Bass Drum"}, {36, L"Bass Drum 1"}, {37, L"Side Stick"}, {38, L"Acoustic Snare"}, {39, L"Hand Clap"}, {40, L"Electric Snare"}, {41, L"Low Floor Tom"}, {42, L"Closed Hi Hat"}, {43, L"High Floor Tom"}, {44, L"Pedal Hi-Hat"}, {45, L"Low Tom"}, {46, L"Open Hi-Hat"}, {47, L"Low-Mid Tom"}, {48, L"Hi-Mid Tom"}, {49, L"Crash Cymbal 1"}, {50, L"High Tom"}, {51, L"Ride Cymbal 1"}, {52, L"Chinese Cymbal"}, {53, L"Ride Bell"}, {54, L"Tambourine"}, {55, L"Splash Cymbal"}, {56, L"Cowbell"}, {57, L"Crash Cymbal 2"}, {58, L"Vibraslap"}, {59, L"Ride Cymbal 2"}, {60, L"Hi Bongo"}, {61, L"Low Bongo"}, {62, L"Mute Hi Conga"}, {63, L"Open Hi Conga"}, {64, L"Low Conga"}, {65, L"High Timbale"}, {66, L"Low Timbale"}, {67, L"High Agogo"}, {68, L"Low Agogo"}, {69, L"Cabasa"}, {70, L"Maracas"}, {71, L"Short Whistle"}, {72, L"Long Whistle"}, {73, L"Short Guiro"}, {74, L"Long Guiro"}, {75, L"Claves"}, {76, L"Hi Wood Block"}, {77, L"Low Wood Block"}, {78, L"Mute Cuica"}, {79, L"Open Cuica"}, {80, L"Mute Triangle"}, {81, L"Open Triangle"}, }; // 外部変数 HMIDIOUT hmo; UINT autoNote; int chanNO = 0; int noteNO; int progNO = 0; int tabSel = 0; // 関数プロトタイプ宣言 INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnInitDialog(HWND hDlg); void OnTabSelChange(HWND hDlg); void OnFamily(HWND hDlg); void OnInstrument(HWND hDlg); void OnPercussion(HWND hDlg, WORD wID); void Play(HWND hDlg); //============================================================================== int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) { midiOutOpen(&hmo, MIDI_MAPPER, NULL, 0, CALLBACK_NULL); DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc); midiOutReset(hmo); midiOutClose(hmo); return 0; } INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { INT_PTR res = TRUE; // メッセージを処理した switch (uMsg) { case WM_COMMAND: WORD wNotifyCode; wNotifyCode = HIWORD(wParam); switch (LOWORD(wParam)) { case IDC_FAMILY: if (wNotifyCode == LBN_SELCHANGE) { OnFamily(hDlg); } break; case IDC_INSTRUMENT: if (wNotifyCode == LBN_SELCHANGE) { OnInstrument(hDlg); Play(hDlg); } break; case IDC_PERCUSSION1: case IDC_PERCUSSION2: case IDC_PERCUSSION3: if (wNotifyCode == LBN_SELCHANGE) { OnPercussion(hDlg, LOWORD(wParam)); Play(hDlg); } break; case IDC_AUTO_NOTE: autoNote = IsDlgButtonChecked(hDlg, IDC_AUTO_NOTE); break; } break; case WM_NOTIFY: switch (wParam) { case IDC_TAB: switch (((LPNMHDR)lParam)->code) { case TCN_SELCHANGE: OnTabSelChange(hDlg); break; } break; } break; case WM_INITDIALOG: OnInitDialog(hDlg); //res = FALSE; // SetFocusでフォーカスを設定した場合はFALSE break; case WM_CLOSE: EndDialog(hDlg, 0); break; default: res = FALSE; // メッセージを処理しなかった } return res; } void OnInitDialog(HWND hDlg) { HWND hTab = GetDlgItem(hDlg, IDC_TAB); HWND hFamily = GetDlgItem(hDlg, IDC_FAMILY); // タブ TCITEM tci; tci.mask = TCIF_TEXT; tci.pszText = L"Instrument"; TabCtrl_InsertItem(hTab, 0, &tci); tci.pszText = L"Percussion"; TabCtrl_InsertItem(hTab, 1, &tci); // Family for (int n = 0; n < _countof(family); n++) { ListBox_InsertString(hFamily, n, family[n]); } // Percussion for (int n = 0; n < _countof(percussion); n++) { TCHAR buf[32]; swprintf_s(buf, L"%03d %s", percussion[n].num, percussion[n].name); ListBox_InsertString(GetDlgItem(hDlg, IDC_PERCUSSION1 + n / 16), n % 16, buf); } OnTabSelChange(hDlg); } void OnTabSelChange(HWND hDlg) { tabSel = TabCtrl_GetCurSel(GetDlgItem(hDlg, IDC_TAB)); // タブ切り替え for (int i = 0; i < _countof(tab); i++) { int nCmdShow = (i == tabSel) ? SW_SHOWNA : SW_HIDE; for (int n = 0; tab[i][n]; n++) { ShowWindow(GetDlgItem(hDlg, tab[i][n]), nCmdShow); } } } void OnFamily(HWND hDlg) { int i = ListBox_GetCurSel(GetDlgItem(hDlg, IDC_FAMILY)); // Instrument HWND hInstrument = GetDlgItem(hDlg, IDC_INSTRUMENT); ListBox_ResetContent(hInstrument); for (int n = 0; n < 8; n++) { TCHAR buf[32]; swprintf_s(buf, L"%03d %s", instrument[i][n].num, instrument[i][n].name); ListBox_InsertString(hInstrument, n, buf); } } void OnInstrument(HWND hDlg) { int f = ListBox_GetCurSel(GetDlgItem(hDlg, IDC_FAMILY)); int i = ListBox_GetCurSel(GetDlgItem(hDlg, IDC_INSTRUMENT)); progNO = instrument[f][i].num; } void OnPercussion(HWND hDlg, WORD wID) { for (int n = IDC_PERCUSSION1; n <= IDC_PERCUSSION3; n++) { if (n != wID) { ListBox_SetCurSel(GetDlgItem(hDlg, n), -1); } } } void Play(HWND hDlg) { if (chanNO) { midiOutShortMsg(hmo, MAKESMSG(0x8, chanNO - 1, noteNO, 0)); // Note Off chanNO = 0; } if (autoNote != BST_CHECKED) return; switch (tabSel) { case 0: // Instrument chanNO = 1; noteNO = 69; break; case 1: // Percussion chanNO = 10; noteNO = -1; for (int n = 0; n < 3; n++) { int i = ListBox_GetCurSel(GetDlgItem(hDlg, IDC_PERCUSSION1 + n)); if (i != LB_ERR) { noteNO = percussion[16 * n + i].num; break; } } break; } if (noteNO < 0) return; if (chanNO != 10) { if (progNO <= 0) return; midiOutShortMsg(hmo, MAKESMSG(0xc, chanNO - 1, progNO - 1, 0)); // Program Change } midiOutShortMsg(hmo, MAKESMSG(0x9, chanNO - 1, noteNO, 127)); // Note On } }} resource.h #highlight(c){{ #define IDD_DIALOG 100 #define IDC_STATIC -1 #define IDC_TAB 1000 #define IDC_FAMILY_NAME 1001 #define IDC_FAMILY 1002 #define IDC_INSTRUMENT_NAME 1003 #define IDC_INSTRUMENT 1004 #define IDC_PERCUSSION1 1005 #define IDC_PERCUSSION2 1006 #define IDC_PERCUSSION3 1007 #define IDC_AUTO_NOTE 1008 }} GeneralMidi.rc #highlight(c){{ // resource script #include <Windows.h> #include <CommCtrl.h> #include "resource.h" IDD_DIALOG DIALOGEX 100, 100, 270, 225 STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX EXSTYLE WS_EX_APPWINDOW CAPTION "GeneralMidi" FONT 9, "MS Pゴシック" BEGIN CONTROL "",IDC_TAB,WC_TABCONTROL,WS_TABSTOP,5,5,260,195 LTEXT "Family Name",IDC_FAMILY_NAME,10,25,120,10 LISTBOX IDC_FAMILY,10,40,120,150,WS_TABSTOP LTEXT "Instrument Name",IDC_INSTRUMENT_NAME,140,25,120,10 LISTBOX IDC_INSTRUMENT,140,40,120,150,WS_TABSTOP LISTBOX IDC_PERCUSSION1,10,40,80,150,WS_TABSTOP LISTBOX IDC_PERCUSSION2,95,40,80,150,WS_TABSTOP LISTBOX IDC_PERCUSSION3,180,40,80,150,WS_TABSTOP CONTROL "Auto Note",IDC_AUTO_NOTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,205,50,15 END }}