2020年9月6日日曜日

C#で、もう1回、MIDI その5

 今回は、前回その4で調べたMIDIファイルをプログラムで扱うための準備です。MIDI Eventをクラスにしています。短い内容なので、読めば分かるでしょう。なんとなく教科書のオブジェクト指向っぽい感じです。

(ちなみに、Sort関数を作っているのは、後々のため。。。たぶん。)


 作ってみて迷ったのは、Timeの扱いです。

 MIDIファイルには、前のMIDI Eventからの相対時間が記録されています。その仕様で実際にMIDIファイルを演奏させてみると、曲の後半で違和感がありました。おそらく、誤差が累積しているからだと思います(演奏のやり方次第なんでしょうが。。。)。というわけで、クラス内のTimeは曲の中の絶対時間を保存することにしました。変数名がDeltaTimeじゃないのは、そういう理由です。


 以下が今回のC#のソースコード"MidiEvent.cs"です。といっても、Main関数がないので、実行はできません。


 ソースコードはご自由にご利用ください。ただし、趣味のプログラムなので保証はありません。コメントとかも適当です。プログラミングを勉強する方のご参考にでもなれば。


------------------------------


/*--------------------------------------------------*/

/* MidiEvent Class */

/*--------------------------------------------------*/

public class MidiEvent

{

public int Time; // Time [tick]

public byte Event; // 0x80 - 0xff



/*--------------------------------------------------*/

/* Sort */

/*--------------------------------------------------*/

public static void Sort( MidiEvent[] trk)

{

MidiEvent temp;


for( int i = 1; i < trk.Length; i++)

{

temp = trk[i];


int j;


for( j = i; 0 < j; j--)

{

if( temp.Time < trk[j - 1].Time)

{

trk[j] = trk[j - 1];

}

else

{

break;

}

}


trk[j] = temp;

}

}

}


/*--------------------------------------------------*/

/* ChannelEvent Class */

/*--------------------------------------------------*/

public class ChannelEvent : MidiEvent

{

public byte Param1; // 0x00 - 0x7f

public byte Param2; // 0x00 - 0x7f


public ChannelEvent( int tm, byte evt, byte p1, byte p2)

{

this.Time = tm;

this.Event = evt;

this.Param1 = p1;

this.Param2 = p2;

}

}


/*--------------------------------------------------*/

/* SystemEvent Class */

/*--------------------------------------------------*/

public class SystemEvent : MidiEvent

{

public byte[] Data;


public SystemEvent( int tm, byte evt, byte[] dt)

{

this.Time = tm;

this.Event = evt;

this.Data = dt;

}

}


/*--------------------------------------------------*/

/* MetaEvent Class */

/*--------------------------------------------------*/

public class MetaEvent : MidiEvent

{

public byte Type;

public byte[] Data;


public MetaEvent( int tm, byte evt, byte tp, byte[] dt)

{

this.Time = tm;

this.Event = evt;

this.Type = tp;

this.Data = dt;

}

}


0 件のコメント:

コメントを投稿