musa-dsl 0.23.8 → 0.23.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/lib/musa-dsl/core-ext/with.rb +4 -3
  3. data/lib/musa-dsl/datasets/gdv.rb +2 -2
  4. data/lib/musa-dsl/datasets/gdvd.rb +2 -1
  5. data/lib/musa-dsl/datasets/helper.rb +1 -1
  6. data/lib/musa-dsl/datasets/score/queriable.rb +43 -42
  7. data/lib/musa-dsl/datasets/score/render.rb +24 -20
  8. data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +120 -122
  9. data/lib/musa-dsl/generative/backboner.rb +2 -2
  10. data/lib/musa-dsl/generative/generative-grammar.rb +2 -0
  11. data/lib/musa-dsl/generative/markov.rb +1 -2
  12. data/lib/musa-dsl/generative/variatio.rb +6 -10
  13. data/lib/musa-dsl/logger/logger.rb +22 -22
  14. data/lib/musa-dsl/matrix/matrix.rb +3 -5
  15. data/lib/musa-dsl/midi/midi-recorder.rb +3 -4
  16. data/lib/musa-dsl/midi/midi-voices.rb +3 -3
  17. data/lib/musa-dsl/music/chords.rb +26 -29
  18. data/lib/musa-dsl/musicxml/builder/direction.rb +2 -2
  19. data/lib/musa-dsl/neumalang/neumalang.rb +25 -67
  20. data/lib/musa-dsl/neumas/array-to-neumas.rb +2 -2
  21. data/lib/musa-dsl/repl/repl.rb +1 -1
  22. data/lib/musa-dsl/sequencer/base-sequencer-implementation-every.rb +12 -11
  23. data/lib/musa-dsl/sequencer/base-sequencer-implementation-move.rb +53 -52
  24. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +2 -4
  25. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +43 -39
  26. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb +5 -7
  27. data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +6 -14
  28. data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +4 -3
  29. data/lib/musa-dsl/sequencer/base-sequencer.rb +5 -5
  30. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +11 -6
  31. data/lib/musa-dsl/series/array-to-serie.rb +5 -3
  32. data/lib/musa-dsl/series/base-series.rb +2 -2
  33. data/lib/musa-dsl/series/buffer-serie.rb +0 -5
  34. data/lib/musa-dsl/series/main-serie-constructors.rb +16 -6
  35. data/lib/musa-dsl/series/main-serie-operations.rb +2 -2
  36. data/lib/musa-dsl/series/quantizer-serie.rb +47 -51
  37. data/lib/musa-dsl/series/series-composer.rb +16 -6
  38. data/lib/musa-dsl/series/timed-serie.rb +49 -48
  39. data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +5 -7
  40. data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +1 -4
  41. data/lib/musa-dsl/transcription/from-gdv.rb +1 -3
  42. data/lib/musa-dsl/transcription/transcription.rb +2 -4
  43. data/lib/musa-dsl/transport/input-midi-clock.rb +7 -4
  44. data/lib/musa-dsl/transport/transport.rb +10 -12
  45. data/lib/musa-dsl.rb +1 -1
  46. data/musa-dsl.gemspec +2 -2
  47. 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}"
@@ -13,7 +13,7 @@ module Musa
13
13
  @block_source = nil
14
14
 
15
15
  if binder.receiver.respond_to?(:sequencer) &&
16
- binder.receiver.sequencer.respond_to?(:on_error)
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; module Sequencer
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 ||= SmartProcBinder.new block, on_rescue: proc { |e| _rescue_error(e) }
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
- duration_exceeded =
13
- (control._start_position + control.duration_value - interval) <= position if interval && control.duration_value
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
- unless control.stopped? || duration_exceeded || till_exceeded || condition_failed || interval.nil?
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; end
88
+ end
@@ -1,10 +1,11 @@
1
- using Musa::Extension::Hashify
2
- using Musa::Extension::Arrayfy
1
+ require_relative '../core-ext/arrayfy'
2
+ require_relative '../core-ext/inspect-nice'
3
3
 
