Ruby の組み込み、ぼちぼちと進んでいます。こんなコードを書くと:
def change_control_number hash = MRDialog.run { layout(2, 2, item(:text, :title=>"Old control number"), item(:textfield, :width=>40, :range=>[0, 127], :tag=>"old"), item(:text, :title=>"New control number"), item(:textfield, :width=>40, :range=>[0, 127], :tag=>"new")) } if hash old = hash["old"] new = hash["new"] (0...number_of_tracks).each { |n| pt = pointer(n) while pt.next if pt.kind == :control && pt.code == old pt.code = new end end } end end
こんなダイアログが出てきて:
OK ボタンを押すと、全部のトラックの CC#11 が CC#7 に置換される。ちゃんと undo も効く。
上のコードの中で、
pt = pointer(n); while pt.next ... end
という記述は今ひとつこなれていない。MIDI イベントというのは単独のオブジェクトにしてしまうと編集時にいろいろ不都合があって、「トラックの中の特定位置」というオブジェクトで間接参照する必要がある。この「特定位置」を示すオブジェクトを与えるのが pointer(n)
なのだが、ちょっとわかりにくい。こんな風に書けた方がスマートかな。
track(n).for_all_events { |ev| if ev.kind == :control ... }