LoginSignup
2
1

Ubuntu で C#:スタンダード MIDI ファイルを作成する

Last updated at Posted at 2023-06-15

Ubuntu で C#:スタンダード MIDI ファイルを作成する

こんにちは、@studio_meowtoon です。今回は、WSL の Ubuntu 環境の C# / .NET からスタンダード MIDI ファイルを作成する方法を紹介します。
csharp_on_ubuntu.png

実現すること

  • Ubuntu 22.04 で C# / .NET プログラムからスタンダード MIDI ファイルを作成します。

C# には本来厳格なコーディング規則がありますが、この記事では可読性のために、一部規則に沿わない表記方法を使用しています。ご注意ください。

技術トピック

スタンダード MIDI ファイルとは?

こちらを展開してご覧いただけます。

スタンダード MIDI ファイル

スタンダード MIDI ファイル(Standard MIDI File)は、音楽の演奏データを保存および転送するためのファイル形式です。

キーワード 内容
プラットフォーム非依存性 スタンダード MIDI ファイルは、異なる音楽ソフトウェアやデバイス間での互換性が高いため、さまざまなプラットフォームやデバイスで使用することができます。
軽量で効率的 MIDI ファイルはテキストベースではなく、音楽データ自体をコンパクトに表現するため、ファイルサイズが小さく、データの転送や保存に効率的です。
多機能性 MIDI ファイルは、音符、テンポ、音色、演奏のタイミングなど、音楽パフォーマンスに関するさまざまな情報を格納できます。これにより、演奏データの再生、編集、交換が容易になります。
インターネット上での共有 MIDI ファイルはファイルサイズが小さく、再生には音源が必要ですが、音楽データを簡単に共有できるため、ウェブ上での楽曲の交換や共有が容易です。
作曲や編曲の効率化 MIDI ファイルは楽曲の構成要素を表現するため、作曲家や編曲家は作業を効率化し、既存の MIDI データを編集して新しいアレンジを作成することができます。
教育や学習のツール MIDI ファイルは、音楽教育や学習のツールとして広く使用されます。演奏や作曲の練習に活用したり、楽曲の分析や学習を支援したりすることができます。

開発環境

  • Windows 11 Home 22H2 を使用しています。

WSL の Ubuntu を操作していきますので macOS の方も参考にして頂けます。

WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます

> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47

Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04

.NET SDK ※ こちらの関連記事からインストール方法をご確認いただけます

$ dotnet --list-sdks
7.0.202 [/usr/share/dotnet/sdk]
$ dotnet --version
7.0.202

作成する音楽の仕様

ドレミファソラシド を4回繰り返す

この記事では、MIDIスタンダード MIDI ファイル(SMF) の仕様の詳細などは説明しておりません。ご了承ください。

MIDI ファイルを作成する手順

プロジェクトを作成

プロジェクトルートフォルダに移動します。
※ ~/tmp をプロジェクトルートフォルダとします。

$ cd ~/tmp

コンソールアプリを作成します。
※ MIDIApp がアプリ名です。

$ dotnet new console -o MIDIApp -f net7.0

一度コンソールアプリをビルド・実行します。

$ cd ~/tmp/MIDIApp
$ dotnet run
Hello, World!

ここまでの作業で、C# / .NET コンソールアプリの雛形が作成できました😋

ライブラリの追加

SMF バイナリファイルを生成できる Sanford.Multimedia.Midi パッケージを NuGet で取得します。

$ dotnet add package Sanford.Multimedia.Midi

パッケージを確認します。

$ dotnet list package
プロジェクト 'MIDIApp' に次のパッケージ参照が含まれています
   [net7.0]:
   最上位レベル パッケージ                   要求済み    解決済み
   > Sanford.Multimedia.Midi      6.6.2   6.6.2

NU1701 警告を抑制します。

Sanford.Multimedia.Midi は元々 .NET 7 用には作られていないのでビルド時などに警告が表示されます。しかし、今回の利用には支障がない為、以下の記述を追加して NU1701 警告表示を抑制します。

$ vim MIDIApp.csproj
MIDIApp.csproj の一部
<Project Sdk="Microsoft.NET.Sdk">
 <!-- 省略 -->
  <PropertyGroup>
    <NoWarn>NU1701</NoWarn>
  </PropertyGroup>

</Project>

ここまでの手順で、プロジェクトに Sanford.Multimedia.Midi のパッケージを組み込むことができました。

