TestGM
Visual C++ 2005 Express Edition
Windows Server 2003 SP1 Platform SDK
Windowsアプリケーション / 空のプロジェクト
General MIDI Level 1 Sound Set
TestGM.c
// マルチバイト文字セット // comctl32.lib // winmm.lib #include
#include
#include
#include
#include "resource.h" #define MAKESMSG(st,ch,d1,d2) (((d2)<<16)|((d1)<<8)|((st)<<4)|(ch)) typedef struct tagNumberName { int iNumber; char* pcName; } NumberName; // グローバル変数 static HWND g_hTab; static HWND g_hLsbFamily; static HWND g_hLsbInstrument; static HWND g_hProgNO; static HMIDIOUT g_hmo; static int g_iTabIndex; static int g_iChanNO = 0; static int g_iProgNO; static int g_iNoteNO; static int g_iAcbAuto = 0; static int aiTab0[] = { IDC_LBL_FAMILY, IDC_LSB_FAMILY, IDC_LBL_INSTRUMENT, IDC_LSB_INSTRUMENT, 0 }; static int aiTab1[] = { IDC_LSB_PERCUSSION1, IDC_LSB_PERCUSSION2, IDC_LSB_PERCUSSION3, 0 }; static int* g_apiTab[] = {aiTab0, aiTab1}; // 楽器ファミリー static char* g_apcFamily[] = { "Piano", "Chromatic Percussion", "Organ", "Guitar", "Bass", "Strings", "Ensemble", "Brass", "Reed", "Pipe", "Synth Lead", "Synth Pad", "Synth Effects", "Ethnic", "Percussive", "Sound Effects", }; // 楽器 static NumberName g_aannInstrument[][8] = { { // Piano {1, "Acoustic Grand Piano"}, {2, "Bright Acoustic Piano"}, {3, "Electric Grand Piano"}, {4, "Honky-tonk Piano"}, {5, "Electric Piano 1"}, {6, "Electric Piano 2"}, {7, "Harpsichord"}, {8, "Clavi"}, }, { // Chromatic Percussion {9, "Celesta"}, {10, "Glockenspiel"}, {11, "Music Box"}, {12, "Vibraphone"}, {13, "Marimba"}, {14, "Xylophone"}, {15, "Tubular Bells"}, {16, "Dulcimer"}, }, { // Organ {17, "Drawbar Organ"}, {18, "Percussive Organ"}, {19, "Rock Organ"}, {20, "Church Organ"}, {21, "Reed Organ"}, {22, "Accordion"}, {23, "Harmonica"}, {24, "Tango Accordion"}, }, { // Guitar {25, "Acoustic Guitar (nylon)"}, {26, "Acoustic Guitar (steel)"}, {27, "Electric Guitar (jazz)"}, {28, "Electric Guitar (clean)"}, {29, "Electric Guitar (muted)"}, {30, "Overdriven Guitar"}, {31, "Distortion Guitar"}, {32, "Guitar harmonics"}, }, { // Bass {33, "Acoustic Bass"}, {34, "Electric Bass (finger)"}, {35, "Electric Bass (pick)"}, {36, "Fretless Bass"}, {37, "Slap Bass 1"}, {38, "Slap Bass 2"}, {39, "Synth Bass 1"}, {40, "Synth Bass 2"}, }, { // Strings {41, "Violin"}, {42, "Viola"}, {43, "Cello"}, {44, "Contrabass"}, {45, "Tremolo Strings"}, {46, "Pizzicato Strings"}, {47, "Orchestral Harp"}, {48, "Timpani"}, }, { // Ensemble {49, "String Ensemble 1"}, {50, "String Ensemble 2"}, {51, "SynthStrings 1"}, {52, "SynthStrings 2"}, {53, "Choir Aahs"}, {54, "Voice Oohs"}, {55, "Synth Voice"}, {56, "Orchestra Hit"}, }, { // Brass {57, "Trumpet"}, {58, "Trombone"}, {59, "Tuba"}, {60, "Muted Trumpet"}, {61, "French Horn"}, {62, "Brass Section"}, {63, "SynthBrass 1"}, {64, "SynthBrass 2"}, }, { // Reed {65, "Soprano Sax"}, {66, "Alto Sax"}, {67, "Tenor Sax"}, {68, "Baritone Sax"}, {69, "Oboe"}, {70, "English Horn"}, {71, "Bassoon"}, {72, "Clarinet"}, }, { // Pipe {73, "Piccolo"}, {74, "Flute"}, {75, "Recorder"}, {76, "Pan Flute"}, {77, "Blown Bottle"}, {78, "Shakuhachi"}, {79, "Whistle"}, {80, "Ocarina"}, }, { // Synth Lead {81, "Lead 1 (square)"}, {82, "Lead 2 (sawtooth)"}, {83, "Lead 3 (calliope)"}, {84, "Lead 4 (chiff)"}, {85, "Lead 5 (charang)"}, {86, "Lead 6 (voice)"}, {87, "Lead 7 (fifths)"}, {88, "Lead 8 (bass + lead)"}, }, { // Synth Pad {89, "Pad 1 (new age)"}, {90, "Pad 2 (warm)"}, {91, "Pad 3 (polysynth)"}, {92, "Pad 4 (choir)"}, {93, "Pad 5 (bowed)"}, {94, "Pad 6 (metallic)"}, {95, "Pad 7 (halo)"}, {96, "Pad 8 (sweep)"}, }, { // Synth Effects {97, "FX 1 (rain)"}, {98, "FX 2 (soundtrack)"}, {99, "FX 3 (crystal)"}, {100, "FX 4 (atmosphere)"}, {101, "FX 5 (brightness)"}, {102, "FX 6 (goblins)"}, {103, "FX 7 (echoes)"}, {104, "FX 8 (sci-fi)"}, }, { // Ethnic {105, "Sitar"}, {106, "Banjo"}, {107, "Shamisen"}, {108, "Koto"}, {109, "Kalimba"}, {110, "Bag pipe"}, {111, "Fiddle"}, {112, "Shanai"}, }, { // Percussive {113, "Tinkle Bell"}, {114, "Agogo"}, {115, "Steel Drums"}, {116, "Woodblock"}, {117, "Taiko Drum"}, {118, "Melodic Tom"}, {119, "Synth Drum"}, {120, "Reverse Cymbal"}, }, { // Sound Effects {121, "Guitar Fret Noise"}, {122, "Breath Noise"}, {123, "Seashore"}, {124, "Bird Tweet"}, {125, "Telephone Ring"}, {126, "Helicopter"}, {127, "Applause"}, {128, "Gunshot"}, }, }; // 打楽器 static NumberName g_annPercussion[] = { {35, "Acoustic Bass Drum"}, {36, "Bass Drum 1"}, {37, "Side Stick"}, {38, "Acoustic Snare"}, {39, "Hand Clap"}, {40, "Electric Snare"}, {41, "Low Floor Tom"}, {42, "Closed Hi Hat"}, {43, "High Floor Tom"}, {44, "Pedal Hi-Hat"}, {45, "Low Tom"}, {46, "Open Hi-Hat"}, {47, "Low-Mid Tom"}, {48, "Hi-Mid Tom"}, {49, "Crash Cymbal 1"}, {50, "High Tom"}, {51, "Ride Cymbal 1"}, {52, "Chinese Cymbal"}, {53, "Ride Bell"}, {54, "Tambourine"}, {55, "Splash Cymbal"}, {56, "Cowbell"}, {57, "Crash Cymbal 2"}, {58, "Vibraslap"}, {59, "Ride Cymbal 2"}, {60, "Hi Bongo"}, {61, "Low Bongo"}, {62, "Mute Hi Conga"}, {63, "Open Hi Conga"}, {64, "Low Conga"}, {65, "High Timbale"}, {66, "Low Timbale"}, {67, "High Agogo"}, {68, "Low Agogo"}, {69, "Cabasa"}, {70, "Maracas"}, {71, "Short Whistle"}, {72, "Long Whistle"}, {73, "Short Guiro"}, {74, "Long Guiro"}, {75, "Claves"}, {76, "Hi Wood Block"}, {77, "Low Wood Block"}, {78, "Mute Cuica"}, {79, "Open Cuica"}, {80, "Mute Triangle"}, {81, "Open Triangle"}, }; // プロトタイプ宣言 INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnTabSelChange(HWND hDlg); void OnLsbFamily(); void OnLsbInstrument(); void OnLsbPercussion(HWND hDlg, int iCtrlID); void OnNoteOff(); void OnNoteOn(HWND hDlg); void OnAcbAuto(); void OnInitDialog(HWND hDlg); void OnClose(); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { INITCOMMONCONTROLSEX icx; icx.dwSize = sizeof(INITCOMMONCONTROLSEX); icx.dwICC = ICC_TAB_CLASSES; if (InitCommonControlsEx(&icx) == FALSE) { return 0; } DialogBox(hInstance, MAKEINTRESOURCE(IDD_TESTGM), NULL, DlgProc); return 0; } INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { NMHDR* pnmh; WORD wNotifyCode; BOOL bRetVal = TRUE; switch (uMsg) { case WM_NOTIFY: switch (wParam) { case IDC_TAB: pnmh = (NMHDR*)lParam; switch (pnmh->code) { case TCN_SELCHANGE: OnTabSelChange(hDlg); break; } break; } break; case WM_COMMAND: wNotifyCode = HIWORD(wParam); switch (LOWORD(wParam)) { case IDC_LSB_FAMILY: if (wNotifyCode == LBN_SELCHANGE) { OnLsbFamily(); } break; case IDC_LSB_INSTRUMENT: if (wNotifyCode == LBN_SELCHANGE) { OnLsbInstrument(); if (g_iAcbAuto) { OnNoteOn(hDlg); } } break; case IDC_LSB_PERCUSSION1: case IDC_LSB_PERCUSSION2: case IDC_LSB_PERCUSSION3: if (wNotifyCode == LBN_SELCHANGE) { OnLsbPercussion(hDlg, LOWORD(wParam)); if (g_iAcbAuto) { OnNoteOn(hDlg); } } break; case IDC_BTN_NOTE_OFF: OnNoteOff(); break; case IDC_BTN_NOTE_ON: OnNoteOn(hDlg); break; case IDC_ACB_AUTO: g_iAcbAuto = (int)SendMessage(GetDlgItem(hDlg, IDC_ACB_AUTO), BM_GETCHECK, 0, 0); break; } break; case WM_INITDIALOG: OnInitDialog(hDlg); bRetVal = TRUE; // TRUEならデフォルトフォーカスを使用 break; case WM_CLOSE: OnClose(); EndDialog(hDlg, IDOK); break; default: bRetVal = FALSE; } return bRetVal; } void OnTabSelChange(HWND hDlg) { BOOL bChanNO; BOOL bNoteNO; int iCmdShow; int iIndex; int i; g_iTabIndex = TabCtrl_GetCurSel(g_hTab); // タブ切り替え for (iIndex = 0; iIndex < 2; iIndex++) { iCmdShow = (iIndex == g_iTabIndex) ? SW_SHOWNA : SW_HIDE; for (i = 0; g_apiTab[iIndex][i]; i++) { ShowWindow(GetDlgItem(hDlg, g_apiTab[iIndex][i]), iCmdShow); } } switch (g_iTabIndex) { case 0: // Instrument bChanNO = TRUE; bNoteNO = TRUE; break; case 1: // Percussion bChanNO = FALSE; bNoteNO = FALSE; break; } EnableWindow(GetDlgItem(hDlg, IDC_EDT_CHAN_NO), bChanNO); EnableWindow(GetDlgItem(hDlg, IDC_EDT_NOTE_NO), bNoteNO); } void OnLsbFamily() { char acBuf[32]; int iIndex; int i; iIndex = (int)SendMessage(g_hLsbFamily, LB_GETCURSEL, 0, 0); // Instrument SendMessage(g_hLsbInstrument, LB_RESETCONTENT, 0, 0); for (i = 0; i < 8; i++) { sprintf_s(acBuf, sizeof(acBuf), "%03d %s", g_aannInstrument[iIndex][i].iNumber, g_aannInstrument[iIndex][i].pcName); SendMessage(g_hLsbInstrument, LB_INSERTSTRING, i, (LPARAM)acBuf); } SendMessage(g_hLsbInstrument, LB_SETCURSEL, 0, 0); OnLsbInstrument(); } void OnLsbInstrument() { int iFamily; int iInstrument; char acBuf[16]; iFamily = (int)SendMessage(g_hLsbFamily, LB_GETCURSEL, 0, 0); iInstrument = (int)SendMessage(g_hLsbInstrument, LB_GETCURSEL, 0, 0); // ProgNO g_iProgNO = g_aannInstrument[iFamily][iInstrument].iNumber; sprintf_s(acBuf, sizeof(acBuf), "%03d", g_iProgNO); SetWindowText(g_hProgNO, acBuf); } void OnLsbPercussion(HWND hDlg, int iCtrlID) { int i; for (i = IDC_LSB_PERCUSSION1; i <= IDC_LSB_PERCUSSION3; i++) { if (i != iCtrlID) { SendMessage(GetDlgItem(hDlg, i), LB_SETCURSEL, -1, 0); } } } void OnNoteOff() { if (g_iChanNO) { midiOutShortMsg(g_hmo, MAKESMSG(0x8, g_iChanNO - 1, g_iNoteNO, 0)); g_iChanNO = 0; } } void OnNoteOn(HWND hDlg) { BOOL bTranslated; int iChanNO; int iNoteNO; int iVelocity; int iIndex; int i; switch (g_iTabIndex) { case 0: // Instrument // Channel#(1-16) iChanNO = GetDlgItemInt(hDlg, IDC_EDT_CHAN_NO, &bTranslated, FALSE); if (!bTranslated || iChanNO < 1 || 16 < iChanNO) { return; } // Note#(0-127) iNoteNO = GetDlgItemInt(hDlg, IDC_EDT_NOTE_NO, &bTranslated, FALSE); if (!bTranslated || iNoteNO < 0 || 127 < iNoteNO) { return; } if (iChanNO == 10) { // Percussion if (iNoteNO < 35 || 81 < iNoteNO) { return; } } break; case 1: // Percussion // Channel#(1-16) iChanNO = 10; // Note#(0-127) iNoteNO = -1; for (i = 0; i < 3; i++) { iIndex = (int)SendMessage(GetDlgItem(hDlg, IDC_LSB_PERCUSSION1 + i), LB_GETCURSEL, 0, 0); if (iIndex != LB_ERR) { iNoteNO = g_annPercussion[16 * i + iIndex].iNumber; break; } } if (iNoteNO < 0) { return; } break; } // Velocity(0-127) iVelocity = GetDlgItemInt(hDlg, IDC_EDT_VELOCITY, &bTranslated, FALSE); if (!bTranslated || iVelocity < 0 || 127 < iVelocity) { return; } OnNoteOff(); if (iChanNO != 10) { midiOutShortMsg(g_hmo, MAKESMSG(0xC, iChanNO - 1, g_iProgNO - 1, 0)); } midiOutShortMsg(g_hmo, MAKESMSG(0x9, iChanNO - 1, iNoteNO, iVelocity)); g_iChanNO = iChanNO; g_iNoteNO = iNoteNO; } void OnInitDialog(HWND hDlg) { RECT rcDesktop; RECT rcDialog; TCITEM tci; char acBuf[32]; int i; GetWindowRect(GetDesktopWindow(), &rcDesktop); GetWindowRect(hDlg, &rcDialog); SetWindowPos(hDlg, HWND_TOP, (rcDesktop.right - (rcDialog.right - rcDialog.left)) / 2, (rcDesktop.bottom - (rcDialog.bottom - rcDialog.top)) / 2, 0, 0, SWP_NOSIZE); g_hTab = GetDlgItem(hDlg, IDC_TAB); g_hLsbFamily = GetDlgItem(hDlg, IDC_LSB_FAMILY); g_hLsbInstrument = GetDlgItem(hDlg, IDC_LSB_INSTRUMENT); g_hProgNO = GetDlgItem(hDlg, IDC_EDT_PROG_NO); // Tab tci.mask = TCIF_TEXT; tci.pszText = "Instrument"; TabCtrl_InsertItem(g_hTab, 0, &tci); tci.pszText = "Percussion"; TabCtrl_InsertItem(g_hTab, 1, &tci); // Family for (i = 0; i < _countof(g_apcFamily); i++) { SendMessage(g_hLsbFamily, LB_INSERTSTRING, i, (LPARAM)g_apcFamily[i]); } SendMessage(g_hLsbFamily, LB_SETCURSEL, 0, 0); OnLsbFamily(); // Percussion for (i = 0; i < 47; i++) { sprintf_s(acBuf, sizeof(acBuf), "%03d %s", g_annPercussion[i].iNumber, g_annPercussion[i].pcName); SendMessage(GetDlgItem(hDlg, IDC_LSB_PERCUSSION1 + i / 16), LB_INSERTSTRING, i % 16, (LPARAM)acBuf); } SendMessage(GetDlgItem(hDlg, IDC_LSB_PERCUSSION1), LB_SETCURSEL, 0, 0); SetWindowText(GetDlgItem(hDlg, IDC_EDT_CHAN_NO), "1"); SetWindowText(GetDlgItem(hDlg, IDC_EDT_NOTE_NO), "60"); SetWindowText(GetDlgItem(hDlg, IDC_EDT_VELOCITY), "127"); OnTabSelChange(hDlg); midiOutOpen(&g_hmo, MIDI_MAPPER, 0, 0, 0); } void OnClose() { midiOutReset(g_hmo); midiOutClose(g_hmo); }
resource.h
#define IDC_STATIC (-1) #define IDD_TESTGM 100 #define IDC_TAB 1000 #define IDC_LBL_FAMILY 1002 #define IDC_LSB_FAMILY 1003 #define IDC_LBL_INSTRUMENT 1004 #define IDC_LSB_INSTRUMENT 1005 #define IDC_LSB_PERCUSSION1 1006 #define IDC_LSB_PERCUSSION2 1007 #define IDC_LSB_PERCUSSION3 1008 #define IDC_EDT_CHAN_NO 1009 #define IDC_EDT_PROG_NO 1010 #define IDC_EDT_NOTE_NO 1011 #define IDC_EDT_VELOCITY 1012 #define IDC_BTN_NOTE_OFF 1013 #define IDC_BTN_NOTE_ON 1014 #define IDC_ACB_AUTO 1015
TestGM.rc
// リソーススクリプト #include
#include
#include "resource.h" IDD_TESTGM DIALOGEX 0, 0, 348, 252 STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX EXSTYLE WS_EX_APPWINDOW CAPTION "TestGM" FONT 9, "MS Pゴシック" BEGIN CONTROL "",IDC_TAB,WC_TABCONTROL,0,12,12,264,204 LTEXT "Family Name",IDC_LBL_FAMILY,24,36,108,8 LISTBOX IDC_LSB_FAMILY,24,48,108,156 LTEXT "Instrument Name",IDC_LBL_INSTRUMENT,144,36,108,8 LISTBOX IDC_LSB_INSTRUMENT,144,48,108,156 LTEXT "Channel#(1-16)",IDC_STATIC,288,12,60,8 LISTBOX IDC_LSB_PERCUSSION1,24,48,72,156 LISTBOX IDC_LSB_PERCUSSION2,108,48,72,156 LISTBOX IDC_LSB_PERCUSSION3,192,48,72,156 EDITTEXT IDC_EDT_CHAN_NO,288,24,24,12 LTEXT "PC#(1-128)",IDC_STATIC,288,48,60,8 EDITTEXT IDC_EDT_PROG_NO,288,60,24,12,WS_DISABLED LTEXT "Note#(0-127)",IDC_STATIC,288,84,60,8 EDITTEXT IDC_EDT_NOTE_NO,288,96,24,12 LTEXT "Velocity(0-127)",IDC_STATIC,288,120,60,8 EDITTEXT IDC_EDT_VELOCITY,288,132,24,12 PUSHBUTTON "■(&Z)",IDC_BTN_NOTE_OFF,12,228,36,16 PUSHBUTTON "▲(&X)",IDC_BTN_NOTE_ON,60,228,36,16 CONTROL "Auto note on",IDC_ACB_AUTO,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,108,228,48,16 END
TestGM.exe