zgomot 0.1.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.rvmrc +1 -1
  2. data/README.rdoc +191 -98
  3. data/Rakefile +2 -0
  4. data/VERSION +1 -1
  5. data/bin/zgomot +1 -1
  6. data/examples/arp_chords.rb +1 -4
  7. data/examples/delay.rb +16 -0
  8. data/examples/full_scale_notes.rb +2 -5
  9. data/examples/inv_chords.rb +1 -4
  10. data/examples/modes_notes.rb +2 -5
  11. data/examples/notes.rb +1 -5
  12. data/examples/percs.rb +4 -8
  13. data/examples/percs_multi.rb +1 -5
  14. data/examples/phase_notes.rb +4 -8
  15. data/examples/prog_chords.rb +2 -5
  16. data/examples/prog_chords_multi_vel_length.rb +1 -4
  17. data/examples/prog_chords_rest.rb +1 -4
  18. data/examples/prog_notes.rb +1 -4
  19. data/examples/prog_notes_multi_vel_length.rb +1 -4
  20. data/examples/prog_notes_rest.rb +1 -4
  21. data/examples/progressive_modes.rb +10 -18
  22. data/examples/reverse_chords.rb +1 -4
  23. data/examples/route_chords.rb +22 -0
  24. data/examples/scale_chords.rb +1 -4
  25. data/examples/scale_notes.rb +1 -4
  26. data/examples/scales_notes.rb +1 -5
  27. data/examples/simple_chords.rb +1 -4
  28. data/examples/simple_input.rb +21 -0
  29. data/examples/simple_markov.rb +1 -5
  30. data/examples/simple_notes.rb +2 -5
  31. data/examples/zgomot_streams.rb +19 -0
  32. data/lib/zgomot/boot.rb +5 -31
  33. data/lib/zgomot/comp/chord.rb +16 -70
  34. data/lib/zgomot/comp/markov.rb +8 -26
  35. data/lib/zgomot/comp/mode.rb +9 -32
  36. data/lib/zgomot/comp/note.rb +1 -16
  37. data/lib/zgomot/comp/pattern.rb +1 -24
  38. data/lib/zgomot/comp/permutation.rb +0 -11
  39. data/lib/zgomot/comp/pitch_class.rb +3 -28
  40. data/lib/zgomot/comp/progression.rb +15 -49
  41. data/lib/zgomot/comp/scale.rb +5 -14
  42. data/lib/zgomot/config.rb +3 -18
  43. data/lib/zgomot/drivers/core_midi.rb +129 -92
  44. data/lib/zgomot/drivers/driver.rb +2 -15
  45. data/lib/zgomot/drivers/mgr.rb +5 -21
  46. data/lib/zgomot/main.rb +13 -24
  47. data/lib/zgomot/midi/cc.rb +67 -0
  48. data/lib/zgomot/midi/channel.rb +20 -50
  49. data/lib/zgomot/midi/clock.rb +21 -48
  50. data/lib/zgomot/midi/dispatcher.rb +13 -26
  51. data/lib/zgomot/midi/note.rb +11 -34
  52. data/lib/zgomot/midi/stream.rb +82 -43
  53. data/lib/zgomot/midi.rb +1 -0
  54. data/lib/zgomot/ui/output.rb +67 -0
  55. data/lib/zgomot/ui/windows.rb +359 -0
  56. data/lib/zgomot/ui.rb +3 -0
  57. data/lib/zgomot.rb +6 -1
  58. data/lib/{zlive.rb → zgomot_sh.rb} +1 -0
  59. data/zgomot.gems +14 -0
  60. data/zgomot.gemspec +26 -14
  61. metadata +52 -9
  62. data/default.gems +0 -7
  63. data/examples/simple_notes_length.rb +0 -17
  64. data/examples/simple_notes_velocity.rb +0 -17
@@ -1,86 +1,61 @@
1
- ##############################################################################################################
2
1
  module Zgomot::Midi
3
2
 
