musa-dsl 0.22.0 → 0.22.5

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.
@@ -30,6 +30,7 @@ module Musa
30
30
  else
31
31
  @logger = Musa::Logger::Logger.new(sequencer: self, position_format: log_position_format)
32
32
 
33
+ @logger.fatal!
33
34
  @logger.error! if do_error_log || do_error_log.nil?
34
35
  @logger.debug! if do_log
35
36
  end
@@ -82,6 +83,11 @@ module Musa
82
83
  @timeslots.empty?
83
84
  end
84
85
 
86
+ def quantize_position(position, warn: nil)
87
+ warn ||= false
88
+ _quantize_position(position, warn: warn)
89
+ end
90
+
85
91
  def run
86
92
  tick until empty?
87
93
  end
@@ -114,22 +120,19 @@ module Musa
114
120
  @event_handlers.last.launch event, *value_parameters, **key_parameters
115
121
  end
116
122
 
117
- def wait(bars_delay, with: nil, debug: nil, &block)
123
+ def wait(bars_delay, debug: nil, &block)
118
124
  debug ||= false
119
125
 
120
126
  control = EventHandler.new @event_handlers.last
121
127
  @event_handlers.push control
122
128
 
123
129
  if bars_delay.is_a? Numeric
124
- _numeric_at position + bars_delay.rationalize, control, with: with, debug: debug, &block
130
+ _numeric_at position + bars_delay.rationalize, control, debug: debug, &block
125
131
  else
126
132
  bars_delay = Series::S(*bars_delay) if bars_delay.is_a?(Array)
127
133
  bars_delay = bars_delay.instance if bars_delay
128
134
 
129
- with = Series::S(*with).repeat if with.is_a?(Array)
130
- with = with.instance if with
131
-
132
- _serie_at bars_delay.eval { |delay| position + delay }, control, with: with, debug: debug, &block
135
+ _serie_at bars_delay.eval { |delay| position + delay }, control, debug: debug, &block
133
136
  end
134
137
 
135
138
  @event_handlers.pop
@@ -137,11 +140,11 @@ module Musa
137
140
  control
138
141
  end
139
142
 
140
- def now(with: nil, &block)
143
+ def now(&block)
141
144
  control = EventHandler.new @event_handlers.last
142
145
  @event_handlers.push control
143
146
 
144
- _numeric_at position, control, with: with, &block
147
+ _numeric_at position, control, &block
145
148
 
146
149
  @event_handlers.pop
147
150
 
@@ -154,22 +157,19 @@ module Musa
154
157
  nil
155
158
  end
156
159
 
157
- def at(bar_position, with: nil, debug: nil, &block)
160
+ def at(bar_position, debug: nil, &block)
158
161
  debug ||= false
159
162
 
160
163
  control = EventHandler.new @event_handlers.last
161
164
  @event_handlers.push control
162
165
 
163
166
  if bar_position.is_a? Numeric
164
- _numeric_at bar_position.rationalize, control, with: with, debug: debug, &block
167
+ _numeric_at bar_position.rationalize, control, debug: debug, &block
165
168
  else
166
169
  bar_position = Series::S(*bar_position) if bar_position.is_a? Array
167
170
  bar_position = bar_position.instance if bar_position
168
171
 
169
- with = Series::S(*with).repeat if with.is_a? Array
170
- with = with.instance if with
171
-
172
- _serie_at bar_position, control, with: with, debug: debug, &block
172
+ _serie_at bar_position, control, debug: debug, &block
173
173
  end
174
174
 
175
175
  @event_handlers.pop
@@ -215,9 +215,6 @@ module Musa
215
215
  end
216
216
 
217
217
  def play_timed(timed_serie,
218
- reference: nil,
219
- step: nil,
220
- right_open: nil,
221
218
  on_stop: nil,
222
219
  after_bars: nil, after: nil,
223
220
  &block)
@@ -233,12 +230,7 @@ module Musa
233
230
 
234
231
  @event_handlers.push control
235
232
 
236
- _play_timed(timed_serie.instance,
237
- control,
238
- reference: reference,
239
- step: step,
240
- right_open: right_open,
241
- &block)
233
+ _play_timed(timed_serie.instance, control, &block)
242
234
 
