musa-dsl 0.22.0 → 0.22.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 45dc15743b61b3ee68c878d59509dc86c7703198fbad479c60f299003ffdbb49
4
- data.tar.gz: f598a8fccc84f4941652cf9f6bc186419e466c0d75cd772ff128d462b5af400a
3
+ metadata.gz: 77d95cd844364ae8dce08779712a34fdb0e8e349336717ffc7e49580c293b647
4
+ data.tar.gz: 16b7d33203bdd273acd5f235189025fa15797e7d09a1bee498151d521c0109d3
5
5
  SHA512:
6
- metadata.gz: 65296b4e141478755d23425f346b80ddfe9f72ffc6bf89fd69f032a86b5f600171e5da53bc07edada254a3f790dfc5375ec1872e710eca106ab124f8f0779855
7
- data.tar.gz: 86c4ad977fc506e3a21c427a5bd2ea381c5d49d7d28447cdc4154ee576a07d43baf5dbb4d14666cb4d1bd9f63a0ab311f67b7508143e651821105c9eae3bdd45
6
+ metadata.gz: bad2f753e7c62c93276dd5a019f57ff8eb2b5c23c38a20989e4dcc5f7a3a4365dfdd1532750da0cbb8dbe0a08c459fb02f8f62b0fd1246f1a5f8da8c755c49c5
7
+ data.tar.gz: a7a7e3d32b7a723c206ec098585cbbad76d2ef377ad55007a722537ef0b1070a9a43a4a18740758db82167193b55e1b524e7bb7f3bdf5251e7beba1c2effd6d5
@@ -1,5 +1,5 @@
1
1
  module Musa
2
- VERSION = '0.22.0'
2
+ VERSION = '0.22.5'
3
3
  end
4
4
 
5
5
  require_relative 'musa-dsl/core-ext'
@@ -22,8 +22,10 @@ module Musa::Datasets
22
22
  end
23
23
  end
24
24
 
25
- def to_timed_serie(time_start = nil, base_duration: nil)
25
+ def to_timed_serie(time_start: nil, time_start_component: nil, base_duration: nil)
26
26
  time_start ||= 0r
27
+ time_start += self.first[time_start_component] if time_start_component
28
+
27
29
  base_duration ||= 1/4r # TODO review incoherence between neumalang 1/4r base duration for quarter notes and general 1r size of bar
28
30
 
29
31
  # TODO if instead of using clone (needed because of p.shift) we use index counter the P elements would be evaluated on the last moment
@@ -22,8 +22,8 @@ module Musa
22
22
  indexes
23
23
  end
24
24
 
25
- def to_p(time_dimension, keep_time: nil)
26
- condensed_matrices.collect { |m| m.to_p(time_dimension, keep_time: keep_time) }
25
+ def to_p(time_dimension:, keep_time: nil)
26
+ condensed_matrices.collect { |m| m.to_p(time_dimension: time_dimension, keep_time: keep_time) }
27
27
  end
28
28
 
29
29
  def condensed_matrices
@@ -69,14 +69,14 @@ module Musa
69
69
  refine ::Matrix do
70
70
  include Musa::Datasets
71
71
 
72
- def to_p(time_dimension, keep_time: nil)
72
+ def to_p(time_dimension:, keep_time: nil)
73
73
  decompose(self.to_a, time_dimension).collect do |points|
74
74
  line = []
75
75
 
76
76
  start_point = points[0]
77
77
  start_time = start_point[time_dimension]
78
78
 
79
- line << start_point.tap { |_| _.delete_at(time_dimension) unless keep_time; _ }.extend(Datasets::V)
79
+ line << start_point.clone.tap { |_| _.delete_at(time_dimension) unless keep_time; _ }.extend(Datasets::V)
80
80
 
81
81
  (1..points.size-1).each do |i|
82
82
  end_point = points[i]
@@ -84,7 +84,7 @@ module Musa
84
84
  end_time = end_point[time_dimension]
85
85
 
86
86
  line << end_time - start_time
87
- line << end_point.tap { |_| _.delete_at(time_dimension) unless keep_time; _ }.extend(Datasets::V)
87
+ line << end_point.clone.tap { |_| _.delete_at(time_dimension) unless keep_time; _ }.extend(Datasets::V)
88
88
 
89
89
  start_time = end_time
90
90
  end
@@ -107,8 +107,9 @@ module Musa
107
107
 
108
108
  x_dim_values_indexes.keys.sort.each do |value|
109
109
  x_dim_values_indexes[value].each do |index|
110
+ #
110
111
  # hacia un lado
111
-
112
+ #
112
113
  unless used_indexes.include?(index)
113
114
  i = index
114
115
  xx = array[i][time_dimension]
@@ -125,8 +126,9 @@ module Musa
125
126
 
126
127
  directional_segments << a if a.size > 1
