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

MidiChord.cpp
#pragma comment(lib, "winmm")
 
#include <Windows.h>
#include <vector>
#include <map>
 
using namespace std;
 
typedef vector<DWORD> VSMSG;
typedef multimap<DWORD, VSMSG> SEQ;
 
// status
#define NOTE_OFF	0x8
#define NOTE_ON		0x9
#define PROGRAM_CHANGE	0xc
 
// program
#define ACOUSTIC_PIANO	0x00
 
// note number
#define G3 55
#define C4 60
#define D4 62
#define E4 64
#define G4 67
#define B4 71
#define C5 72
 
#define MAKESMSG(st,ch,d1,d2) ((st)<<4|(ch)|(d1)<<8|(d2)<<16)
#define MAKESMSG_(d1,d2) ((d1)|(d2)<<8)
#define CH 0
 
// 関数プロトタイプ宣言
void SeqInsert(DWORD ticks, DWORD smsg);
void SeqInsert(DWORD ticks, DWORD smsg1, DWORD smsg2, DWORD smsg3, DWORD smsg4);
 
// 外部変数
SEQ seq;
 
//==============================================================================
int main()
{
	HMIDIOUT hmo;
	DWORD ticks = 0;
	int vel = 0x70;
 
	SeqInsert(ticks, MAKESMSG(PROGRAM_CHANGE, CH, ACOUSTIC_PIANO, 0));
 
	SeqInsert(ticks, MAKESMSG(NOTE_ON, CH, C4, vel),
		MAKESMSG_(E4, vel), MAKESMSG_(G4, vel), MAKESMSG_(C5, vel));
	ticks += 1500;
	SeqInsert(ticks - 1, MAKESMSG(NOTE_OFF, CH, C4, 0),
		MAKESMSG_(E4, 0), MAKESMSG_(G4, 0), MAKESMSG_(C5, 0));
 
	SeqInsert(ticks, MAKESMSG(NOTE_ON, CH, G3, vel),
		MAKESMSG_(D4, vel), MAKESMSG_(G4, vel), MAKESMSG_(B4, vel));
	ticks += 1500;
	SeqInsert(ticks - 1, MAKESMSG(NOTE_OFF, CH, G3, 0),
		MAKESMSG_(D4, 0), MAKESMSG_(G4, 0), MAKESMSG_(B4, 0));
 
	SeqInsert(ticks, MAKESMSG(NOTE_ON, CH, C4, vel),
		MAKESMSG_(E4, vel), MAKESMSG_(G4, vel), MAKESMSG_(C5, vel));
	ticks += 1500;
	SeqInsert(ticks - 1, MAKESMSG(NOTE_OFF, CH, C4, 0),
		MAKESMSG_(E4, 0), MAKESMSG_(G4, 0), MAKESMSG_(C5, 0));
 
	// play
	midiOutOpen(&hmo, MIDI_MAPPER, NULL, 0, CALLBACK_NULL);
 
	DWORD start = timeGetTime();
	for (SEQ::iterator it = seq.begin(); it != seq.end(); it++) {
		while (timeGetTime() - start < (*it).first) Sleep(1);
		for (size_t i = 0; i < (*it).second.size(); i++) {
			midiOutShortMsg(hmo, (*it).second[i]);
		}
	}
 
	midiOutReset(hmo);
	midiOutClose(hmo);
	return 0;
}
 
void SeqInsert(DWORD ticks, DWORD smsg)
{
	VSMSG vsmsg;
	vsmsg.push_back(smsg);
	seq.insert(SEQ::value_type(ticks, vsmsg));
}
 
void SeqInsert(DWORD ticks, DWORD smsg1, DWORD smsg2, DWORD smsg3, DWORD smsg4)
{
	VSMSG vsmsg;
	vsmsg.push_back(smsg1);
	vsmsg.push_back(smsg2);
	vsmsg.push_back(smsg3);
	vsmsg.push_back(smsg4);
	seq.insert(SEQ::value_type(ticks, vsmsg));
}
 
最終更新:2013年01月24日 16:57