4
- using Musa::Extension::InspectNice
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
- every[i] = Rational(effective_duration, steps + right_open_offset[i])
114
- else
115
- every[i] = nil
116
- end
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
- if array_mode
303
- binder.apply(effective_values, effective_next_values,
304
- control: control,
305
- duration: _durations(every_groups, effective_duration),
306
- quantized_duration: q_durations.dup,
307
- started_ago: _started_ago(last_position, position, process_indexes),
308
- position_jitter: position_jitters.dup,
309
- duration_jitter: duration_jitters.dup,
310
- right_open: right_open.dup)
311
- elsif hash_mode
312
- binder.apply(_hash_from_keys_and_values(hash_keys, effective_values),
313
- _hash_from_keys_and_values(hash_keys, effective_next_values),
314
- control: control,
315
- duration: _hash_from_keys_and_values(
316
- hash_keys,
317
- _durations(every_groups, effective_duration)),
318
- quantized_duration: _hash_from_keys_and_values(
319
- hash_keys,
320
- q_durations),
321
- started_ago: _hash_from_keys_and_values(
322
- hash_keys,
323
- _started_ago(last_position, position, process_indexes)),
324
- position_jitter: _hash_from_keys_and_values(
325
- hash_keys,
326
- position_jitters),
327
- duration_jitter: _hash_from_keys_and_values(
328
- hash_keys,
329
- duration_jitters),
330
- right_open: _hash_from_keys_and_values(hash_keys, right_open))
331
- else
332
- binder.apply(effective_values.first,
333
- effective_next_values.first,
334
- control: control,
335
- duration: _durations(every_groups, effective_duration).first,
336
- quantized_duration: q_durations.first,
337
- position_jitter: position_jitters.first,
338
- duration_jitter: duration_jitters.first,
339
- started_ago: nil,
340
- right_open: right_open.first)
341
- end
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; 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
- using Musa::Extension::Hashify
2
- using Musa::Extension::Arrayfy
1
+ require_relative '../core-ext/inspect-nice'
3
2
 
4
- using Musa::Extension::InspectNice
5
-
6
- module Musa; module Sequencer
3
+ module Musa::Sequencer
7
4
  class BaseSequencer
8
- private def _play_timed(timed_serie,
9
- control,
10
- &block)
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
- affected_components = component_ids.select { |_| !source_next_value[:value][_].nil? } if source_next_value
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
- if affected_components && affected_components.any?
46
- time = source_next_value[:time]
46
+ values = hash_mode ? {} : []
47
+ extra_attributes = extra_attribute_names.collect { |_| [_, hash_mode ? {} : []] }.to_h
48
+ started_ago = hash_mode ? {} : []
47
49
 
48
- values = hash_mode ? {} : []
49
- extra_attributes = extra_attribute_names.collect { |_| [_, hash_mode ? {} : []] }.to_h
50
- started_ago = hash_mode ? {} : []
50
+ affected_components.each do |component|
51
+ values[component] = source_next_value[:value][component]
51
52
 
52
- affected_components.each do |component|
53
- values[component] = source_next_value[:value][component]
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
- extra_attribute_names.each do |attribute_name|
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
- last_positions[component] = _quantize_position(time, warn: false)
60
- end
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
- component_ids.each do |component|
63
- if last_positions[component] && last_positions[component] != time
64
- sa = _quantize_position(time, warn: false) - last_positions[component]
65
- started_ago[component] = (sa == 0) ? nil : sa
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
- _numeric_at _quantize_position(start_position + time, warn: true), control do
70
- binder.call(values,
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; 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; module Sequencer
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
- on_rescue: proc { |e| _rescue_error(e) }),
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; 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
- using Musa::Extension::Arrayfy
5
- using Musa::Extension::DeepCopy
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
- SmartProcBinder.new block, on_rescue: proc { |e| _rescue_error(e) }
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; 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') { "_check_position: rounding "\
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