127
128
 
129
+ #
128
130
  # y hacia el otro
129
-
131
+ #
130
132
  i = index
131
133
  xx = array[i][time_dimension]
132
134
 
@@ -324,8 +324,13 @@ module Musa
324
324
  run_operation eval_use_variable(element[:use_variable])
325
325
 
326
326
  when :event
327
- value_parameters = element[:value_parameters] ? element[:value_parameters].collect { |e| subcontext.eval_element(e) } : []
328
- key_parameters = element[:key_parameters] ? element[:key_parameters].collect { |k, e| [k, subcontext.eval_element(e)] }.to_h : {}
327
+ value_parameters = element[:value_parameters] ?
328
+ element[:value_parameters].collect { |e| subcontext.eval_element(e) } :
329
+ []
330
+
331
+ key_parameters = element[:key_parameters] ?
332
+ element[:key_parameters].collect { |k, e| [k, subcontext.eval_element(e)] }.to_h :
333
+ {}
329
334
 
330
335
  { current_operation: :event,
331
336
  current_event: element[:event],
@@ -7,98 +7,59 @@ module Musa; module Sequencer
7
7
  class BaseSequencer
8
8
  private def _play_timed(timed_serie,
9
9
  control,
10
- reference: nil,
11
- step: nil,
12
- right_open: nil,
13
10
  &block)
14
11
 
15
- reference ||= 0r
16
- step ||= 1r
17
-
18
12
  if first_value_sample = timed_serie.peek_next_value
19
-
20
13
  debug "_play_timed: first_value_sample #{first_value_sample}"
21
14
 
22
15
  hash_mode = first_value_sample[:value].is_a?(Hash)
23
16
 
24
17
  if hash_mode
25
- components = first_value_sample[:value].keys
26
-
27
- reference = reference.hashify(keys: components)
28
- step = step.hashify(keys: components)
29
- right_open = right_open.hashify(keys:components)
18
+ component_ids = first_value_sample[:value].keys
30
19
  else
31
20
  size = first_value_sample[:value].size
32
- components = (0 .. size-1).to_a
33
-
34
- reference = reference.arrayfy(size: size)
35
- step = step.arrayfy(size: size)
36
- right_open = right_open.arrayfy(size: size)
37
- end
38
-
39
- split = timed_serie.flatten_timed.split
40
- quantized_series = hash_mode ? {} : []
41
-
42
- components.each do |component|
43
- quantized_series[component] =
44
- QUANTIZE(split[component],
45
- reference: reference[component],
46
- step: step[component],
47
- right_open: right_open[component],
48
- stops: true).instance
21
+ component_ids = (0 .. size-1).to_a
49
22
  end
23
+ extra_attribute_names = Set[*(first_value_sample.keys - [:time, :value])]
50
24
 
51
25
  last_positions = hash_mode ? {} : []
52
26
  end
53
27
 
54
28
  binder = SmartProcBinder.new(block)
55
29
 
56
- _play_timed_step(hash_mode, components, quantized_series, position, last_positions, binder, control)
30
+ _play_timed_step(hash_mode, component_ids, extra_attribute_names, timed_serie,
31
+ position, last_positions, binder, control)
57
32
  end
58
33
 
59
-
60
- private def _play_timed_step(hash_mode, components, quantized_series, start_position, last_positions,
34
+ private def _play_timed_step(hash_mode,
35
+ component_ids, extra_attribute_names,
36
+ timed_serie,
37
+ start_position,
38
+ last_positions,
61
39
  binder, control)
62
40
 
63
- affected_components_by_time = {}
64
-
65
- components.each do |component|
66
- if v = quantized_series[component].peek_next_value
41
+ source_next_value = timed_serie.next_value
67
42
 
68
- debug "_play_timed_step: quantized_series[#{component}].peek_next_value #{v}"
69
- time = v[:time]
70
-
71
- affected_components_by_time[time] ||= []
72
- affected_components_by_time[time] << component
73
- end
74
- end
43
+ affected_components = component_ids.select { |_| !source_next_value[:value][_].nil? } if source_next_value
75
44
 
76
- if affected_components_by_time.any?
77
- time = affected_components_by_time.keys.sort.first
45
+ if affected_components && affected_components.any?
46
+ time = source_next_value[:time]
78
47
 
79
48
  values = hash_mode ? {} : []
80
- next_values = hash_mode ? {} : []
81
- durations = hash_mode ? {} : []
82
- q_durations = hash_mode ? {} : []
49
+ extra_attributes = extra_attribute_names.collect { |_| [_, hash_mode ? {} : []] }.to_h
83
50
  started_ago = hash_mode ? {} : []
84
51
 
85
- affected_components_by_time[time].each do |component|
86
- value = quantized_series[component].next_value
87
-
88
- values[component] = value[:value]
89
- durations[component] = value[:duration]
90
-
91
- q_durations[component] =
92
- _quantize_position(time + durations[component], warn: false) -
93
- _quantize_position(time, warn: false)
52
+ affected_components.each do |component|
53
+ values[component] = source_next_value[:value][component]
94
54
 
95
- nv = quantized_series[component].peek_next_value
96
- next_values[component] = (nv && nv[:value] != values[component]) ? nv[:value] : nil
55
+ extra_attribute_names.each do |attribute_name|
56
+ extra_attributes[attribute_name][component] = source_next_value[attribute_name][component]
57
+ end
97
58
 
98
59
  last_positions[component] = _quantize_position(time, warn: false)
99
60
  end
100
61
 
101
- components.each do |component|
62
+ component_ids.each do |component|
102
63
  if last_positions[component] && last_positions[component] != time
103
64
  sa = _quantize_position(time, warn: false) - last_positions[component]
104
65
  started_ago[component] = (sa == 0) ? nil : sa
@@ -106,82 +67,21 @@ module Musa; module Sequencer
106
67
  end
107
68
 
108
69
  _numeric_at start_position + _quantize_position(time, warn: false), control do
109
- debug "_play_timed_step: before binder.call: durations #{durations} q_durations #{q_durations}"
110
- binder.call(values, next_values,
111
- duration: durations,
112
- quantized_duration: q_durations,
70
+ binder.call(values,
71
+ **extra_attributes,
113
72
  started_ago: started_ago,
114
73
  control: control)
115
74
 
116
- _play_timed_step(hash_mode, components, quantized_series, start_position, last_positions,
75
+ _play_timed_step(hash_mode,
76
+ component_ids, extra_attribute_names,
77
+ timed_serie,
78
+ start_position,
79
+ last_positions,
117
80
  binder, control)
118
81
  end
119
82
  end
120
83
  end
121
84
 
122
- # TODO implement this alternative play method as another mode
123
- # Este es un modo muy interesante pero que implica un procesamiento diferente en el yield_block que no me
124
- # sirve para el código de samples/multidim_sample, puesto que en este el next_values es literal,
125
- # mientras que samples/multidim_sample necesita que el next_value sea nil si el valor no cambia durante el periodo.
126
- #
127
- private def _play_timed_step_b(hash_mode, components, quantized_series, start_position, last_positions,
128
- binder, control)
129
-
130
- affected_components_by_time = {}
131
-
132
- components.each do |component|
133
- if v = quantized_series[component].peek_next_value
134
- time = v[:time]
135
-
136
- affected_components_by_time[time] ||= []
137
- affected_components_by_time[time] << component
138
- end
139
- end
140
-
141
- if !affected_components_by_time.empty?
142
- time = affected_components_by_time.keys.sort.first
143
-
144
- values = hash_mode ? {} : []
145
- next_values = hash_mode ? {} : []
146
- durations = hash_mode ? {} : []
147
- q_durations = hash_mode ? {} : []
148
- started_ago = hash_mode ? {} : []
149
-
150
- affected_components_by_time[time].each do |component|
151
- value = quantized_series[component].next_value
152
-
153
- values[component] = value[:value]
154
- durations[component] = value[:duration]
155
-
156
- q_durations[component] =
157
- _quantize_position(time + durations[component], warn: false) -
158
- _quantize_position(time, warn: false)
159
-
160
- last_positions[component] = _quantize_position(time, warn: false)
161
- end
162
-
163
- components.each do |component|
164
- nv = quantized_series[component].peek_next_value
165
- next_values[component] = nv[:value] if nv
166
-
167
- if last_positions[component] && last_positions[component] != time
168
- started_ago[component] = _quantize_position(time, warn: false) - last_positions[component]
169
- end
170
- end
171
-
172
- _numeric_at start_position + _quantize_position(time, warn: false), control do
173
- binder.call(values, next_values,
174
- duration: durations,
175
- quantized_duration: q_durations,
176
- started_ago: started_ago,
177
- control: control)
178
-
179
- _play_timed_step_b(hash_mode, components, quantized_series, start_position, last_positions,
180
- binder, control)
181
- end
182
- end
183
- end
184
-
185
85
  class PlayTimedControl < EventHandler
186
86
  attr_reader :do_on_stop, :do_after
187
87
 
@@ -63,21 +63,16 @@ module Musa; module Sequencer
63
63
  nil
64
64
  end
65
65
 
66
- private def _numeric_at(at_position, control, with: nil, debug: nil, &block)
66
+ private def _numeric_at(at_position, control, debug: nil, &block)
67
67
  raise ArgumentError, "'at_position' parameter cannot be nil" if at_position.nil?
68
68
  raise ArgumentError, 'Yield block is mandatory' unless block
69
69
 
70
70
  at_position = _quantize_position(at_position)
71
71
 
72
- value_parameters = []
73
- value_parameters << with if !with.nil? && !with.is_a?(Hash)
74
-
75
72
  block_key_parameters_binder =
76
73
  SmartProcBinder.new block, on_rescue: proc { |e| _rescue_error(e) }
77
74
 
78
75
  key_parameters = {}
79
- key_parameters.merge! block_key_parameters_binder._apply(nil, with).last if with.is_a?(Hash)
80
-
81
76
  key_parameters[:control] = control if block_key_parameters_binder.key?(:control)
82
77
 
83
78
  if at_position == @position
@@ -85,7 +80,7 @@ module Musa; module Sequencer
85
80
 
86
81
  begin
87
82
  locked = @tick_mutex.try_lock
88
- block_key_parameters_binder._call(value_parameters, key_parameters)
83
+ block_key_parameters_binder._call(nil, key_parameters)
89
84
  ensure
90
85
  @tick_mutex.unlock if locked
91
86
  end
@@ -100,8 +95,8 @@ module Musa; module Sequencer
100
95
  end
101
96
  end
102
97
 
103
- @timeslots[at_position] << { parent_control: control, block: block_key_parameters_binder,
104
- value_parameters: value_parameters,
98
+ @timeslots[at_position] << { parent_control: control,
99
+ block: block_key_parameters_binder,
105
100
  key_parameters: key_parameters }
106
101
  else
107
102
  @logger.warn('BaseSequencer') { "._numeric_at: ignoring past 'at' command for #{at_position}" }
@@ -110,20 +105,14 @@ module Musa; module Sequencer
110
105
  nil
111
106
  end
112
107
 
113
- private def _serie_at(bar_position_serie, control, with: nil, debug: nil, &block)
114
- bar_position = bar_position_serie.next_value
115
-
116
- with_value = if with.respond_to? :next_value
117
- with.next_value
118
- else
119
- with
120
- end
108
+ private def _serie_at(position_or_serie, control, debug: nil, &block)
109
+ bar_position = position_or_serie.next_value
121
110
 
122
111
  if bar_position
123
- _numeric_at bar_position, control, with: with_value, debug: debug, &block
112
+ _numeric_at bar_position, control, debug: debug, &block
124
113
 
125
114
  _numeric_at bar_position, control, debug: false do
126
- _serie_at bar_position_serie, control, with: with, debug: debug, &block
115
+ _serie_at position_or_serie, control, debug: debug, &block
127
116
  end
128
117
  else
129
118
  # serie finalizada
@@ -224,8 +213,3 @@ module Musa; module Sequencer
224
213
  private_constant :EventHandler
225
214
  end
226
215
  end; end
227
-
228
- require_relative 'base-sequencer-implementation-every'
229
- require_relative 'base-sequencer-implementation-move'
230
- require_relative 'base-sequencer-implementation-play'
231
- require_relative 'base-sequencer-implementation-play-timed'
@@ -27,9 +27,7 @@ module Musa
27
27
  _release_public_ticks
28
28
  end
29
29
 
30
- private
31
-
32
- def _init_timing
30
+ private def _init_timing
33
31
  @ticks_per_bar = Rational(beats_per_bar * ticks_per_beat)
34
32
  @tick_duration = Rational(1, @ticks_per_bar)
35
33
 
@@ -37,11 +35,11 @@ module Musa
37
35
  @hold_ticks = 0
38
36
  end
39
37
 
40
- def _reset_timing
38
+ private def _reset_timing
41
39
  @position = @position_mutex.synchronize { 1r - @tick_duration }
42
40
  end
43
41
 
44
- def _quantize_position(position, warn: true)
42
+ private def _quantize_position(position, warn: true)
45
43
  ticks_position = position / @tick_duration
46
44
 
47
45
  if ticks_position.round != ticks_position
@@ -58,11 +56,11 @@ module Musa
58
56
  position
59
57
  end
60
58
 
61
- def _hold_public_ticks
59
+ private def _hold_public_ticks
62
60
  @hold_public_ticks = true
63
61
  end
64
62
 
65
- def _release_public_ticks
63
+ private def _release_public_ticks
66
64
  @hold_ticks.times { _tick(@position_mutex.synchronize { @position += @tick_duration }) }
67
65
  @hold_ticks = 0
68
66
  @hold_public_ticks = false
@@ -53,16 +53,14 @@ module Musa
53
53
  @on_fast_forward.each { |block| block.call(false) }
54
54
  end
55
55
 
56
- private
57
-
58
- def _init_timing
56
+ private def _init_timing
59
57
  end
60
58
 
61
- def _reset_timing
59
+ private def _reset_timing
62
60
  @position = nil
63
61
  end
64
62
 
65
- def _quantize_position(position, warn: false)
63
+ private def _quantize_position(position, warn: false)
66
64
  position
67
65
  end
68
66
  end