243
235
  @event_handlers.pop
244
236
 
@@ -17,13 +17,14 @@ module Musa
17
17
  :position=,
18
18
  :event_handler
19
19
 
20
- def_delegators :@context, :position, :logger, :debug
21
- def_delegators :@context, :with, :now, :at, :wait, :play, :every, :move
20
+ def_delegators :@context, :position, :quantize_position, :logger, :debug
21
+ def_delegators :@context, :with, :now, :at, :wait, :play, :play_timed, :every, :move
22
22
  def_delegators :@context, :everying, :playing, :moving
23
23
  def_delegators :@context, :launch, :on
24
24
  def_delegators :@context, :run
25
25
 
26
- def initialize(beats_per_bar, ticks_per_beat,
26
+ def initialize(beats_per_bar = nil,
27
+ ticks_per_beat = nil,
27
28
  sequencer: nil,
28
29
  logger: nil,
29
30
  do_log: nil, do_error_log: nil, log_position_format: nil,
@@ -50,7 +51,9 @@ module Musa
50
51
 
51
52
  def_delegators :@sequencer,
52
53
  :launch, :on,
53
- :position, :size, :everying, :playing, :moving,
54
+ :position, :quantize_position,
55
+ :size,
56
+ :everying, :playing, :moving,
54
57
  :ticks_per_bar, :logger, :debug, :inspect,
55
58
  :run
56
59
 
@@ -1,3 +1,10 @@
1
- require_relative 'base-sequencer-public'
1
+ require_relative 'base-sequencer'
2
+
2
3
  require_relative 'base-sequencer-implementation'
4
+
5
+ require_relative 'base-sequencer-implementation-every'
6
+ require_relative 'base-sequencer-implementation-move'
7
+ require_relative 'base-sequencer-implementation-play'
8
+ require_relative 'base-sequencer-implementation-play-timed'
9
+
3
10
  require_relative 'sequencer-dsl'
@@ -30,7 +30,7 @@ module Musa
30
30
  if @is_instance
31
31
  self
32
32
  else
33
- clone(freeze: false).tap(&:_instance!).mark_as_instance!(self)
33
+ clone(freeze: false).tap(&:_instance!).mark_as_instance!(self).tap(&:restart)
34
34
  end
35
35
  end
36
36
 
@@ -40,7 +40,7 @@ module Musa
40
40
  # handle prototyping/instancing automatically.
41
41
  # If there is a @sources attribute with the eventual several sources, SeriePrototyping will handle them by
42
42
  # default.
43
- # If needed the subclasses can override this behaviour to accomodate to real subclass specificities.
43
+ # If needed the subclasses can override this behaviour to accommodate to real subclass specificities.
44
44
  #
45
45
  protected def _prototype!
46
46
  @source = @source.prototype if @source
@@ -6,6 +6,8 @@ module Musa
6
6
  end
7
7
 
8
8
  class Splitter
9
+ include Enumerable
10
+
9
11
  def initialize(proxy)
10
12
  @proxy = proxy
11
13
  @series = {}
@@ -19,6 +21,46 @@ module Musa
19
21
  end
20
22
  end
21
23
 
24
+ def each
25
+ if block_given?
26
+ if @proxy.hash_mode?
27
+ @proxy.components.each do |key|
28
+ yield [key, self[key]]
29
+ end
30
+ elsif @proxy.array_mode?
31
+ @proxy.components.each do |index|
32
+ yield self[index]
33
+ end
34
+ else
35
+ # do nothing
36
+ end
37
+ else
38
+ if @proxy.hash_mode?
39
+ @proxy.components.collect { |key| [key, self[key]] }.each
40
+ elsif @proxy.array_mode?
41
+ @proxy.components.collect { |index| self[index] }.each
42
+ else
43
+ [].each
44
+ end
45
+ end
46
+ end
47
+
48
+ def to_hash
49
+ if @proxy.hash_mode?
50
+ @proxy.components.collect { |key| [key, self[key]] }.to_h
51
+ else
52
+ raise RuntimeError, 'Splitter is not based on Hash: can\'t convert to Hash'
53
+ end
54
+ end
55
+
56
+ def to_array
57
+ if @proxy.array_mode?
58
+ [].tap { |_| @proxy.components.each { |i| _[i] = self[i] } }
59
+ else
60
+ raise RuntimeError, 'Splitter is not based on Array: can\'t convert to Array'
61
+ end
62
+ end
63
+
22
64
  class BufferedProxy
23
65
  include SeriePrototyping
24
66
 
@@ -29,6 +71,11 @@ module Musa
29
71
  mark_regarding! @source
30
72
  end
31
73
 
74
+ attr_reader :components
75
+
76
+ def hash_mode?; @hash_mode; end
77
+ def array_mode?; @array_mode; end
78
+
32
79
  protected def _instance!
33
80
  super
34
81
  restart
@@ -36,22 +83,39 @@ module Musa
36
83
 
37
84
  def restart(restart_source: true)
38
85
  @source.restart if restart_source
39
- @values = nil
86
+
87
+ source = @source.instance
88
+ sample = source.current_value || source.peek_next_value
89
+
90
+ case sample
91
+ when Array
92
+ @components = (0..sample.size-1).to_a
93
+ @values = []
94
+ @array_mode = true
95
+ @hash_mode = false
96
+ when Hash
97
+ @components = sample.keys.clone
98
+ @values = {}
99
+ @array_mode = false
100
+ @hash_mode = true
101
+ else
102
+ @components = []
103
+ @values = nil
104
+ @array_mode = @hash_mode = false
105
+ end
40
106
  end
41
107
 
42
108
  def next_value(key_or_index)
43
- if @values.nil? || @values[key_or_index].nil? || @values[key_or_index].empty?
109
+ if @values[key_or_index].nil? || @values[key_or_index].empty?
44
110
  hash_or_array_value = @source.next_value
45
111
 
46
112
  case hash_or_array_value
47
113
  when Hash
48
- @values ||= {}
49
114
  hash_or_array_value.each do |k, v|
50
115
  @values[k] ||= []
51
116
  @values[k] << v
52
117
  end
53
118
  when Array
54
- @values ||= []
55
119
  hash_or_array_value.each_index do |i|
56
120
  @values[i] ||= []
57
121
  @values[i] << hash_or_array_value[i]
@@ -192,6 +192,8 @@ module Musa
192
192
  private_constant :Sequence
193
193
 
194
194
  class FromEvalBlockWithParameters
195
+ using Musa::Extension::DeepCopy
196
+
195
197
  include Serie
196
198
  include Musa::Extension::SmartProcBinder
197
199
 
@@ -211,8 +213,8 @@ module Musa
211
213
  end
212
214
 
213
215
  def _restart
214
- @value_parameters = @original_value_parameters.collect(&:clone)
215
- @key_parameters = @original_key_parameters.transform_values(&:clone)
216
+ @value_parameters = @original_value_parameters.clone(deep: true)
217
+ @key_parameters = @original_key_parameters.clone(deep: true)
216
218
 
217
219
  @first = true
218
220
  @value = nil
@@ -268,9 +270,7 @@ module Musa
268
270
  @to.nil?
269
271
  end
270
272
 
271
- private
272
-
273
- def sign_adjust_step
273
+ private def sign_adjust_step
274
274
  @step = (-@step if @to && (@from < @to && @step < 0 || @from > @to && @step > 0)) || @step
275
275
  end
276
276
  end
@@ -337,9 +337,7 @@ module Musa
337
337
  end
338
338
  end
339
339
 
340
- private
341
-
342
- def adjust_step
340
+ private def adjust_step
343
341
  @step = (-@step if @from < @to && @step < 0 || @from > @to && @step > 0) || @step
344
342
  @step_count = ((@to - @from) / @step).to_i
345
343
  end
@@ -411,9 +409,7 @@ module Musa
411
409
  value
412
410
  end
413
411
 
414
- private
415
-
416
- def adjust_step
412
+ private def adjust_step
417
413
  @step = (-@step if @from < @to && @step < 0 || @from > @to && @step > 0) || @step
418
414
  @step_count = ((@to - @from) / @step).to_i
419
415
  end
@@ -112,6 +112,10 @@ module Musa
112
112
  ProcessWith.new self, &yield_block
113
113
  end
114
114
 
115
+ def anticipate(&yield_block)
116
+ Anticipate.new self, &yield_block
117
+ end
118
+
115
119
  ###
116
120
  ### Implementation
117
121
  ###
@@ -130,7 +134,7 @@ module Musa
130
134
  @block = SmartProcBinder.new(block) if block_given?
131
135
 
132
136
  if @source.prototype?
133
- @sources = @sources.transform_values { |s| s.prototype }
137
+ @sources = @sources.transform_values { |s| s.prototype }.freeze
134
138
  else
135
139
  @sources = @sources.transform_values { |s| s.instance }
136
140
  end
@@ -168,6 +172,37 @@ module Musa
168
172
 
169
173
  private_constant :ProcessWith
170
174
 
175
+ class Anticipate
176
+ include Musa::Extension::SmartProcBinder
177
+ include Serie
178
+
179
+ attr_reader :source, :block
180
+
181
+ def initialize(serie, &block)
182
+ @source = serie
183
+ @block = block
184
+
185
+ mark_regarding! @source
186
+ end
187
+
188
+ def _restart
189
+ @source.restart
190
+ end
191
+
192
+ def _next_value
193
+ value = @source.next_value
194
+ peek_next_value = @source.peek_next_value
195
+
196
+ @block.call(value, peek_next_value)
197
+ end
198
+
199
+ def infinite?
200
+ @source.infinite?
201
+ end
202
+ end
203
+
204
+ private_constant :Anticipate
205
+
171
206
  class Switcher
172
207
  include Serie
173
208
 
@@ -185,7 +220,7 @@ module Musa
185
220
  @sources = hash_series.clone.transform_values(&get)
186
221
  end
187
222
 
188
- if get == :_prototype!
223
+ if get == :prototype!
189
224
  @sources.freeze
190
225
  end
191
226
 
@@ -236,7 +271,7 @@ module Musa
236
271
 
237
272
  _restart false
238
273
 
239
- if get == :_prototype!
274
+ if get == :prototype
240
275
  @sources.freeze
241
276
  end
242
277
 
@@ -293,7 +328,7 @@ module Musa
293
328
  @sources = hash_series.clone.transform_values(&get)
294
329
  end
295
330
 
296
- if get == :_prototype!
331
+ if get == :prototype
297
332
  @sources.freeze
298
333
  end
299
334
 
@@ -65,7 +65,7 @@ module Musa
65
65
  case n
66
66
  when nil
67
67
  time = value = nil
68
- when AbsTimed
68
+ when Musa::Datasets::AbsTimed
69
69
  time = n[:time].rationalize
70
70
  value = n[@value_attribute].rationalize
71
71
  when Array
@@ -87,8 +87,6 @@ module Musa
87
87
 
88
88
  attr_reader :source
89
89
 
90
- attr_reader :points_history
91
-
92
90
  def initialize(reference, step, source, value_attribute, stops, left_open, right_open)
93
91
  @reference = reference
94
92
  @step_size = step.abs
@@ -144,7 +142,9 @@ module Musa
144
142
 
145
143
  return { time: first[:time],
146
144
  @value_attribute => first[:value],
147
- duration: durations_to_sum.sum { |_| _[:duration] } }.extend(AbsTimed).extend(AbsD)
145
+ duration: durations_to_sum.sum { |_| _[:duration] } }
146
+ .extend(Musa::Datasets::AbsTimed)
147
+ .extend(Musa::Datasets::AbsD)
148
148
  else
149
149
  i += 1
150
150
  end
@@ -179,7 +179,9 @@ module Musa
179
179
 
180
180
  return { time: first[:time],
181
181
  @value_attribute => first[:value],
182
- duration: durations_to_sum.sum { |_| _[:duration] } }.extend(AbsTimed).extend(AbsD)
182
+ duration: durations_to_sum.sum { |_| _[:duration] } }
183
+ .extend(Musa::Datasets::AbsTimed)
184
+ .extend(Musa::Datasets::AbsD)
183
185
  else