4
- #####-------------------------------------------------------------------------------------------------------
5
3
  class Time
6
4
 
7
- #.........................................................................................................
8
5
  attr_reader :measure, :beat, :tick, :seconds
9
-
10
- #.........................................................................................................
6
+
11
7
  def initialize(arg=nil)
12
8
  if arg.kind_of?(Hash)
13
9
  [:measure, :beat, :tick].each{|a| raise(Zgomot::Error, "#{a} is a required argument") unless args.include?(a)}
14
- init_with_measure_beat_tick(arg)
15
- elsif arg.nil?; init_with_nil
10
+ init_with_measure_beat_tick(arg)
11
+ elsif arg.nil?; init_with_nil
16
12
  elsif arg.kind_of?(Float); init_with_seconds(arg); end
17
13
  end
18
-
19
- #.........................................................................................................
20
14
  def to_s
21
- "#{measure}.#{beat}.#{tick}"
15
+ "%d:%d:%d" % [measure, beat, tick]
22
16
  end
23
-
24
- #.........................................................................................................
25
17
  def to_f
26
18
  seconds
27
19
  end
28
-
29
20
  private
30
-
31
- #.........................................................................................................
32
21
  def init_with_seconds(sec)
33
22
  @seconds = sec
34
23
  @measure = (sec/Clock.measure_sec).to_i
35
24
  @beat = ((sec % Clock.measure_sec)/Clock.beat_sec).to_i
36
25
  @tick = ((sec - measure*Clock.measure_sec - beat*Clock.beat_sec)/Clock.tick_sec).to_i
37
26
  end
38
-
39
- #.........................................................................................................
40
27
  def init_with_measure_beat_tick(args)
41
28
  @measure, @beat, @tick = args[:measure], args[:beat], args[:tick]
42
29
  @seconds = (measure*Clock.measure_sec + beat*Clock.beat_sec + tick*Clock.tick_sec).to_f
43
30
  end
44
-
45
- #.........................................................................................................
46
31
  def init_with_nil
47
32
  @measure, @beat, @tick, @seconds = 0, 0, 0, 0.0
48
33
  end
49
-
50
- #### Time
51
34
  end
52
35
 
53
- #####-------------------------------------------------------------------------------------------------------
54
36
  class Clock
55
-
56
- #.........................................................................................................
57
- @beats_per_measure, @beat_note = Zgomot.config[:time_signature].split('/').map{|v| v.to_f}
58
- @beats_per_minute = Zgomot.config[:beats_per_minute].to_f
59
- @resolution = Zgomot.config[:resolution].split('/').last.to_f
60
- @beat_sec= 60.0/@beats_per_minute
61
- @whole_note_sec = @beat_sec*@beat_note
62
- @measure_sec = @beat_sec*@beats_per_measure
63
- @tick_sec = @whole_note_sec/(@resolution)
64
-
65
- #####-------------------------------------------------------------------------------------------------------
66
37
  class << self
67
-
68
- #.........................................................................................................
69
- attr_accessor :beat_note, :beats_per_measure, :beats_per_minute, :resolution,
70
- :beat_sec, :whole_note_sec, :measure_sec, :tick_sec
71
-
72
- #### self
38
+ attr_accessor :beat_note, :beats_per_measure, :beats_per_minute, :resolution,
39
+ :beat_sec, :whole_note_sec, :measure_sec, :tick_sec, :time_signature
40
+ def set_config(config)
41
+ @time_signature = config[:time_signature] || '4/4'
42
+ @beats_per_minute = (config[:beats_per_minute] || '120').to_f
43
+ @resolution = (config[:resolution] || '1/32').split('/').last.to_f
44
+ @beats_per_measure, @beat_note = @time_signature.split('/').map{|v| v.to_f}
45
+ @beat_sec= 60.0/@beats_per_minute
46
+ @whole_note_sec = @beat_sec*@beat_note
47
+ @measure_sec = @beat_sec*@beats_per_measure
48
+ @tick_sec = @whole_note_sec/(@resolution);nil
49
+ end
73
50
  end
