MIDI音源の音を鳴らす(midiOutShortMsg) ~Delphiソースコード集
DelphiでMIDI音源の音を鳴らす方法を解説します。
MIDIデバイスをオープンするには以下の関数を使います。
var hMidi:HMIDIOUT; // MIDIハンドル
midiOutOpen(@hMidi, MIDI_MAPPER, 0, 0, CALLBACK_NULL);
音を鳴らしたり止めたり、音色を変えたりするには以下の関数を使います
midiOutShortMsg(hMidi,dwMsg);
MIDIデバイスをクローズするには以下の関数を使います。
midiOutClose(hMidi);
midiOutShortMsg関数について
midiOutShortMsg(hMidi,dwMsg);
第1引数「hMidi」はオープンしたMIDIハンドルです。
第2引数「dwMsg」は4バイトの数値を与えるのですが、与える数字により命令が変わります。
主なメッセージ | 1バイト目 | 2バイト目 | 3バイト目 | 例 |
---|---|---|---|---|
ノートオフ(消音) | $8n | ノート番号 | - | $80 |
ノートオン(発音) | $9n | ノート番号 | ベロシティ | $7F3C90 |
エクスプレッション(音量変更) | $Bn | $0B(11) | 音量値0~127($00~$7F) | $7F0BB0 |
リバーブ・デプス(残響効果深さ) | $Bn | $5D(93) | 音量値0~127($00~$7F) | $7F5BB0 |
コーラス・デプス(コーラス効果深さ) | $Bn | $5B(91) | 音量値0~127($00~$7F) | $7F5BB0 |
プログラムチェンジ(音色変更) | $Cn | 音色番号0~127($00~$7F) | - | $04C0 |
- 上記表のn
- チャンネル番号0~15(16進数での$0~$F)を示します
- 上記表のノート番号
-
音程0~127(16進数での$00~$7F)
ド 60($3C) ド# 61($3D) レ 62($3E) レ# 63($3F) ミ 64($40) ファ 65($41) ファ# 66($42) ソ 67($43) ソ# 68($44) ラ 69($45) シ 70($46) シ# 71($47) ド↑ 72($48) ド↑# 73($49) レ↑ 74($4A) レ↑# 75($4B) - 上記表のベロシティ
- 音量0~127(16進数での$00~$7F)
- 音色番号
-
音色番号 音色 0 アコースティックピアノ 1 ブライトピアノ 2 エレクトリックグランドピアノ 3 ホンキートンクピアノノ 4 エレクトリックピアノ 5 エレクトリックピアノ2 6 ハープシコード 7 クラビネット 8 チェレスタノ 9 グロッケンシュピール 10 オルゴール 11 ヴィブラフォン 12 マリンバノ 13 シロフォン 14 チューブラーベル 15 ダルシマー 16 ドローバーオルガン 17 パーカッシブオルガン 18 ロックオルガン 19 チャーチオルガン 20 リードオルガン 21 アコーディオン 22 ハーモニカ 23 タンゴアコーディオン 24 アコースティックギター(ナイロン弦) 25 アコースティックギター(スチール弦) 26 ジャズギター 27 クリーンギター 28 ミュートギター 29 オーバードライブギター 30 ディストーションギター 31 ギターハーモニクス 32 アコースティックベース 33 フィンガー・ベース 34 ピック・ベース 35 フレットレスベース 36 スラップベース 1 37 スラップベース 2 38 シンセベース 1 39 シンセベース 2 40 ヴァイオリン 41 ヴィオラ 42 チェロ 43 コントラバス 44 トレモロ 45 ピッチカート 46 ハープ 47 ティンパニ 48 ストリングアンサンブル 1 49 ストリングアンサンブル 2 50 シンセストリングス 1 51 シンセストリングス 2 52 声 あ 53 声 お 54 シンセヴォイス 55 オーケストラヒット 56 トランペット 57 トロンボーン 58 チューバ 59 ミュート トランペット 60 フレンチ・ホルン 61 ブラスセクション 62 シンセブラス 1 63 シンセブラス 2 64 ソプラノサックス 65 アルトサックス 66 テナーサックス 67 バリトンサックス 68 オーボエ 69 イングリッシュホルン 70 ファゴット 71 クラリネット 72 ピッコロ 73 フルート 74 リコーダー 75 パンフルート 76 茶瓶 77 尺八 78 口笛 79 オカリナ 80 矩形波 81 ノコギリ波 82 カリオペ 83 チフ 84 チャランゴ 85 声 86 フィフスズ 87 バス + リード 88 ファンタジア 89 ウォーム 90 ポリシンセ 91 クワイア 92 ボウ 93 メタリック 94 ハロー 95 スウィープ 96 雨 97 サウンドトラック 98 クリスタル 99 アトモスフィア 100 ブライトネス 101 ゴブリン 102 エコー 103 サイファイ 104 シタール 105 バンジョー 106 三味線 107 琴 108 カリンバ 109 バグパイプ 110 フィドル 111 シャハナーイ 112 ティンクルベル 113 アゴゴ 114 スチールドラム 115 ウッドブロック 116 太鼓 117 メロディックタム 118 シンセドラム 119 逆シンバル 120 ギターフレットノイズ 121 ブレスノイズ 122 海岸 123 鳥の囀り 124 電話 125 ヘリコプター 126 拍手 127 銃声
プロジェクトの作成と画面設計
プロジェクトを新規作成(VCLアプリケーション)します。
フォーム(Form1)にTButtonコンポーネントをフォームにドラッグ&ドロップして配置します。
ソースコードの記述
Button1をダブルクリックして以下ソースコードを記述します。
以下ソースコードでは「ド」を1秒間鳴らして停止します。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Winapi.MMSystem;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var hMidi:HMIDIOUT; //MIDIハンドル
dwMsg:Cardinal;
vol,tone,ch:byte;
begin
//ボリューム
vol:=$40;//$00~$7F
//音色
tone:=$7C;//(電話) $00~$7F
//チャンネル
ch:=$00;//$00~$0F
//MIDIデバイスを開く(MIDI音源を使えるようにします)
midiOutOpen(@hMidi, MIDI_MAPPER, 0, 0, CALLBACK_NULL);
try
//音色の変更
dwMsg:=($C0+ch)+(tone shl 8);
midiOutShortMsg(hMidi,dwMsg);
//音を出す ド 音量
dwMsg:=($90+ch) + ($3C shl 8) + (vol shl 16);
midiOutShortMsg(hMidi,dwMsg);
//1秒待つ
sleep(1000);
//ドの音を止める
dwMsg:=($80+ch) + ($3C shl 8);
midiOutShortMsg(hMidi,dwMsg);
finally
//MIDIデバイスを閉じる
midiOutClose(hMidi);
end;
end;
end.
参考
以下ソースコードでは「ド」「ミ」「ソ」の和音を1秒間鳴らして停止します。
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Winapi.MMSystem; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var hMidi:HMIDIOUT; //MIDIハンドル dwMsg:Cardinal; vol,tone,ch:byte; begin //ボリューム vol:=$40;//$00~$7F //音色 tone:=$10;//$00~$7F //チャンネル ch:=$00;//$00~$0F //MIDIデバイスを開く(MIDI音源を使えるようにします) midiOutOpen(@hMidi, MIDI_MAPPER, 0, 0, CALLBACK_NULL); try //音色の変更 dwMsg:=($C0+ch)+(tone shl 8); midiOutShortMsg(hMidi,dwMsg); //音を出す ド 音量 dwMsg:=($90+ch) + ($3C shl 8) + (vol shl 16); midiOutShortMsg(hMidi,dwMsg); //音を出す ミ 音量 dwMsg:=($90+ch) + ($40 shl 8) + (vol shl 16); midiOutShortMsg(hMidi,dwMsg); //音を出す ソ 音量 dwMsg:=($90+ch) + ($43 shl 8) + (vol shl 16); midiOutShortMsg(hMidi,dwMsg); //1秒待つ sleep(1000); //ドの音を止める dwMsg:=($80+ch) + ($3C shl 8); midiOutShortMsg(hMidi,dwMsg); //ミの音を止める dwMsg:=($80+ch) + ($40 shl 8); midiOutShortMsg(hMidi,dwMsg); //ソの音を止める dwMsg:=($80+ch) + ($43 shl 8); midiOutShortMsg(hMidi,dwMsg); finally //MIDIデバイスを閉じる midiOutClose(hMidi); end; end; end.
参考
以下ソースコードは演奏します。
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Winapi.MMSystem; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} const notes:array[0..42] of Byte= ( $3C,$3E,$40,$41,$40,$3E,$3C,$00, $40,$41,$43,$45,$43,$41,$40,$00, $3C,$00,$3C,$00,$3C,$00,$3C,$00, $3C,$00,$3C,$00,$3E,$00,$3E,$00,$40,$00,$40,$00,$41,$00,$41,$00, $40,$3E,$3C ); times:array[0..42] of Integer= ( 400,400,400,400,400,400,400,400, 400,400,400,400,400,400,400,400, 400,400,400,400,400,400,400,400, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 400,400,400 ); procedure TForm1.Button1Click(Sender: TObject); var hMidi:HMIDIOUT; //MIDIハンドル dwMsg:Cardinal; vol,tone,ch:byte; i:Integer; begin //ボリューム vol:=$40;//$00~$7F //音色 tone:=52;//(声「あ」) $00~$7F //チャンネル ch:=$00;//$00~$0F //MIDIデバイスを開く(MIDI音源を使えるようにします) midiOutOpen(@hMidi, MIDI_MAPPER, 0, 0, CALLBACK_NULL); try //音色の変更 dwMsg:=($C0+ch)+(tone shl 8); midiOutShortMsg(hMidi,dwMsg); for i := Low(notes) to High(notes) do begin if notes[i]<>0 then begin //音を出す dwMsg:=($90+ch) + (notes[i] shl 8) + (vol shl 16); midiOutShortMsg(hMidi,dwMsg); end; sleep(times[i]); if notes[i]<>0 then begin //音を止める dwMsg:=($80+ch) + (notes[i] shl 8); midiOutShortMsg(hMidi,dwMsg); end; end; finally //MIDIデバイスを閉じる midiOutClose(hMidi); end; end; end.