トップへ(mam-mam.net/)

MIDI音源の音を鳴らす(midiOutShortMsg) ~Delphiソースコード集

検索:

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コンポーネントをフォームにドラッグ&ドロップして配置します。

Delphi IDEで画面設計

ソースコードの記述

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.