74
-
75
- #...........................................................................................................
51
+ set_config(Zgomot.config)
76
52
  attr_reader :current_time
77
-
78
- #...........................................................................................................
79
53
  def initialize
80
54
  @current_time = Time.new
81
55
  end
82
-
83
- #...........................................................................................................
56
+ def to_s
57
+ @current_time.to_s
58
+ end
84
59
  def update(time=nil)
85
60
  csecs = if time.kind_of?(Float)
86
61
  current_time.to_f + time
@@ -89,13 +64,11 @@ module Zgomot::Midi
89
64
  elsif time.nil?
90
65
  current_time.to_f + Clock.tick_sec
91
66
  else
92
- raise(Zgomot::Error, "argument must by of type Float or Zgomot::Midi::Time")
67
+ raise(Zgomot::Error, "argument must by of type Float or Zgomot::Midi::Time")
93
68
  end
94
69
  @current_time = Time.new(csecs)
95
70
  end
96
71
 
97
- #### Clock
98
72
  end
99
73
 
100
- #### Zgomot ::Midi
101
74
  end
@@ -1,92 +1,79 @@
1
- ##############################################################################################################
2
1
  module Zgomot::Midi
3
2
 
4
- #####-------------------------------------------------------------------------------------------------------
5
3
  class Dispatcher
6
4
 
7
- #.........................................................................................................
8
5
  @queue, @playing = [], []
9
6
  @qmutex, @qdispatch = Mutex.new, Mutex.new
10
-
11
- #.........................................................................................................
7
+
12
8
  @clock = Clock.new
13
9
  @tick = Clock.tick_sec
14
10
 
15
- #####-------------------------------------------------------------------------------------------------------
16
11
  class << self
17
-
18
- #.........................................................................................................
12
+
19
13
  attr_reader :resolution, :queue, :thread, :clock, :tick, :qmutex, :qdispatch, :playing, :last_time
20
14
 
21
- #.........................................................................................................
15
+ def clk
16
+ clock.to_s
17
+ end
18
+
22
19
  def flush
23
20
  @queue.clear
24
21
  end
25
- #.........................................................................................................
22
+
26
23
  def done?
27
24
  qdispatch.synchronize{queue.empty? and playing.empty?}
28
25
  end
29
26
 
30
- #.........................................................................................................
31
- def enqueue(ch)
27
+ def enqueue(ch)
32
28
  qmutex.synchronize do
33
29
  @queue += ch.pattern.map{|p| p.to_midi}.flatten.compact.select{|n| not n.pitch_class.eql?(:R)}
34
30
  end
35
31
  end
36
-
37
- #.........................................................................................................
32
+
38
33
  def dequeue(time)
39
34
  qmutex.synchronize do
40
35
  queue.partition{|n| n.play_at <= time}
41
36
  end
42
37
  end
43
38
 
44
- #.........................................................................................................
45
39
  def dispatch(now)
46
- qdispatch.synchronize do
40
+ qdispatch.synchronize do
47
41
  ready, @queue = dequeue(now)
48
42
  notes_off(now)
49
43
  notes_on(ready)
50
44
  end
51
45
  end
52
46
 
53
- #.........................................................................................................
54
47
  def notes_on(notes)
55
- notes.each do |n|
48
+ notes.each do |n|
56
49
  Zgomot.logger.info "NOTE ON: #{n.channel} : #{n.to_s} : #{n.time.to_s} : #{clock.current_time.to_s}"
57
50
  Zgomot::Drivers::Mgr.note_on(n.midi, n.channel, (127*n.velocity).to_i)
58
51
  end
59
52
  @playing += notes
60
53
  end
61
54
 
62
- #.........................................................................................................
63
55
  def notes_off(time)
64
56
  turn_off, @playing = playing.partition{|n| (n.play_at+n.length_to_sec) <= time}
65
- turn_off.each do |n|
57
+ turn_off.each do |n|
66
58
  Zgomot.logger.info "NOTE OFF:#{n.channel} : #{n.to_s} : #{n.time.to_s} : #{clock.current_time.to_s}"
