Class: Musa::Clock::InputMidiClock

Inherits:
Clock
  • Object
show all
Defined in:
lib/musa-dsl/transport/input-midi-clock.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Clock

#on_change_position, #on_start, #on_stop, #running?

Constructor Details

#initialize(input = nil, logger: nil, do_log: nil) ⇒ InputMidiClock

Returns a new instance of InputMidiClock.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/musa-dsl/transport/input-midi-clock.rb', line 8

def initialize(input = nil, logger: nil, do_log: nil)
  do_log ||= false

  super()

  @logger = logger

  self.input = input

  if logger
    @logger = logger
  else
    @logger = Musa::Logger::Logger.new
    @logger.debug! if do_log
  end

  @time_table = []
  @midi_parser = MIDIParser.new
end

Instance Attribute Details

#inputObject

Returns the value of attribute input.



28
29
30
# File 'lib/musa-dsl/transport/input-midi-clock.rb', line 28

def input
  @input
end

#time_tableObject (readonly)

Returns the value of attribute time_table.



29
30
31
# File 'lib/musa-dsl/transport/input-midi-clock.rb', line 29

def time_table
  @time_table
end

Instance Method Details

#runObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/musa-dsl/transport/input-midi-clock.rb', line 36

def run
  @run = true

  while @run
    if @input
      raw_messages = @input.gets
    else
      @logger.warn('InputMidiClock') { 'Waiting for clock input MIDI port' }

      @waiting_for_input = Thread.current
      sleep
      @waiting_for_input = nil

      if @input
        @logger.info('InputMidiClock') { "Assigned clock input MIDI port '#{@input.name}'" }
      else
        @logger.warn('InputMidiClock') { 'Clock input MIDI port not found' }
      end
    end

    messages = []
    stop_index = nil

    raw_messages&.each do |message|
      mm = @midi_parser.parse message[:data]

      if mm
        if mm.is_a? Array
          mm.each do |m|
            stop_index = messages.size if m.name == 'Stop' && !stop_index
            messages << m
          end
        else
          stop_index = messages.size if mm.name == 'Stop' && !stop_index
          messages << mm
        end
      end
    end

    size = messages.size
    index = 0
    while index < size
      if index == stop_index && size >= index + 3 &&
          messages[index + 1].name == 'Song Position Pointer' &&
          messages[index + 2].name == 'Continue'

        @logger.debug('InputMidiClock') { 'processing Stop + Song Position Pointer + Continue...' }

        process_start unless @started

        process_message messages[index + 1] do
          yield if block_given?
        end

        index += 2

        @logger.debug('InputMidiClock') { 'processing Stop + Song Position Pointer + Continue... done' }

      else
        process_message messages[index] do
          yield if block_given?
        end
      end

      index += 1
    end

    Thread.pass
  end
end

#terminateObject



107
108
109
# File 'lib/musa-dsl/transport/input-midi-clock.rb', line 107

def terminate
  @run = false
end