184
186
  i += 1
185
187
  end
@@ -214,13 +216,13 @@ module Musa
214
216
  if @segments.last && @segments.last[:time] == from_time
215
217
 
216
218
  @segments.last[:duration] = to_time - from_time
217
- @segments.last[:info] += "; edited on a as start"
219
+ @segments.last[:info] += '; edited on a as start'
218
220
 
219
221
  else
220
222
  @segments << { time: from_time,
221
223
  value: from_value,
222
224
  duration: to_time - from_time,
223
- info: "added on a as start" }
225
+ info: 'added on a as start' }
224
226
 
225
227
  end
226
228
 
@@ -229,7 +231,7 @@ module Musa
229
231
  value: from_value,
230
232
  duration: 0,
231
233
  stop: true,
232
- info: "added on a as end stop" }
234
+ info: 'added on a as end stop' }
233
235
  end
234
236
  else
235
237
  time_increment = to_time - from_time
@@ -264,7 +266,7 @@ module Musa
264
266
  @segments.last[:value] == value
265
267
 
266
268
  @segments.last[:duration] = step_time_increment
267
- @segments.last[:info] += "; edited on b"
269
+ @segments.last[:info] += '; edited on b'
268
270
 
269
271
  # puts "process2: editing #{@segments.last}"
270
272
 
