koudenpaのブログ

趣味のブログです。株式会社はてなでWebアプリケーションエンジニアをやっています。職業柄IT関連の記事が多いと思います。

.NETでMIDIファイルの再生にほぼ失敗した

ので出来事として記録しておく。

https://github.com/7474/SRC を弄るうえで避けて通れないのがMIDIファイルの再生なので少し手を付けてみた。できれば移植性のあるコードで再生したいので依存関係に.NET Standard 2しか入っていないっぽいNAudioを使って試してみた。バーンってMIDI対応してるっぽいこと書いてあるしな!!

github.com

結果、とりあえず再生はできたけれど聴けたものではなかった。

MIDIも音楽もほぼ何も知らない状態なので何も分からん状態。いい感じの再生のためには何か色々な手続きがあるのだろう。

試していた状態のコード。

var midiOut = new MidiOut(0);
var midiFile = new MidiFile(path, false);
var task = Task.Run(async () =>
{
    var sw = new Stopwatch();
    sw.Start();
    var startMillis = midiFile.Events.StartAbsoluteTime;
    foreach (var melist in midiFile.Events)
    {
        foreach (var me in melist)
        {
            var eventTime = me.AbsoluteTime - startMillis;
            if (eventTime - sw.ElapsedMilliseconds > 0)
            {
                await Task.Delay((int)Math.Max(0, eventTime - sw.ElapsedMilliseconds));
            }
            midiOut.Send(me.GetAsShortMessage());
        }
    }
});

NumberOfDevices1 だったので使うデバイスを変えれば音源が変わる環境ではない模様。

> MidiOut.NumberOfDevices
1

おとなしくWindows向けのええ感じのライブラリを使うのがいいのだろう。

NAudioのMIDIもどう見てもWindows専用だしな!!!

NAudio/MidiInterop.cs at master · naudio/NAudio · GitHub

いい感じのソフトウェア音源を.NETマネージドな世界で使えれば、環境非依存でMIDI再生はできそうなものだけれど、需要はなさそう。