Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Preliminary support for midi controllers and tempo changes.

  • Loading branch information...
commit ba072f8f849179ab970adf13d04495054a93d2f1 1 parent e0afa69
Jeremy Voorhis authored
4 lib/music/pretty_printer.rb
@@ -21,5 +21,9 @@ def eval_note(note, context)
21 21 def eval_rest(rest, context)
22 22 "rest(#{rest.duration})"
23 23 end
  24 +
  25 + def eval_controller(ctl, context)
  26 + "ctl(#{ctl.name}, #{ctl.data})"
  27 + end
24 28 end
25 29 end
4 lib/music/score.rb
@@ -325,8 +325,8 @@ class Controller < ScoreObject
325 325 include Instant
326 326 attr_reader :attributes
327 327
328   - def initialize(name, value, attrs = {})
329   - @attributes = attrs.merge(:name => name, :value => value)
  328 + def initialize(name, data, attrs = {})
  329 + @attributes = attrs.merge(:name => name, :data => Array(data))
330 330 end
331 331
332 332 def ==(other)
35 lib/music/smf_writer.rb
@@ -14,20 +14,16 @@ def initialize(options = {})
14 14 def track(arrangement_or_timeline, options = {})
15 15 timeline = arrangement_or_timeline.to_timeline
16 16 track = Track.new
17   - channel = options.fetch(:channel, 1)
18 17 name = options.fetch(:name, gen_seq_name)
19 18
20 19 track << SequenceName.new(0, name)
21 20 track << @tempo
22 21
23 22 timeline.each_with_time do |note, time|
24   - attack = @time.ppqn(time)
25   - release = attack + @time.ppqn(note.duration)
26   - pitch = note.pitch.to_i
27   - velocity = note.attributes.fetch(:velocity, 80)
28   -
29   - track << NoteOn.new(attack, channel, pitch, velocity)
30   - track << NoteOff.new(release, channel, pitch, velocity)
  23 + case note
  24 + when Note: write_note(track, note, time)
  25 + when Controller: write_controller(track, note, time)
  26 + end
31 27 end
32 28
33 29 @seq << track
@@ -50,5 +46,28 @@ def gen_seq_name
50 46 def bpm_to_qn_per_usec(bpm)
51 47 (60_000_000.0 / bpm).to_i
52 48 end
  49 +
  50 + def write_note(track, note, time)
  51 + attack = @time.ppqn(time)
  52 + release = attack + @time.ppqn(note.duration)
  53 + pitch = note.pitch.to_i
  54 + velocity = note.attributes.fetch(:velocity, 80)
  55 + channel = note.read(:channel) || 1
  56 +
  57 + track << NoteOn.new(attack, channel, pitch, velocity)
  58 + track << NoteOff.new(release, channel, pitch, velocity)
  59 + end
  60 +
  61 + def write_controller(track, ctl, time)
  62 + offset = @time.ppqn(time)
  63 + channel = ctl.read(:channel) || 1
  64 +
  65 + track << case ctl.name.to_s
  66 + when 'tempo'
  67 + SetTempo.new(offset, ctl.data[0])
  68 + when /^cc(0?[1-9]|1[0-6])$/
  69 + ControlChange.new(offset, channel, $1, ctl.data[0])
  70 + end
  71 + end
53 72 end
54 73 end
4 lib/music/timeline.rb
@@ -75,5 +75,9 @@ def eval_note(note, context)
75 75 def eval_rest(rest, context)
76 76 Timeline.new([])
77 77 end
  78 +
  79 + def eval_controller(ctl, context)
  80 + Timeline.new([Event.new(context.time, ctl)])
  81 + end
78 82 end
79 83 end
4 spec/score_spec.rb
@@ -230,6 +230,10 @@
230 230 end
231 231
232 232 it_should_behave_like "all scores"
  233 +
  234 + it "should carry associated data" do
  235 + @object.data.should == [120]
  236 + end
233 237 end
234 238
235 239 describe "All ScoreObjects" do

0 comments on commit ba072f8

Please sign in to comment.
Something went wrong with that request. Please try again.