«前の日記(2020年12月02日) 最新 次の日記(2020年12月09日)» 編集

一往確認日記


2020年12月08日 [長年日記]

_ ENVELOPE - その5 (MIDI編)

もうBBC Microとは関係ないのですが、成り行きでMIDIファイルについて書いてます。

前回の続きです。

midilibの使い方について調べていきます。

GitHub - jimm/midilib: Pure Ruby MIDI file and event manipulation library

from_scratch.rbが参考になりそうでしたので、一通り見ていきます。

The midilib MIDI file reader only understands MIDI file format 1

midilibではMIDIファイルフォーマット1に対応している様です。 MIDIファイルフォーマット1って何?ってなりますが、今は気に留めず先に進みます。

Gemの読み込みとMIDIモジュールのincludeをしています。

require 'midilib/sequence'
require 'midilib/consts'
include MIDI

まずはMIDIシーケンスオブジェクトを作成しています。

seq = Sequence.new()

次にトラックを追加しています。 最初のトラックは特別でテンポやシーケンス名などのメタ情報が入る専用トラックの様です。 ここでもテンポとシーケンス名を入れています。 ちなみにテンポはbpm_to_mpqでbpsからmpq(μs)に換算しています。

track = Track.new(seq)
seq.tracks << track
track.events << Tempo.new(Tempo.bpm_to_mpq(120))
track.events << MetaEvent.new(META_SEQ_NAME, 'Sequence Name')

次に2トラック目を追加し、トラック名と楽器名(音色)を設定しています。

track = Track.new(seq)
seq.tracks << track
track.name = 'My New Track'
track.instrument = GM_PATCH_NAMES[0]

次にトラックに対しイベントを追加しています。 最初はボリュームを設定しています。127は100%を示す様です。 その下は恐らく音色の指定です。

track.events << Controller.new(0, CC_VOLUME, 127)
track.events << ProgramChange.new(0, 1, 0)

こちらには音符データが入ります。 quarter_note_lengthに4分音符の長さを入れています。 NoteOnで音の開始、NoteOffで終了をしていましす。 最初の引数がMIDIチャンネルで、次が音程、次が長さです。 長さは前のNoteOnまたはNoteOffからの差分で指定する様です。

quarter_note_length = seq.note_to_delta('quarter')
[0, 2, 4, 5, 7, 9, 11, 12].each do |offset|
  track.events << NoteOn.new(0, 64 + offset, 127, 0)
  track.events << NoteOff.new(0, 64 + offset, 127, quarter_note_length)
end

最後にファイルに書き出して終了です。

File.open('from_scratch.mid', 'wb') { |file| seq.write(file) }

では出来あがったファイルを確認してみます。

GarageBandでも良いのですが、MuseScoreを使ってみます。

from_scratch.mid

音階が表示されちゃんと鳴らすこともできました。
それにしても何でCから始めてないんだろう?


Amazon | Bluetooth MIDI アダプター mi.1 II | 電子ピアノアクセサリ | 楽器