5.ピアノロールを作りたい

MIDIを作れるJavaアプレットを作っているのだ。
前回でついに音が鳴ったのだ!

そろそろMIDI作成ソフトらしいこと始めるで。
MIDIの編集方法にはいろいろあるわけやけれども、MIDIAPではピアノロールだけを使うことにするわ。
なんでかっつうと、まず音楽ソフトのインストールすら億劫な初心者さんは五線譜の読み方や、ましてやMIDIイベントの概念についてはさっぱり知らんと考えたほうがええわけや。
それに五線譜やと調や拍子によって外観が大きく変わるし、だいいちその解釈はそれを読む人の感覚に委ねられとるから、最終的に厳密な演奏データとして扱われることになるMIDIには向かへんわけや。
MIDIイベントを直接編集する方法は論外。そんなの勉強する間があったらソフトインストールしとれって話や。
まあ、一番大きい理由は音符が矩形やったり調によって表示形式を変える必要がないからプログラムが簡単になるってことやけどな。

でもいきなり作り始めることはせえへん。そんなことしたら行き詰まるかもしれへんし。
とりあえずいまんとこは引き続きテスト用のビューで方向性と可能性を模索することにしとくわ。

うちは基本的に外観から入るタイプやから、まずそっから。
基本的に矩形ばっかやから、特別ビットマップとかを用意する必要はあらへん。
まあ最低限ピアノロール言うぐらいやから白鍵黒鍵ぐらいは色分けせなあかんやろな。
んなわけで、ド・レ・ファ・ソ・ラの#に相当する部分を黒にすりゃええわけやけど、こんなもん毎回いちいち色変えて描くなんて処理を馬鹿正直に書いとったら日い暮れてまうんで、鍵盤の色情報を配列に入れてまう。

// 階名
String noteName[] = {
	"ど","ど#","れ","れ#","み","ふぁ",
	"ふぁ#","そ","そ#","ら","ら#","し",
	};
// 1だと黒鍵、ということにしておこう
int noteColorIndex[] = {
	0,1,0,1,0,0,1,0,1,0,1,0,
	};
// 左側の鍵盤
Color noteColorL[] = {
	new Color(0xffffff),
	new Color(0x000000),
};
// 右側のピアノロール
Color noteColorR[] = {
	new Color(0xffffff),
	new Color(0xc0c0c0),
};
// 文字色
Color noteColorS[] = {
	new Color(0x000000),
	new Color(0xffffff),
};

正直階名はいらんかも知れんと思たけどまあただ四角があるだけ言うのも寂しいんで付けてみた。
new Color(~)ってとこが怪しい気がするけど一応期待通りに動くみたいやからほっとく。
それで、この配列を使って、鍵盤を表示するわけやけど、色変えて四角描いて色変えて四角描いて階名書いてを繰り返しとったらやっぱり日が暮れてまうんで、関数にでも入れとく。

public void drawKeyboard(Graphics g, int y, int note) {
	g.setColor(noteColorL[noteColorIndex[note%12]]);
	g.fill3DRect(0,y,50,10,true);
	g.setColor(noteColorR[noteColorIndex[note%12]]);
	g.fill3DRect(50,y,150,10,true);
	g.setColor(noteColorS[noteColorIndex[note%12]]);
	g.drawString(noteName[note%12],0,y+9);
}

これをpaint内で順次呼び出してやれば鍵盤らしきものが出来上がるというわけや。
なんかいろんなとこずれたりしよるけど後で調整するからほっとく。
で、お次は音を出す部分。音出して確認できな初心者さんはなかなかイメージわかへんと思うんや。僕もその一人。

public void mousePressed(MouseEvent e){
	if (e.getButton()==MouseEvent.BUTTON1){
		note = 72-e.getY()/10;
		applet.synthesizer.getChannels()[0].noteOn(note,100);
	}
}
public void mouseReleased(MouseEvent e){
	if (e.getButton()==MouseEvent.BUTTON1){
		applet.synthesizer.getChannels()[0].noteOff(note,100);
		note = 0;
	}
}

音出すんは左クリックオンリー。if (e.getButton()==MouseEvent.BUTTON1){はそういう意味や。
72は適当につけた値。ちゃんと後で調整せなあかん。noteは勝手に定義しとれ。
allNotesOffでもよかった気がする。

今回も実際にできたコードを。
ピアノロールへの道1
音符を置くんは次回以降。

続く