Home › Category Archives › Tips

MIDI ファイルを4キー上げて再生する

次の例では、Next MIDI を用いて、MIDI ファイルのキーを +4 した後、再生しています。

using System;
using System.IO;
using System.Text;
using NextMidi.Data.Domain;
using NextMidi.DataElement;
using NextMidi.Filing.Midi;
using NextMidi.MidiPort.Output;
using NextMidi.Time;

/* ... */

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 引数チェック
            if (args.Length != 2)
            {
                Console.WriteLine("1 port name and 1 file name required");
                return;
            }

            // MIDI ファイルを読み込み
            string fname = args[1];
            if (!File.Exists(fname))
            {
                Console.WriteLine("File does not exist");
                return;
            }
            var midiData = MidiReader.ReadFrom(fname, Encoding.GetEncoding("shift-jis"));

            // 全ての MIDI ノートを 4 半音上げる
            foreach (var track in midiData.Tracks)
            {
                foreach (var note in track.GetData<NoteEvent>())
                {
                    note.Note += 4;
                }
            }

            // テンポマップを作成
            var domain = new MidiFileDomain(midiData);

            // MIDI ポートを作成
            var port = new MidiOutPort(args[0]);
            try
            {
                port.Open();
            }
            catch
            {
                Console.WriteLine("no such port exists");
                return;
            }

            // MIDI プレーヤーを作成
            var player = new MidiPlayer(port);

            // MIDI ファイルを再生
            player.Play(domain);
        }
    }
}

MIDI 信号を再生する

次の例では、Next MIDI を用いて、簡単な MIDI 信号を再生します。

using System;
using System.Threading;
using NextMidi.DataElement;
using NextMidi.MidiPort.Output;

/* ... */

static void Main(string[] args)
{
    // MIDI ポート名を指定して MIDI ポートを開く
    if (args.Length != 1)
    {
        Console.WriteLine("1 port name required");
        return;
    }
    var port = new MidiOutPort(args[0]);
    try
    {
        port.Open();
    }
    catch
    {
        Console.WriteLine("no such port exists");
        return;
    }

    // Program No.5 に切り替え
    port.Send(new ProgramEvent(4));

    // 500 ミリ秒待つ
    Thread.Sleep(500);

    // ドレミファソラシド
    foreach (byte n in new byte[8] { 60, 62, 64, 65, 67, 69, 71, 72 })
    {
        // ベロシティ 112 でノートオンを送信
        port.Send(new NoteOnEvent(n, 112));
        Thread.Sleep(n != 72 ? 500 : 1500);
        port.Send(new NoteOffEvent(n));
    }
}

MIDI ポートを列挙する

次の例では、Next MIDI を用いて、MIDI 入力ポートと MIDI 出力ポートの一覧を取得します。

using System;
using NextMidi.MidiPort.Input.Core;
using NextMidi.MidiPort.Output.Core;

/* ... */

static void EnumInput()
{
    int count = MidiInPortHandle.PortCount;
    for (int i = 0; i < count; i++)
    {
        Console.WriteLine(MidiInPortHandle.GetPortInformation(i).szPname);
    }
}

static void EnumOutput()
{
    int count = MidiOutPortHandle.PortCount;
    for (int i = 0; i < count; i++)
    {
        Console.WriteLine(MidiOutPortHandle.GetPortInformation(i).szPname);
    }
}

static void Main(string[] args)
{
    EnumInput();
    Console.WriteLine();
    EnumOutput();
}

トラックごとのイベント数を数える

次の例では、Next MIDI を用いて、MIDI ファイルの各トラックに含まれる MIDI イベント数、ノート数、プログラムチェンジの数、コントロールチェンジの数、メタイベント数、エクスクルーシブイベント数を表示します。

using System;
using System.IO;
using System.Text;
using NextMidi.Data.Track;
using NextMidi.DataElement;
using NextMidi.DataElement.MetaData;
using NextMidi.Filing.Midi;

/* ... */

static void Main(string[] args)
{
    // MIDI ファイルを指定する
    if (args.Length != 1)
    {
        Console.WriteLine("1 source file required");
        return;
    }
    string fname = args[0];
    if (!File.Exists(fname))
    {
        Console.WriteLine("File does not exist");
        return;
    }

    // MIDI ファイルを読み込む
    var midiData = MidiReader.ReadFrom(fname, Encoding.GetEncoding("shift-jis"));

    Console.WriteLine();
    Console.WriteLine("Track Evnt Note Prog Cont Meta Excl  Title");
    Console.WriteLine("----- ---- ---- ---- ---- ---- ----  ----------------");

    for (int i = 0; i < midiData.Tracks.Count; i++)
    {
        var track = midiData.Tracks[i];

        Console.WriteLine("{0} {1} {2} {3} {4} {5} {6}  {7}",
        i.ToString().PadLeft(5),
        track.GetData<MidiEvent>().Count.ToString().PadLeft(4),
        track.GetData<NoteEvent>().Count.ToString().PadLeft(4),
        track.GetData<ProgramEvent>().Count.ToString().PadLeft(4),
        track.GetData<ControlEvent>().Count.ToString().PadLeft(4),
        track.GetData<MetaEvent>().Count.ToString().PadLeft(4),
        track.GetData<ExclusiveEvent>().Count.ToString().PadLeft(4),
        track.GetTitle(i == 0));
    }
}