コードの追加と修正

スタンダード MIDI ファイルに対応するバイト配列に変換するクラスを作成します。

$ vim Converter.cs
Converter.cs
using static System.Convert;
using static System.Math;

namespace MIDIApp {
    // コンバータークラス
    public static class Converter {

        // 数値 BPM を SMF のテンポ情報に変換
        public static byte[] ToByteTempo(int tempo) {
            double double_value = 60 * Pow(x: 10, y: 6) / tempo;
            string hex = int.Parse(s: Round(a: double_value).ToString()).ToString("X6"); // 16進数6桁の変換
            char[] char_array = hex.ToCharArray();
            return new byte[3]{ // 3バイトで返す
                ToByte(value: char_array[0].ToString() + char_array[1].ToString(), fromBase: 16),
                ToByte(value: char_array[2].ToString() + char_array[3].ToString(), fromBase: 16),
                ToByte(value: char_array[4].ToString() + char_array[5].ToString(), fromBase: 16)
            };
        }

        // 文字列をバイト配列に変換
        public static byte[] ToByteArray(string target) {
            return target.ToCharArray().Select(selector: x => ToByte(value: x)).ToArray();
        }
    }
}

Program.cs を修正します。

$ vim Program.cs
Program.cs
using static System.Console;

using Sanford.Multimedia.Midi;
using static Sanford.Multimedia.Midi.ChannelCommand;
using static Sanford.Multimedia.Midi.MetaType;

using static MIDIApp.Converter;

namespace MIDIApp {
    class Program {
        static void Main(string[] args) {
            // シーケンスの作成
            Sequence sequence = new();
            sequence.Format = 1;

            int channel = 0; // MIDI チャンネル番号
            int velocity = 112; // ノートオン時のベロシティ
            int bpm = 120; // テンポ
            int eighth_note_length = 6000 / (bpm * 4); // 8分音符の長さ(ミリ秒)
            string song_name = "New Song 001"; // 曲名
            string copyright = "STUDIO Awesome"; // 著作権

            // ノートの長さを 8分音符に設定
            int duration = eighth_note_length;

            // ドレミファソラシドの音階を設定
            int[] notes = { 60, 62, 64, 65, 67, 69, 71, 72 };
            notes = Enumerable.Repeat(notes, 4).SelectMany(n => n).ToArray(); // 4回繰り返す

            // コンダクタートラックの設定
            Track conductor_track = new();
            conductor_track.Insert(position: 0, new MetaMessage(Tempo, ToByteTempo(bpm)));
            conductor_track.Insert(position: 0, new MetaMessage(TrackName, ToByteArray(song_name)));
            conductor_track.Insert(position: 0, new MetaMessage(Copyright, ToByteArray(copyright)));
            sequence.Add(item: conductor_track);

            // シーケンストラックの設定
            Track sequence_track = new();
            sequence_track.Insert(position: 0, new MetaMessage(TrackName, ToByteArray("Melody")));
            sequence.Add(item: sequence_track);

            // 音階の設定
            int tick = 0; // 時間のトラッキング用変数
            foreach (int note_number in notes) {
                // ノートオンイベントの作成
                sequence_track.Insert(position: tick, new ChannelMessage(NoteOn, channel, note_number, velocity));
                // 次のノートまでの時間を加算
                tick += duration;
                // ノートオフイベントの作成
                sequence_track.Insert(position: tick, new ChannelMessage(NoteOff, channel, note_number, 0));
            }

            // MIDI ファイルの保存
            sequence.Save($"{song_name.Replace(" ", "_")}.mid");
            WriteLine("completed.");
        }
    }
}

ターミナルから実行します。

$ dotnet run
completed.

プロジェクトフォルダに以下の MIDI ファイルが出力されます。

New_Song_001.mid

ここまでの手順で、Ubuntu の C# / .NET からスタンダード MIDI ファイルを作成することができました。作成した MIDI ファイルは、Windows 11 であれば標準の Windows メディアプレイヤーなどから再生することが可能です😋

まとめ

Ubuntu 22.04 で C# からスタンダード MIDI ファイルを作成して出力することができました。

どうでしたか? Window 11 の WSL Ubuntu に、C# / .NET の開発環境を手軽に構築することができます。ぜひお試しください。今後も .NET の開発環境などを紹介していきますので、ぜひお楽しみにしてください。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1