@@ -272,7 +274,7 @@ module Musa
272
274
  @segments << v = { time: intermediate_point_time,
273
275
  value: value,
274
276
  duration: step_time_increment,
275
- info: "added on b" }
277
+ info: 'added on b' }
276
278
 
277
279
  # puts "process2: adding #{v.inspect}"
278
280
  end
@@ -293,7 +295,7 @@ module Musa
293
295
 
294
296
  private def process(time, value, last_time_value)
295
297
  if time && value
296
- raise RuntimeError, "time only can go forward" if @last_processed_time && time <= @last_processed_time
298
+ raise RuntimeError, 'time only can go forward' if @last_processed_time && time <= @last_processed_time
297
299
 
298
300
  q_value = round_quantize(value)
299
301
 
@@ -400,7 +402,9 @@ module Musa
400
402
  if time > first_time
401
403
  result = { time: first_time,
402
404
  @value_attribute => round_to_nearest_quantize(first_value, value),
403
- duration: time - first_time }.extend(AbsD).extend(AbsTimed)
405
+ duration: time - first_time }
406
+ .extend(Musa::Datasets::AbsD)
407
+ .extend(Musa::Datasets::AbsTimed)
404
408
  else
405
409
  result = _next_value
406
410
  end
@@ -409,7 +413,9 @@ module Musa
409
413
  next_time = @crossings[1][:time]
