Module: MidiPatch
- Defined in:
- lib/midi_patch.rb
Constant Summary collapse
- STEPWISE_X_DELTA =
0.0001
Class Method Summary collapse
- .add_to_stack(stack, event) ⇒ Object
- .build_gate_node(seq) ⇒ Object
- .build_patch(path) ⇒ Object
- .build_pitch_node(seq) ⇒ Object
- .make_stepwise(coordinates) ⇒ Object
- .remove_from_stack(stack, event) ⇒ Object
- .scale_time(time, min_time, max_time) ⇒ Object
- .scale_velocity(velocity) ⇒ Object
Class Method Details
.add_to_stack(stack, event) ⇒ Object
100 101 102 |
# File 'lib/midi_patch.rb', line 100 def self.add_to_stack(stack, event) stack << event end |
.build_gate_node(seq) ⇒ Object
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 |
# File 'lib/midi_patch.rb', line 65 def self.build_gate_node(seq) note_on_off_events = seq.first.select {|e| MIDI::NoteOn === e || MIDI::NoteOff === e} note_stack = [] times = note_on_off_events.map(&:time_from_start) min_time, max_time = [times.min, times.max].map(&:to_f) coordinates = note_on_off_events.map {|event| time = scale_time(event.time_from_start, min_time, max_time) case event when MIDI::NoteOn add_to_stack(note_stack, event) [time, scale_velocity(event.velocity)] when MIDI::NoteOff remove_from_stack(note_stack, event) if note_stack.empty? [time, 0.0] else [time, scale_velocity(note_stack[-1].velocity)] end end } stepwise_coordinates = make_stepwise(coordinates) SplineHelper.build_spline_node_from_coordinates(stepwise_coordinates) end |
.build_patch(path) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/midi_patch.rb', line 9 def self.build_patch(path) seq = MIDI::Sequence.new() File.open(path, 'rb') do |file| seq.read(file) end doc = Audulus.build_init_doc patch = doc['patch'] pitch_node = build_pitch_node(seq) Audulus.add_node(patch, pitch_node) Audulus.move_node(pitch_node, 0, 0) scaler_node = Audulus.build_expr_node('x*10-5') Audulus.add_node(patch, scaler_node) Audulus.move_node(scaler_node, 425, 55) Audulus.wire_output_to_input(patch, pitch_node, 0, scaler_node, 0) pitch_label = Audulus.build_text_node("pitch") Audulus.add_node(patch, pitch_label) Audulus.move_node(pitch_label, -50, 100) gate_node = build_gate_node(seq) Audulus.add_node(patch, gate_node) Audulus.move_node(gate_node, 0, 200) pitch_label = Audulus.build_text_node("gate") Audulus.add_node(patch, pitch_label) Audulus.move_node(pitch_label, -50, 300) _, file = File.(path).split("/")[-2..-1] basename = File.basename(file, ".mid") File.write("#{basename}.audulus", JSON.generate(doc)) end |
.build_pitch_node(seq) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/midi_patch.rb', line 45 def self.build_pitch_node(seq) note_on_events = seq.first.select {|e| MIDI::NoteOn === e} times = note_on_events.map(&:time_from_start) min_time, max_time = [times.min, times.max].map(&:to_f) scaled_times = times.map {|time| scale_time(time, min_time, max_time) } notes = note_on_events.map(&:note) scaled_notes = notes.map {|note| one_per_octave = (note.to_f - 69.0)/12.0 (one_per_octave+5)/10 # scale to be > 0 } coordinates = scaled_times.zip(scaled_notes) stepwise_coordinates = make_stepwise(coordinates) SplineHelper.build_spline_node_from_coordinates(stepwise_coordinates) end |
.make_stepwise(coordinates) ⇒ Object
108 109 110 111 112 113 114 115 116 117 |
# File 'lib/midi_patch.rb', line 108 def self.make_stepwise(coordinates) last_y = nil coordinates.flat_map {|x, y| result = [] result << [x-STEPWISE_X_DELTA, last_y] unless last_y.nil? result << [x, y] last_y = y result } end |
.remove_from_stack(stack, event) ⇒ Object
104 105 106 |
# File 'lib/midi_patch.rb', line 104 def self.remove_from_stack(stack, event) stack.delete_if {|e| e.note == event.note} end |
.scale_time(time, min_time, max_time) ⇒ Object
92 93 94 |
# File 'lib/midi_patch.rb', line 92 def self.scale_time(time, min_time, max_time) (time - min_time).to_f / (max_time - min_time).to_f end |
.scale_velocity(velocity) ⇒ Object
96 97 98 |
# File 'lib/midi_patch.rb', line 96 def self.scale_velocity(velocity) velocity.to_f / 127.0 end |