67
59
  Zgomot::Drivers::Mgr.note_off(n.midi, n.channel, (127*n.velocity).to_i)
68
60
  end
69
61
  end
70
62
 
71
- #.........................................................................................................
72
63
  private :dispatch, :notes_on, :notes_off
73
64
 
74
- #### self
75
65
  end
76
66
 
77
- #.........................................................................................................
78
67
  @thread = Thread.new do
79
68
  loop do
80
69
  now = ::Time.now.truncate_to(Clock.tick_sec)
81
- dispatch(now)
70
+ dispatch(now)
82
71
  clock.update(last_time.nil? ? tick : now-last_time)
83
72
  @last_time = now
84
73
  sleep(tick)
85
74
  end
86
75
  end
87
76
 
88
- #### Dispatcher
89
77
  end
90
78
 
91
- #### Zgomot::Midi
92
79
  end
@@ -1,10 +1,7 @@
1
- ##############################################################################################################
2
1
  module Zgomot::Midi
3
2
 
4
- #####-------------------------------------------------------------------------------------------------------
5
3
  class Note
6
-
7
- #.........................................................................................................
4
+
8
5
  PITCH_CLASS = {
9
6
  :C => 0, :Bs => 0,
10
7
  :Cs => 1, :Db => 1,
@@ -13,38 +10,32 @@ module Zgomot::Midi
13
10
  :E => 4, :Fd => 4,
14
11
  :F => 5, :Es => 5,
15
12
  :Fs => 6, :Gb => 6,
16
- :G => 7,
13
+ :G => 7,
17
14
  :Gs => 8, :Ab => 8,
18
15
  :A => 9,
19
16
  :As => 10, :Bb => 10,
20
- :B => 11, :Cb => 11,
21
- :R => -1,
17
+ :B => 11, :Cb => 11,
18
+ :R => -1,
22
19
  }
23
20
 
24
- #.........................................................................................................
25
21
  LENGTH = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024].select{|d| d <= Clock.resolution}
26
22
 
27
- #.........................................................................................................
28
23
  OCTAVE = (-1..9).to_a
29
24
 
30
- #####-------------------------------------------------------------------------------------------------------
31
25
  class << self
32
26
 
33
- #### self
34
27
  end
35
-
36
- #.........................................................................................................
28
+
37
29
  attr_reader :pitch_class, :octave, :midi, :time_scale
38
30
  attr_accessor :time, :offset_time, :channel, :velocity, :length
39
-
40
- #.........................................................................................................
31
+
41
32
  def initialize(args)
42
33
  @pitch_class, @octave = case args[:pitch]
43
34
  when Array then args[:pitch]
44
35
  when Symbol then [args[:pitch], 4]
45
36
  else raise(Zgomot::Error, "#{args[:pitch].inspect} is invalid pitch")
46
37
  end
47
- @length, @velocity = args[:length], args[:velocity]
38
+ @length, @velocity = args[:length], args[:velocity]
48
39
  @midi = pitch_to_midi(pitch_class, octave)
49
40
  @time_scale = 1.0
50
41
  raise(Zgomot::Error, "#{octave} is invalid octave") unless OCTAVE.include?(octave)
@@ -53,52 +44,38 @@ module Zgomot::Midi
53
44
  raise(Zgomot::Error, "#{velocity} is invalid velocity") unless velocity < 1.0
54
45
  end
55
46
 
56
- #.........................................................................................................
57
47
  def to_s
58
48
  "[#{pitch_class.to_s},#{octave}].#{length}.#{midi}.#{velocity}"
59
49
  end
60
50
 
61
- #.........................................................................................................
62
- # transforms
63
- #.........................................................................................................
64
51
  def bpm!(bpm)
65
52
  @time_scale = 1.0/bpm.to_f; self
66
53
  end
67
54
 
68
- #.........................................................................................................
69
55
  def octave!(oct)