410
414
  result = { time: time,
411
415
  @value_attribute => value,
412
- duration: next_time - time }.extend(AbsD).extend(AbsTimed)
416
+ duration: next_time - time }
417
+ .extend(Musa::Datasets::AbsD)
418
+ .extend(Musa::Datasets::AbsTimed)
413
419
 
414
420
  @crossings.shift
415
421
 
@@ -417,7 +423,9 @@ module Musa
417
423
  if @last_time && @last_time > @crossings[0][:time]
418
424
  result = { time: @crossings[0][:time],
419
425
  @value_attribute => @crossings[0][@value_attribute],
420
- duration: @last_time - @crossings[0][:time] }.extend(AbsD).extend(AbsTimed)
426
+ duration: @last_time - @crossings[0][:time] }
427
+ .extend(Musa::Datasets::AbsD)
428
+ .extend(Musa::Datasets::AbsTimed)
421
429
 
422
430
  @last_time = nil
423
431
  end
@@ -427,7 +435,9 @@ module Musa
427
435
  if @first && @last_time && @last_time > first_time
428
436
  result = { time: first_time,
429
437
  value: round_to_nearest_quantize(first_value),
430
- duration: @last_time - first_time }.extend(AbsD).extend(AbsTimed)
438
+ duration: @last_time - first_time }
439
+ .extend(Musa::Datasets::AbsD)
440
+ .extend(Musa::Datasets::AbsTimed)
431
441
 
432
442
  @first = false
433
443
  @last_time = false