class SMF::Sheet
Public Class Methods
new(sq)
click to toggle source
# File lib/smf/toy/macro.rb, line 12 def initialize(sq) @sq = sq @co = [] gt(0) end
Public Instance Methods
generate()
click to toggle source
# File lib/smf/toy/macro.rb, line 34 def generate i = 0 @co = @co.sort_by{|x| [x[:of], i += 1]} i = 0 lev = {} uniq = {} @co.each do |ev| ev.each_key do |key| if ev[key] == nil || ev[key] == lev[key] next end case key.to_s when /\A_(no|tx|ke)/ k = format('%d:%s', i, key) uniq[k] = [i, key, ev] when /\A(te|ti|pp|co|mo|pr|cp|pi|gm)/ k = format('%s:%s', ev[:of], key) if uniq[k] uniq[k] = [uniq[k][0], key, ev] else uniq[k] = [i, key, ev] end lev[key] = ev[key] end i += 1 end end co2 = uniq.values.sort_by{|x| x[0]} wh = @sq.division * 4 ke = {} co2.each do |_, key, ev| tr = ev[:tr].to_i; tr = re(tr, 0, 65535) # 0/2**16-1 ch = ev[:ch].to_i; ch = re(ch, 0, 15) # 0/2**4-1 of = ev[:of]; of = re(of, 0) oc = ev[:oc] le = ev[:le]; le = re(le, 0.to_r) du = ev[:du]; du = re(du, 0.to_r) ve = ev[:ve]; ve = re(ve, 0.to_r, 1.to_r) sf, = ev[:ke]; sf ||= 0 v = ev[key] case key.to_s when '_no' t = gt(tr) o = (of * wh).round p = ((of + le * du) * wh).round na, s1, s12 = v unless s1 unless ke[sf] ke[sf] = [0] * 12 d = if sf < 0 then -1 else +1 end b = if d == 1 then 5 else 11 end sf.to_i.abs.times do |j| n = (b + 7 * j * d) % 12 ke[sf][n] += d end end s1 = ke[sf][na] end s1 ||=0 s12 ||=0 n = (na + s1 + s12 + oc * 12 + 12).to_i if n < 0 then n = n % 12 end if n > 127 then n = 116 + (n - 116) % 12 end w = (ve * 127).round if w != 0 t << NoteOn.new(o, ch, n, w) t << NoteOff.new(p, ch, n, 64) end when '_tx' n = if /\A(co|sq):/ =~ v then 0 else tr end t = gt(n) o = (of * wh).round case v when /\Ate:/; t << GeneralPurposeText.new(o, $') when /\Aco:/; t << CopyrightNotice.new(o, $') when /\Asq:/; t << SequenceName.new(o, $') when /\Atr:/; t << TrackName.new(o, $') when /\Ain:/; t << InstrumentName.new(o, $') when /\Aly:/; t << Lyric.new(o, $') when /\Ama:/; t << Marker.new(o, $') when /\Acu:/; t << CuePoint.new(o, $') when /\Apr:/; t << ProgramName.new(o, $') when /\Ade:/; t << DeviceName.new(o, $') else; t << GeneralPurposeText.new(o, v) end when '_ke' s, m = v m ||= 0 s = re(s, -128, 127) # -2**7/2**7-1 m = re(m, 0, 1) # 0/1 t = gt(tr) o = (of * wh).round t << KeySignature.new(o, s.to_i, m.to_i) when 'te' v = re(v, 1, 16777215) # 1/2**24-1 t = gt(0) o = (of * wh).round t << SetTempo.new(o, (60000000 / v).round) when 'ti' n, d = v d ||= 4 n = re(n, 1, 255) # 1/2**8-1 d = re(d, 0, 255) # 0/2**8-1 t = gt(0) o = (of * wh).round n, d = n.to_i, d.to_i dd = -1 while d != 0 d >>= 1 dd += 1 end c = 96 >> dd t << TimeSignature.new(o, n, dd, c, 8) when /\App(\d+)\/\d+\z/ n = $1 v = re(v, 0, 127) # 0/2**7-1 t = gt(tr) o = (of * wh).round t << PolyphonicKeyPressure.new(o, ch, n.to_i, v.to_i) when /\Aco(\d+)\/\d+\z/ n = $1 v = re(v, 0, 127) # 0/2**7-1 t = gt(tr) o = (of * wh).round t << ControlChange.new(o, ch, n.to_i, v.to_i) when /\Amo(\d+)\/\d+\z/ n = $1 v = re(v, 0, 127) # 0/2**7-1 t = gt(tr) o = (of * wh).round case n.to_i when 0x78; t << AllSoundOff.new(o, ch) when 0x79; t << ResetAllControllers.new(o, ch) when 0x7a; t << LocalControl.new(o, ch, v) when 0x7b; t << AllNotesOff.new(o, ch) when 0x7c; t << OmniOff.new(o, ch) when 0x7d; t << OmniOn.new(o, ch) when 0x7e; t << MonoMode.new(o, ch, v) when 0x7f; t << PolyMode.new(o, ch) end when /\Apr\/\d+\z/ v = re(v, 0, 127) # 0/2**7-1 t = gt(tr) o = (of * wh).round t << ProgramChange.new(o, ch, v.to_i) when /\Acp\/\d+\z/ v = re(v, 0, 127) # 0/2**7-1 t = gt(tr) o = (of * wh).round t << ChannelPressure.new(o, ch, v.to_i) when /\Api\/\d+\z/ v = re(v, -8192, 8191) # -2**13/2**13-1 t = gt(tr) o = (of * wh).round t << PitchBendChange.new(o, ch, v.to_i) when 'gm' v = re(v, 0, 2) # 0/2 t = gt(0) o = (of * wh).round case v when 0; t << GMSystemOff.new(o) when 1; t << GMSystemOn.new(o) when 2; t << GM2SystemOn.new(o) end end end ev = @co[-1] max_of = (if ev then ev[:of] else 0 end) o = (max_of * wh).round @sq.each do |tr| tr << EndOfTrack.new(o) end end
snap(ev)
click to toggle source
# File lib/smf/toy/macro.rb, line 18 def snap(ev) @co << ev end
Private Instance Methods
gt(n)
click to toggle source
# File lib/smf/toy/macro.rb, line 22 def gt(n) @sq[n] ||= Track.new end
re(v, l, h=nil)
click to toggle source
# File lib/smf/toy/macro.rb, line 26 def re(v, l, h=nil) if v && l && v < l then v = l end if v && h && v > h then v = h end v end