70
56
  @octave = oct; self
71
57
  end
72
-
73
- #.........................................................................................................
74
- # channel and dispatch interface
75
- #.........................................................................................................
58
+
76
59
  def play_at
77
60
  time.to_f + offset_time.to_f
78
61
  end
79
-
80
- #.........................................................................................................
62
+
81
63
  def length_to_sec
82
64
  time_scale*Clock.whole_note_sec/length
83
65
  end
84
66
 
85
- #.........................................................................................................
86
67
  def to_midi
87
68
  self
88
69
  end
89
-
90
- #.........................................................................................................
70
+
91
71
  def pitch_to_midi(pitch_class, octave)
92
72
  if PITCH_CLASS[pitch_class]
93
73
  (midi = 12*(octave+1)+PITCH_CLASS[pitch_class]) <= 127 ? midi : nil
94
74
  end
95
75
  end
96
76
 
97
- #.........................................................................................................
98
77
  private :pitch_to_midi
99
-
100
- #### Note
78
+
101
79
  end
102
80
 
103
- #### Zgomot::Midi
104
81
  end
@@ -1,76 +1,115 @@
1
- ##############################################################################################################
2
1
  module Zgomot::Midi
3
2
 
4
- #####-------------------------------------------------------------------------------------------------------
5
3
  class Stream
6
4
 
7
- #.........................................................................................................
8
5
  @streams = []
9
6
 
10
- #####-------------------------------------------------------------------------------------------------------
11
7
  class << self
12
-
13
- #.........................................................................................................
14
8
  attr_reader :streams
15
-
16
- #.........................................................................................................
17
9
  def str(name, pattern=nil, opts={}, &blk)
18
- strm = new(name, blk.arity, pattern, opts[:lim])
19
- strm.define_meta_class_method(:play, &blk)
10
+ strm = new(name, blk.arity, pattern, opts)
11
+ strm.define_meta_class_method(:play, &blk)
20
12
  @streams << strm
21
13
  end
22
-
23
- #.........................................................................................................
24
- def play
25
- streams.each{|s| s.dispatch(::Time.now.truncate_to(Clock.tick_sec) + Zgomot::PLAY_DELAY) if s.status.eql?(:new)}
14
+ def play(name=nil)
15
+ start_time = ::Time.now.truncate_to(Clock.tick_sec) + Zgomot::PLAY_DELAY
16
+ if name.nil?
17
+ streams.reduce([]) do |a, s|
18
+ if s.status_eql?(:paused)
19
+ s.dispatch(start_time + s.delay)
20
+ a << s.name
21
+ end; a
22
+ end
23
+ else
24
+ apply_to_stream(name){|stream|
25
+ stream.status_eql?(:paused) ? (stream.dispatch(start_time + stream.delay); name) : nil}
26
+ end
27
+ end
28
+ alias_method :run, :play
29
+ def pause(name=nil)
30
+ if name.nil?
31
+ streams.each do |stream|
32
+ stream.update_status(:paused)
33
+ end; true
34
+ else
35
+ apply_to_stream(name) do |stream|
36
+ stream.update_status(:paused)
37
+ name
38
+ end
39
+ end
40
+ end
41
+ alias_method :stop, :pause
42
+ def tog(name)
43
+ apply_to_stream(name) do |stream|
44
+ stream.status_eql?(:playing) ? pause(name) : play(name)
45
+ end
46
+ end
47
+ def apply_to_stream(name)
48
+ stream = streams.find{|s| s.name == name.to_s}
49
+ if stream
50
+ yield stream
51
+ else
52
+ Zgomot.logger.error "STREAM '#{name}' NOT FOUND"; nil
53
+ end
26
54
  end
27
-
28
- #### self
29
55
  end
