Class: Musa::MIDIRecorder::MIDIRecorder
- Defined in:
- lib/musa-dsl/midi/midi-recorder.rb
Overview
Collects raw MIDI bytes alongside the sequencer position and transforms them into note events. It is especially useful when capturing phrases from an external controller that is clocked by the sequencer timeline.
The recorder uses the midi-parser gem to parse raw MIDI bytes into MIDIEvents objects, then pairs note-on/note-off events to calculate durations and detect silences.
Instance Method Summary collapse
-
#clear ⇒ void
Clears all stored events.
- #initialize(sequencer) ⇒ void constructor
-
#raw ⇒ Array<Message>
Unprocessed recorded messages.
-
#record(midi_bytes) ⇒ void
Records one MIDI packet.
-
#transcription ⇒ Array<Hash>
Converts the message buffer into a list of note hashes.
Constructor Details
#initialize(sequencer) ⇒ void
84 85 86 87 88 89 |
# File 'lib/musa-dsl/midi/midi-recorder.rb', line 84 def initialize(sequencer) @sequencer = sequencer @midi_parser = MIDIParser.new clear end |
Instance Method Details
#clear ⇒ void
This method returns an undefined value.
Clears all stored events.
94 95 96 |
# File 'lib/musa-dsl/midi/midi-recorder.rb', line 94 def clear @messages = [] end |
#raw ⇒ Array<Message>
Returns unprocessed recorded messages.
112 113 114 |
# File 'lib/musa-dsl/midi/midi-recorder.rb', line 112 def raw @messages end |
#record(midi_bytes) ⇒ void
This method returns an undefined value.
Records one MIDI packet.
102 103 104 105 106 107 108 109 |
# File 'lib/musa-dsl/midi/midi-recorder.rb', line 102 def record(midi_bytes) m = @midi_parser.parse midi_bytes m = [m] unless m.is_a? Array m.each do |mm| @messages << Message.new(@sequencer.position, mm) end end |
#transcription ⇒ Array<Hash>
Converts the message buffer into a list of note hashes.
Each note hash contains the keys :position, :channel, :pitch, :velocity
and, when appropriate, :duration and :velocity_off. Silences (gaps between
notes on the same channel) are expressed as pitch: :silence.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/musa-dsl/midi/midi-recorder.rb', line 129 def transcription note_on = {} last_note = {} notes = [] @messages.each do |m| mm = m. case mm when MIDIEvents::NoteOn if last_note[mm.channel] notes << { position: last_note[mm.channel], channel: mm.channel, pitch: :silence, duration: m.position - last_note[mm.channel] } last_note.delete mm.channel end note = { position: m.position, channel: mm.channel, pitch: mm.note, velocity: mm.velocity } note_on[mm.channel] ||= {} note_on[mm.channel][mm.note] = note notes << note when MIDIEvents::NoteOff note_on[mm.channel] ||= {} note = note_on[mm.channel][mm.note] if note note_on[mm.channel].delete mm.note note[:duration] = m.position - note[:position] note[:velocity_off] = mm.velocity end last_note[mm.channel] = m.position end end notes end |