musa-dsl 0.23.8 → 0.23.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/musa-dsl/core-ext/with.rb +4 -3
- data/lib/musa-dsl/datasets/gdv.rb +2 -2
- data/lib/musa-dsl/datasets/gdvd.rb +2 -1
- data/lib/musa-dsl/datasets/helper.rb +1 -1
- data/lib/musa-dsl/datasets/score/queriable.rb +43 -42
- data/lib/musa-dsl/datasets/score/render.rb +24 -20
- data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +120 -122
- data/lib/musa-dsl/generative/backboner.rb +2 -2
- data/lib/musa-dsl/generative/generative-grammar.rb +2 -0
- data/lib/musa-dsl/generative/markov.rb +1 -2
- data/lib/musa-dsl/generative/variatio.rb +6 -10
- data/lib/musa-dsl/logger/logger.rb +22 -22
- data/lib/musa-dsl/matrix/matrix.rb +3 -5
- data/lib/musa-dsl/midi/midi-recorder.rb +3 -4
- data/lib/musa-dsl/midi/midi-voices.rb +3 -3
- data/lib/musa-dsl/music/chords.rb +26 -29
- data/lib/musa-dsl/musicxml/builder/direction.rb +2 -2
- data/lib/musa-dsl/neumalang/neumalang.rb +25 -67
- data/lib/musa-dsl/neumas/array-to-neumas.rb +2 -2
- data/lib/musa-dsl/repl/repl.rb +1 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-every.rb +12 -11
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-move.rb +53 -52
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +2 -4
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +43 -39
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb +5 -7
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +6 -14
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +4 -3
- data/lib/musa-dsl/sequencer/base-sequencer.rb +5 -5
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +11 -6
- data/lib/musa-dsl/series/array-to-serie.rb +5 -3
- data/lib/musa-dsl/series/base-series.rb +2 -2
- data/lib/musa-dsl/series/buffer-serie.rb +0 -5
- data/lib/musa-dsl/series/main-serie-constructors.rb +16 -6
- data/lib/musa-dsl/series/main-serie-operations.rb +2 -2
- data/lib/musa-dsl/series/quantizer-serie.rb +47 -51
- data/lib/musa-dsl/series/series-composer.rb +16 -6
- data/lib/musa-dsl/series/timed-serie.rb +49 -48
- data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +5 -7
- data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +1 -4
- data/lib/musa-dsl/transcription/from-gdv.rb +1 -3
- data/lib/musa-dsl/transcription/transcription.rb +2 -4
- data/lib/musa-dsl/transport/input-midi-clock.rb +7 -4
- data/lib/musa-dsl/transport/transport.rb +10 -12
- data/lib/musa-dsl.rb +1 -1
- data/musa-dsl.gemspec +2 -2
- metadata +2 -2
@@ -7,7 +7,7 @@ module Musa
|
|
7
7
|
refine Array do
|
8
8
|
def to_neumas
|
9
9
|
if length > 1
|
10
|
-
MERGE(*collect { |e| convert_to_neumas(e) })
|
10
|
+
Musa::Series::Constructors.MERGE(*collect { |e| convert_to_neumas(e) })
|
11
11
|
else
|
12
12
|
convert_to_neumas(first)
|
13
13
|
end
|
@@ -21,7 +21,7 @@ module Musa
|
|
21
21
|
def convert_to_neumas(e)
|
22
22
|
case e
|
23
23
|
when Musa::Neumas::Neuma::Serie then e
|
24
|
-
when Musa::Neumas::Neuma::Parallel then S(e).extend(Musa::Neumas::Neuma::Serie)
|
24
|
+
when Musa::Neumas::Neuma::Parallel then Musa::Series::Constructors.S(e).extend(Musa::Neumas::Neuma::Serie)
|
25
25
|
when String then e.to_neumas
|
26
26
|
else
|
27
27
|
raise ArgumentError, "Don't know how to convert to neumas #{e}"
|
data/lib/musa-dsl/repl/repl.rb
CHANGED
@@ -13,7 +13,7 @@ module Musa
|
|
13
13
|
@block_source = nil
|
14
14
|
|
15
15
|
if binder.receiver.respond_to?(:sequencer) &&
|
16
|
-
|
16
|
+
binder.receiver.sequencer.respond_to?(:on_error)
|
17
17
|
|
18
18
|
binder.receiver.sequencer.on_error do |e|
|
19
19
|
send_exception e, output: @connection
|
@@ -1,16 +1,18 @@
|
|
1
|
-
module Musa
|
1
|
+
module Musa::Sequencer
|
2
2
|
class BaseSequencer
|
3
3
|
private def _every(interval, control, block_procedure_binder: nil, &block)
|
4
4
|
block ||= proc {}
|
5
5
|
|
6
|
-
block_procedure_binder ||=
|
6
|
+
block_procedure_binder ||=
|
7
|
+
Musa::Extension::SmartProcBinder::SmartProcBinder.new block, on_rescue: proc { |e| _rescue_error(e) }
|
7
8
|
|
8
9
|
_numeric_at position, control do
|
9
10
|
control._start_position ||= position
|
10
11
|
control._execution_counter ||= 0
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
if interval && control.duration_value
|
14
|
+
duration_exceeded = (control._start_position + control.duration_value - interval) <= position
|
15
|
+
end
|
14
16
|
|
15
17
|
till_exceeded = control.till_value - interval <= position if interval && control.till_value
|
16
18
|
|
@@ -22,17 +24,16 @@ module Musa; module Sequencer
|
|
22
24
|
end
|
23
25
|
|
24
26
|
|
25
|
-
|
26
|
-
_numeric_at control._start_position + control._execution_counter * interval, control do
|
27
|
-
_every interval, control, block_procedure_binder: block_procedure_binder
|
28
|
-
end
|
29
|
-
|
30
|
-
else
|
27
|
+
if control.stopped? || duration_exceeded || till_exceeded || condition_failed || interval.nil?
|
31
28
|
control.do_on_stop.each(&:call)
|
32
29
|
|
33
30
|
control.do_after.each do |do_after|
|
34
31
|
_numeric_at position + (interval || 0) + do_after[:bars], control, &do_after[:block]
|
35
32
|
end
|
33
|
+
else
|
34
|
+
_numeric_at control._start_position + control._execution_counter * interval, control do
|
35
|
+
_every interval, control, block_procedure_binder: block_procedure_binder
|
36
|
+
end
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
@@ -84,4 +85,4 @@ module Musa; module Sequencer
|
|
84
85
|
|
85
86
|
private_constant :EveryControl
|
86
87
|
end
|
87
|
-
end
|
88
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../core-ext/arrayfy'
|
2
|
+
require_relative '../core-ext/inspect-nice'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
module Musa; module Sequencer
|
4
|
+
module Musa::Sequencer
|
7
5
|
class BaseSequencer
|
6
|
+
using Musa::Extension::Arrayfy
|
7
|
+
using Musa::Extension::InspectNice
|
8
|
+
|
8
9
|
private def _move(every: nil,
|
9
10
|
from:, to: nil,
|
10
11
|
step: nil,
|
@@ -109,11 +110,11 @@ module Musa; module Sequencer
|
|
109
110
|
steps = (to[i] - from[i]) / step[i]
|
110
111
|
|
111
112
|
# When to == from don't need to do any iteration with every
|
112
|
-
if steps + right_open_offset[i] > 0
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
113
|
+
every[i] = if steps + right_open_offset[i] > 0
|
114
|
+
Rational(effective_duration, steps + right_open_offset[i])
|
115
|
+
else
|
116
|
+
nil
|
117
|
+
end
|
117
118
|
|
118
119
|
elsif to[i] && !step[i] && !every[i]
|
119
120
|
|
@@ -166,7 +167,7 @@ module Musa; module Sequencer
|
|
166
167
|
#
|
167
168
|
# Prepare yield block, parameters to yield block and coincident moving interval groups
|
168
169
|
#
|
169
|
-
binder = SmartProcBinder.new(block)
|
170
|
+
binder = Musa::Extension::SmartProcBinder::SmartProcBinder.new(block)
|
170
171
|
|
171
172
|
every_groups = {}
|
172
173
|
group_counter = {}
|
@@ -299,46 +300,46 @@ module Musa; module Sequencer
|
|
299
300
|
# Adapt values to array/hash/value mode
|
300
301
|
#
|
301
302
|
value_parameters, key_parameters =
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
303
|
+
if array_mode
|
304
|
+
binder.apply(effective_values, effective_next_values,
|
305
|
+
control: control,
|
306
|
+
duration: _durations(every_groups, effective_duration),
|
307
|
+
quantized_duration: q_durations.dup,
|
308
|
+
started_ago: _started_ago(last_position, position, process_indexes),
|
309
|
+
position_jitter: position_jitters.dup,
|
310
|
+
duration_jitter: duration_jitters.dup,
|
311
|
+
right_open: right_open.dup)
|
312
|
+
elsif hash_mode
|
313
|
+
binder.apply(_hash_from_keys_and_values(hash_keys, effective_values),
|
314
|
+
_hash_from_keys_and_values(hash_keys, effective_next_values),
|
315
|
+
control: control,
|
316
|
+
duration: _hash_from_keys_and_values(
|
317
|
+
hash_keys,
|
318
|
+
_durations(every_groups, effective_duration)),
|
319
|
+
quantized_duration: _hash_from_keys_and_values(
|
320
|
+
hash_keys,
|
321
|
+
q_durations),
|
322
|
+
started_ago: _hash_from_keys_and_values(
|
323
|
+
hash_keys,
|
324
|
+
_started_ago(last_position, position, process_indexes)),
|
325
|
+
position_jitter: _hash_from_keys_and_values(
|
326
|
+
hash_keys,
|
327
|
+
position_jitters),
|
328
|
+
duration_jitter: _hash_from_keys_and_values(
|
329
|
+
hash_keys,
|
330
|
+
duration_jitters),
|
331
|
+
right_open: _hash_from_keys_and_values(hash_keys, right_open))
|
332
|
+
else
|
333
|
+
binder.apply(effective_values.first,
|
334
|
+
effective_next_values.first,
|
335
|
+
control: control,
|
336
|
+
duration: _durations(every_groups, effective_duration).first,
|
337
|
+
quantized_duration: q_durations.first,
|
338
|
+
position_jitter: position_jitters.first,
|
339
|
+
duration_jitter: duration_jitters.first,
|
340
|
+
started_ago: nil,
|
341
|
+
right_open: right_open.first)
|
342
|
+
end
|
342
343
|
|
343
344
|
#
|
344
345
|
# Do the REAL thing
|
@@ -436,4 +437,4 @@ module Musa; module Sequencer
|
|
436
437
|
|
437
438
|
private_constant :MoveControl
|
438
439
|
end
|
439
|
-
end
|
440
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
using Musa::Extension::DeepCopy
|
2
|
-
|
3
1
|
module Musa
|
4
2
|
module Sequencer
|
5
3
|
class BaseSequencer
|
@@ -270,7 +268,7 @@ module Musa
|
|
270
268
|
|
271
269
|
when Array
|
272
270
|
{ current_operation: :no_eval_play,
|
273
|
-
current_parameter: S(*element) }
|
271
|
+
current_parameter: Musa::Series::Constructors.S(*element) }
|
274
272
|
else
|
275
273
|
case element[:kind]
|
276
274
|
when :value
|
@@ -294,7 +292,7 @@ module Musa
|
|
294
292
|
|
295
293
|
if _value.is_a?(Array)
|
296
294
|
{ current_operation: :no_eval_play,
|
297
|
-
current_parameter: S(*_value) }
|
295
|
+
current_parameter: Musa::Series::Constructors.S(*_value) }
|
298
296
|
else
|
299
297
|
{ current_operation: :block,
|
300
298
|
current_parameter: _value,
|
@@ -1,13 +1,10 @@
|
|
1
|
-
|
2
|
-
using Musa::Extension::Arrayfy
|
1
|
+
require_relative '../core-ext/inspect-nice'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
module Musa; module Sequencer
|
3
|
+
module Musa::Sequencer
|
7
4
|
class BaseSequencer
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
using Musa::Extension::InspectNice
|
6
|
+
|
7
|
+
private def _play_timed(timed_serie, control, &block)
|
11
8
|
|
12
9
|
if first_value_sample = timed_serie.peek_next_value
|
13
10
|
debug "_play_timed: first_value_sample #{first_value_sample}"
|
@@ -25,7 +22,7 @@ module Musa; module Sequencer
|
|
25
22
|
last_positions = hash_mode ? {} : []
|
26
23
|
end
|
27
24
|
|
28
|
-
binder = SmartProcBinder.new(block)
|
25
|
+
binder = Musa::Extension::SmartProcBinder::SmartProcBinder.new(block)
|
29
26
|
|
30
27
|
_play_timed_step(hash_mode, component_ids, extra_attribute_names, timed_serie,
|
31
28
|
position, last_positions, binder, control)
|
@@ -40,45 +37,52 @@ module Musa; module Sequencer
|
|
40
37
|
|
41
38
|
source_next_value = timed_serie.next_value
|
42
39
|
|
43
|
-
|
40
|
+
if source_next_value
|
41
|
+
affected_components = component_ids.select { |_| !source_next_value[:value][_].nil? }
|
42
|
+
|
43
|
+
if affected_components&.any?
|
44
|
+
time = source_next_value[:time]
|
44
45
|
|
45
|
-
|
46
|
-
|
46
|
+
values = hash_mode ? {} : []
|
47
|
+
extra_attributes = extra_attribute_names.collect { |_| [_, hash_mode ? {} : []] }.to_h
|
48
|
+
started_ago = hash_mode ? {} : []
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
started_ago = hash_mode ? {} : []
|
50
|
+
affected_components.each do |component|
|
51
|
+
values[component] = source_next_value[:value][component]
|
51
52
|
|
52
|
-
|
53
|
-
|
53
|
+
extra_attribute_names.each do |attribute_name|
|
54
|
+
extra_attributes[attribute_name][component] = source_next_value[attribute_name][component]
|
55
|
+
end
|
54
56
|
|
55
|
-
|
56
|
-
extra_attributes[attribute_name][component] = source_next_value[attribute_name][component]
|
57
|
+
last_positions[component] = _quantize_position(time, warn: false)
|
57
58
|
end
|
58
59
|
|
59
|
-
|
60
|
-
|
60
|
+
component_ids.each do |component|
|
61
|
+
if last_positions[component] && last_positions[component] != time
|
62
|
+
sa = _quantize_position(time, warn: false) - last_positions[component]
|
63
|
+
started_ago[component] = (sa == 0) ? nil : sa
|
64
|
+
end
|
65
|
+
end
|
61
66
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
67
|
+
_numeric_at _quantize_position(start_position + time, warn: true), control do
|
68
|
+
binder.call(values,
|
69
|
+
**extra_attributes,
|
70
|
+
time: start_position + time,
|
71
|
+
started_ago: started_ago,
|
72
|
+
control: control)
|
73
|
+
|
74
|
+
_play_timed_step(hash_mode,
|
75
|
+
component_ids, extra_attribute_names,
|
76
|
+
timed_serie,
|
77
|
+
start_position,
|
78
|
+
last_positions,
|
79
|
+
binder, control)
|
66
80
|
end
|
67
81
|
end
|
82
|
+
else
|
68
83
|
|
69
|
-
|
70
|
-
|
71
|
-
**extra_attributes,
|
72
|
-
time: start_position + time,
|
73
|
-
started_ago: started_ago,
|
74
|
-
control: control)
|
75
|
-
|
76
|
-
_play_timed_step(hash_mode,
|
77
|
-
component_ids, extra_attribute_names,
|
78
|
-
timed_serie,
|
79
|
-
start_position,
|
80
|
-
last_positions,
|
81
|
-
binder, control)
|
84
|
+
control.do_after.each do |do_after|
|
85
|
+
_numeric_at position + do_after[:bars], control, &do_after[:block]
|
82
86
|
end
|
83
87
|
end
|
84
88
|
end
|
@@ -107,5 +111,5 @@ module Musa; module Sequencer
|
|
107
111
|
|
108
112
|
private_constant :PlayTimedControl
|
109
113
|
end
|
110
|
-
end
|
114
|
+
end
|
111
115
|
|
@@ -1,11 +1,9 @@
|
|
1
|
+
require_relative '../core-ext/inspect-nice'
|
1
2
|
require_relative 'base-sequencer-implementation-play-helper'
|
2
3
|
|
3
|
-
using Musa::Extension::Hashify
|
4
|
-
using Musa::Extension::Arrayfy
|
5
|
-
|
6
4
|
using Musa::Extension::InspectNice
|
7
5
|
|
8
|
-
module Musa
|
6
|
+
module Musa::Sequencer
|
9
7
|
class BaseSequencer
|
10
8
|
private def _play(serie,
|
11
9
|
control,
|
@@ -20,8 +18,8 @@ module Musa; module Sequencer
|
|
20
18
|
|
21
19
|
__play_eval ||= PlayEval.create \
|
22
20
|
mode,
|
23
|
-
SmartProcBinder.new(block,
|
24
|
-
|
21
|
+
Musa::Extension::SmartProcBinder::SmartProcBinder.new(block,
|
22
|
+
on_rescue: proc { |e| _rescue_error(e) }),
|
25
23
|
decoder,
|
26
24
|
neumalang_context
|
27
25
|
|
@@ -175,4 +173,4 @@ module Musa; module Sequencer
|
|
175
173
|
|
176
174
|
private_constant :PlayControl
|
177
175
|
end
|
178
|
-
end
|
176
|
+
end
|
@@ -1,16 +1,10 @@
|
|
1
|
-
require_relative '../core-ext/arrayfy'
|
2
1
|
require_relative '../core-ext/smart-proc-binder'
|
2
|
+
require_relative '../core-ext/inspect-nice'
|
3
3
|
|
4
|
-
|
5
|
-
using Musa::Extension::
|
4
|
+
module Musa::Sequencer
|
5
|
+
using Musa::Extension::InspectNice
|
6
6
|
|
7
|
-
module Musa; module Sequencer
|
8
7
|
class BaseSequencer
|
9
|
-
include Musa::Extension::SmartProcBinder
|
10
|
-
include Musa::Extension::DeepCopy
|
11
|
-
|
12
|
-
using Musa::Extension::InspectNice
|
13
|
-
|
14
8
|
private def _tick(position_to_run)
|
15
9
|
@before_tick.each { |block| block.call position_to_run }
|
16
10
|
queue = @timeslots[position_to_run]
|
@@ -72,7 +66,7 @@ module Musa; module Sequencer
|
|
72
66
|
at_position = _quantize_position(at_position)
|
73
67
|
|
74
68
|
block_key_parameters_binder =
|
75
|
-
|
69
|
+
Musa::Extension::SmartProcBinder::SmartProcBinder.new block, on_rescue: proc { |e| _rescue_error(e) }
|
76
70
|
|
77
71
|
key_parameters = {}
|
78
72
|
key_parameters[:control] = control if block_key_parameters_binder.key?(:control)
|
@@ -133,8 +127,6 @@ module Musa; module Sequencer
|
|
133
127
|
end
|
134
128
|
|
135
129
|
class EventHandler
|
136
|
-
include Musa::Extension::SmartProcBinder
|
137
|
-
|
138
130
|
attr_accessor :continue_parameters
|
139
131
|
|
140
132
|
@@counter = 0
|
@@ -174,7 +166,7 @@ module Musa; module Sequencer
|
|
174
166
|
@handlers[event] ||= {}
|
175
167
|
|
176
168
|
# TODO: add on_rescue: proc { |e| _rescue_block_error(e) } [this method is on Sequencer, not in EventHandler]
|
177
|
-
@handlers[event][name] = { block: SmartProcBinder.new(block), only_once: only_once }
|
169
|
+
@handlers[event][name] = { block: Musa::Extension::SmartProcBinder::SmartProcBinder.new(block), only_once: only_once }
|
178
170
|
end
|
179
171
|
|
180
172
|
def launch(event, *value_parameters, **key_parameters)
|
@@ -214,4 +206,4 @@ module Musa; module Sequencer
|
|
214
206
|
|
215
207
|
private_constant :EventHandler
|
216
208
|
end
|
217
|
-
end
|
209
|
+
end
|
@@ -2,7 +2,6 @@ module Musa
|
|
2
2
|
module Sequencer
|
3
3
|
class BaseSequencer
|
4
4
|
module TickBasedTiming
|
5
|
-
|
6
5
|
using Musa::Extension::InspectNice
|
7
6
|
|
8
7
|
attr_reader :position, :ticks_per_bar, :tick_duration
|
@@ -49,9 +48,11 @@ module Musa
|
|
49
48
|
position = ticks_position.round * @tick_duration
|
50
49
|
|
51
50
|
if warn
|
52
|
-
@logger.warn('BaseSequencer')
|
51
|
+
@logger.warn('BaseSequencer') do
|
52
|
+
'_check_position: rounding ' \
|
53
53
|
"position #{original_position.inspect} (#{original_position.to_f.round(5)}) "\
|
54
|
-
"to tick precision: #{position.inspect} (#{position.to_f.round(5)})"
|
54
|
+
"to tick precision: #{position.inspect} (#{position.to_f.round(5)})"
|
55
|
+
end
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|