30
-
31
- #####-------------------------------------------------------------------------------------------------------
32
- attr_reader :patterns, :times, :status, :count, :thread, :limit, :name, :play_meth
33
-
34
- #.........................................................................................................
35
- def initialize(name, arity, pattern, limit)
36
- @patterns, @times = [Zgomot::Comp::Pattern.new(pattern)], [Time.new]
37
- @limit, @name, @count, @thread, @status = limit || :inf, name, 0, nil, :new
56
+
57
+ attr_accessor :count
58
+ attr_reader :patterns, :status, :thread, :limit, :name, :play_meth,
59
+ :delay, :ch
60
+
61
+ def initialize(name, arity, pattern, opts)
62
+ @patterns = [Zgomot::Comp::Pattern.new(pattern)]
63
+ @delay = (opts[:del].to_f * 60.0/ Zgomot.config[:beats_per_minute].to_f).to_i || 0
64
+ @limit, @name, @thread, @status, @count = opts[:lim] || :inf, name, nil, :paused, 0
65
+ @ch = Zgomot::Midi::Channel.ch(opts[:ch] || 0)
38
66
  @play_meth = "play#{arity.eql?(-1) ? 0 : arity}".to_sym
67
+ @status_mutex = Mutex.new
39
68
  end
40
-
41
- #.........................................................................................................
42
- def dispatch(start_time)
43
- ch_time, @status = 0.0, :playing
69
+ def update_status(new_status)
70
+ @status_mutex.synchronize do
71
+ @status = new_status
72
+ end
73
+ end
74
+ def status_eql?(test_status)
75
+ @status_mutex.synchronize do
76
+ @status == test_status
77
+ end
78
+ end
79
+ def info
80
+ [name, status, ch.number, ch.clock, count, limit, delay].map(&:to_s)
81
+ end
82
+ def dispatch(start_time)
83
+ @count = 0
84
+ ch.set_clock
85
+ update_status(:playing)
44
86
  @thread = Thread.new do
45
- loop do
87
+ while(status_eql?(:playing)) do
46
88
  @count += 1
89
+ loop_time = ::Time.now
47
90
  break if not limit.eql?(:inf) and count > limit
48
- if self.respond_to?(play_meth, true)
49
- if (chan = self.send(play_meth)).kind_of?(Zgomot::Midi::Channel)
50
- Dispatcher.enqueue(chan.time_shift(start_time+ch_time))
91
+ if self.respond_to?(play_meth, true)
92
+ if pattern = self.send(play_meth)
93
+ ch << pattern
94
+ Dispatcher.enqueue(ch.time_shift(start_time))
51
95
  else; break; end
52
96
  else
53
97
  raise(Zgomot::Error, 'str block arity not supported')
54
98
  end
55
99
  Zgomot.logger.info "STREAM:#{count}:#{name}"
56
- patterns << Zgomot::Comp::Pattern.new(chan.pattern)
57
- ch_time += chan.length_to_sec; times << Time.new(ch_time)
58
- sleep(0.80*(start_time+ch_time-::Time.now.truncate_to(Clock.tick_sec)))
100
+ patterns << Zgomot::Comp::Pattern.new(ch.pattern)
101
+ sleep(ch.length_to_sec) if count > 1
59
102
  end
60
103
  Zgomot.logger.info "STREAM FINISHED:#{name}"
61
- @status = :finished
62
- end
104
+ update_status(:paused)
105
+ end
63
106
  end
64
-
65
- #.........................................................................................................
107
+
66
108
  def play0;play;end
67
109
  def play1;play(Marshal.load(Marshal.dump(patterns.last)));end
68
110
 
69
- #.........................................................................................................
70
111
  private :play0, :play1
71
-
72
- #### Stream
112
+
73
113
  end
74
114
 
75
- #### Zgomot::Midi
76
115
  end
data/lib/zgomot/midi.rb CHANGED
@@ -3,3 +3,4 @@ require 'zgomot/midi/note'
3
3
  require 'zgomot/midi/channel'
4
4
  require 'zgomot/midi/stream'
5
5
  require 'zgomot/midi/dispatcher'
