開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 GeneralMidi
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト


GeneralMidi.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
#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
// 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
 
最終更新:2013年04月11日 12:23