テキストから MIDI ファイルを作成する

MIDI とスクリプトの勉強を兼ね、テキストから MIDI ファイルを作成してみました

環境

MIDI ファイルを再生できること、また Ruby が動くこと

MIDI データ

  • C コードを 1 回だけ鳴らす
  • SMF(Standard MIDI Files) のフォーマットに従い、テキストで書く
  • cmajor.txt
4D 54 68 64 00 00 00 06 00 00 00 01 00 01 4D 54 72 6B 00 00 00 1C 00 90 3C 40 00 90 40 40 00 90 43 40 04 80 3C 00 00 80 40 00 00 80 43 00 00 FF 2F 00
  • 上だけ見ると訳がわかりませんが、次のような構造です
4D 54 68 64 # ヘッダ
00 00 00 06 # データ長:6[byte]
00 01       # フォーマット:1
00 01       # トラック数:1
00 01       # 1 拍の分解能:1

4D 54 72 6B # トラック 1 開始
00 00 00 1C # データ長: 28[byte]
00 90 3C 40 # 0拍後, オン:ch0, key:3C(ド), vel:40
00 90 40 40 # 0拍後, オン:ch0, key:40(ミ), vel:40
00 90 43 40 # 0拍後, オン:ch0, key:43(ソ), vel:40
04 80 3C 00 # 4拍後, オフ:ch0, key:3C
00 80 40 00 # 0拍後, オフ:ch0, key:40
00 80 43 00 # 0拍後, オフ:ch0, key:43
00 FF 2F 00 # トラック 1 終了

しかし

  • 実際の MIDI ファイルはバイナリです
  • 一方、作成した cmajor.txt はテキストのため、このままでは Windows Media Player 等で再生することができません
  • このため、cmajor.txt に記載したデータをバイナリ化します

テキストの 16 進数をバイナリ表示するスクリプト

  • txt_to_bin.rb
 #!/usr/bin/ruby
 
 array = []
 
 filename = ARGV[0]
 file = open( filename )
 text = file.read
 file.close
 
 array << text.split.join
 binary = array.pack( "H*" )
 
 print binary

バイナリ化したデータを cmajor.midi へ書き込み

 ruby txt_to_bin.rb cmajor.txt > cmajor.midi

新規作成された cmajor.midiWindows Media Player 等で再生すると、C のコードが 1 回鳴るはずです

参考