6
+ require 'zgomot/midi/cc'
@@ -0,0 +1,67 @@
1
+ module Zgomot::UI
2
+ class Output
3
+ @stream_mgr = Zgomot::Midi::Stream
4
+ @cc_mgr = Zgomot::Midi::CC
5
+ @clk_mgr = Zgomot::Midi::Clock
6
+ HEADER_COLOR = '#666666'
7
+ STREAM_OUTPUT_FORMAT_WIDTHS = [30, 9, 6, 11, 9, 8, 7]
8
+ STREAM_HEADER = %w(Name Status Chan Time Count Limit Delay)
9
+ STREAM_STATUS_PLAY_COLOR = '#19D119'
10
+ STREAM_STATUS_PAUSE_COLOR = '#EAC117'
11
+ CC_OUTPUT_FORMAT_WIDTHS = [30, 10, 8, 8, 8, 8, 8]
12
+ CC_HEADER = %w(Name Value CC Chan Type Max Min)
13
+ CC_COLOR = '#EAC117'
14
+ CONFIG_COLOR = '#EAC117'
15
+ class << self
16
+ attr_reader :stream_mgr, :cc_mgr, :clk_mgr
17
+ def lstr(name=nil)
18
+ puts format_for_color(STREAM_OUTPUT_FORMAT_WIDTHS, HEADER_COLOR) % color(STREAM_HEADER, HEADER_COLOR)
19
+ format_streams(name).each{|stream| puts stream}; nil
20
+ end
21
+ def lcc(name=nil)
22
+ puts format_for_color(CC_OUTPUT_FORMAT_WIDTHS, HEADER_COLOR) % color(CC_HEADER, HEADER_COLOR)
23
+ format_ccs(name).each{|cc| puts cc}; nil
24
+ end
25
+ def lconfig
26
+ format = '%-35s %-25s'
27
+ puts format % ['Time Signature'.foreground(HEADER_COLOR), clk_mgr.time_signature.foreground(CONFIG_COLOR)]
28
+ puts format % ['Beats/Minute'.foreground(HEADER_COLOR), clk_mgr.beats_per_minute.to_i.to_s.foreground(CONFIG_COLOR)]
29
+ puts format % ['Resolution'.foreground(HEADER_COLOR), "1/#{clk_mgr.resolution.to_i}".foreground(CONFIG_COLOR)]
30
+ puts format % ['Seconds/Beat'.foreground(HEADER_COLOR), clk_mgr.beat_sec.to_s.foreground(CONFIG_COLOR)]
31
+ end
32
+ private
33
+ def color(string, color)
34
+ Array(string).map{|s| s.to_s.foreground(color)}
35
+ end
36
+ def format_for_color(widths, color)
37
+ color_offset = "".color(color).length
38
+ widths.map{|width| "%-#{width+color_offset}s"}.join(" ")
39
+ end
40
+ def format_stream_info(stream)
41
+ stream_output = stream.info
42
+ value_color = stream.status_eql?(:playing) ? STREAM_STATUS_PLAY_COLOR : STREAM_STATUS_PAUSE_COLOR
43
+ format_for_color(STREAM_OUTPUT_FORMAT_WIDTHS, value_color) % color(stream_output, value_color)
44
+ end
45
+ def format_streams(name=nil)
46
+ if name.nil?
47
+ stream_mgr.streams.map{|stream| format_stream_info(stream)}
48
+ else
49
+ [stream_mgr.apply_to_stream(name.to_s){|stream| stream_info(stream)}]
50
+ end
51
+ end
52
+ def format_cc_config(config)
53
+ format_for_color(CC_OUTPUT_FORMAT_WIDTHS, CC_COLOR) % color(config, CC_COLOR)
54
+ end
55
+ def format_cc_info(name)
56
+ cc_mgr.info(name).map{|config| format_cc_config(config)}
57
+ end
58
+ def format_ccs(name=nil)
59
+ if name.nil?
60
+ cc_mgr.cc_names.reduce([]){|ccs, cc_name| ccs + format_cc_info(cc_name)}
61
+ else
62
+ format_cc_info(name.to_sym)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end