musa-dsl 0.22.5 → 0.23.3

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -1
  3. data/lib/musa-dsl.rb +14 -8
  4. data/lib/musa-dsl/core-ext/deep-copy.rb +12 -1
  5. data/lib/musa-dsl/core-ext/inspect-nice.rb +1 -2
  6. data/lib/musa-dsl/core-ext/smart-proc-binder.rb +13 -11
  7. data/lib/musa-dsl/datasets/p.rb +38 -15
  8. data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +14 -12
  9. data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +32 -6
  10. data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +24 -10
  11. data/lib/musa-dsl/generative/backboner.rb +6 -11
  12. data/lib/musa-dsl/generative/generative-grammar.rb +1 -3
  13. data/lib/musa-dsl/generative/markov.rb +10 -6
  14. data/lib/musa-dsl/logger/logger.rb +6 -1
  15. data/lib/musa-dsl/midi/midi-voices.rb +8 -7
  16. data/lib/musa-dsl/music/scales.rb +1 -1
  17. data/lib/musa-dsl/neumalang/neumalang.rb +1 -1
  18. data/lib/musa-dsl/neumas/array-to-neumas.rb +1 -1
  19. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +2 -2
  20. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +2 -1
  21. data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +2 -0
  22. data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +4 -2
  23. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +6 -6
  24. data/lib/musa-dsl/series/base-series.rb +293 -144
  25. data/lib/musa-dsl/series/buffer-serie.rb +236 -0
  26. data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +145 -115
  27. data/lib/musa-dsl/series/main-serie-constructors.rb +249 -156
  28. data/lib/musa-dsl/series/main-serie-operations.rb +331 -318
  29. data/lib/musa-dsl/series/proxy-serie.rb +25 -41
  30. data/lib/musa-dsl/series/quantizer-serie.rb +38 -38
  31. data/lib/musa-dsl/series/queue-serie.rb +39 -43
  32. data/lib/musa-dsl/series/series-composer.rb +316 -0
  33. data/lib/musa-dsl/series/series.rb +5 -1
  34. data/lib/musa-dsl/series/timed-serie.rb +119 -130
  35. data/musa-dsl.gemspec +13 -3
  36. metadata +9 -9
  37. data/.ruby-version +0 -1
  38. data/lib/musa-dsl/series/holder-serie.rb +0 -87
@@ -5,11 +5,15 @@ require_relative 'main-serie-operations'
5
5
 
6
6
  require_relative 'array-to-serie'
7
7
 
8
- require_relative 'holder-serie'
9
8
  require_relative 'proxy-serie'
10
9
  require_relative 'queue-serie'
11
10
 
11
+ require_relative 'buffer-serie'
12
+
13
+ require_relative 'series-composer'
14
+
12
15
  require_relative 'hash-or-array-serie-splitter'
13
16
 
14
17
  require_relative 'quantizer-serie'
15
18
  require_relative 'timed-serie'
19
+
@@ -1,45 +1,38 @@
1
1
  require_relative '../datasets/e'
2
2
 
3
- module Musa
4
- module Series
5
- extend self
3
+ require_relative 'base-series'
6
4
 
5
+ module Musa
6
+ module Series::Constructors
7
7
  def TIMED_UNION(*array_of_timed_series, **hash_of_timed_series)
8
8
  raise ArgumentError, 'Can\'t union an array of series with a hash of series' if array_of_timed_series.any? && hash_of_timed_series.any?
9
9
 
10
10
  if array_of_timed_series.any?
11
- TimedUnionOfArrayOfSeries.new(array_of_timed_series)
11
+ TimedUnionOfArrayOfTimedSeries.new(array_of_timed_series)
12
12
  elsif hash_of_timed_series.any?
13
- TimedUnionOfHashOfSeries.new(hash_of_timed_series)
13
+ TimedUnionOfHashOfTimedSeries.new(hash_of_timed_series)
14
14
  else
15
15
  raise ArgumentError, 'Missing argument series'
16
16
  end
17
17
  end
18
18
 
19
- class TimedUnionOfArrayOfSeries
20
- include Serie
21
-
22
- attr_reader :sources
19
+ class TimedUnionOfArrayOfTimedSeries
20
+ include Series::Serie.with(sources: true)
23
21
 
24
22
  def initialize(series)
25
- @sources = if series[0].prototype?
26
- series.collect(&:prototype).freeze
27
- else
28
- series.collect(&:instance)
29
- end
30
-
31
- _restart false
32
-
33
- mark_regarding! series[0]
23
+ self.sources = series
24
+ init
34
25
  end
35
26
 
36
- private def _restart(restart_sources = true)
37
- @sources.each { |serie| serie.restart } if restart_sources
27
+ private def _init
38
28
  @sources_next_values = Array.new(@sources.size)
39
-
40
29
  @components = nil
41
30
  end
42
31
 
32
+ private def _restart
33
+ @sources.each(&:restart)
34
+ end
35
+
43
36
  private def _next_value
44
37
  sources_values = @sources_next_values.each_index.collect do |i|
45
38
  @sources_next_values[i] || (@sources_next_values[i] = @sources[i].next_value)
@@ -74,7 +67,7 @@ module Musa
74
67
  end
75
68
  end
76
69
 
77
- result
70
+ result.extend(Musa::Datasets::AbsTimed)
78
71
  else
79
72
  nil
80
73
  end
@@ -146,37 +139,36 @@ module Musa
146
139
  return components, hash_mode, array_mode
147
140
  end
148
141
 
149
- private_constant :TimedUnionOfArrayOfSeries
142
+ private_constant :TimedUnionOfArrayOfTimedSeries
150
143
 
151
- class TimedUnionOfHashOfSeries
152
- include Serie
153
-
154
- attr_reader :sources
144
+ class TimedUnionOfHashOfTimedSeries
145
+ include Series::Serie.with(sources: true)
155
146
 
156
147
  def initialize(series)
157
- @components = series.keys
158
-
159
- @sources = if series.values.first.prototype?
160
- series.transform_values(&:prototype).freeze
161
- else
162
- series.transform_values(&:instance)
163
- end
164
-
165
- _restart false
148
+ self.sources = series
149
+ init
150
+ end
166
151
 
167
- mark_regarding! series.values.first
152
+ def sources=(series)
153
+ super
154
+ @components = series.keys
168
155
  end
169
156
 
170
- private def _restart(restart_sources = true)
171
- @sources.each_value { |serie| serie.restart } if restart_sources
157
+ private def _init
172
158
  @sources_next_values = @components.collect { |k| [k, nil] }.to_h
173
159
  @other_attributes = nil
174
160
  end
175
161
 
162
+ private def _restart
163
+ @sources.each_value(&:restart)
164
+ end
165
+
176
166
  private def _next_value
177
- sources_values = @sources_next_values.collect do |key, _|
178
- [key, @sources_next_values[key] || (@sources_next_values[key] = @sources[key].next_value)]
179
- end.to_h
167
+ sources_values = {}
168
+
169
+ @components.each do |key|
170
+ sources_values[key] = @sources_next_values[key] || (@sources_next_values[key] = @sources[key].next_value)
171
+ end
180
172
 
181
173
  @other_attributes = infer_other_attributes(sources_values) unless @other_attributes
182
174
 
@@ -205,7 +197,7 @@ module Musa
205
197
  end
206
198
  end
207
199
 
208
- result
200
+ result.extend(Musa::Datasets::AbsTimed)
209
201
  else
210
202
  nil
211
203
  end
@@ -228,127 +220,124 @@ module Musa
228
220
  end
229
221
  end
230
222
 
231
- private_constant :TimedUnionOfHashOfSeries
223
+ private_constant :TimedUnionOfHashOfTimedSeries
224
+ end
232
225
 
233
- module SerieOperations
234
- def flatten_timed
235
- TimedFlattener.new(self)
236
- end
226
+ module Series::Operations
227
+ def flatten_timed
228
+ TimedFlattener.new(self)
229
+ end
237
230
 
238
- def compact_timed
239
- TimedCompacter.new(self)
240
- end
231
+ def compact_timed
232
+ TimedCompacter.new(self)
233
+ end
241
234
 
242
- def union_timed(*other_timed_series, key: nil, **other_key_timed_series)
243
- if key && other_key_timed_series.any?
244
- Series::TIMED_UNION(key => self, **other_key_timed_series)
235
+ def union_timed(*other_timed_series, key: nil, **other_key_timed_series)
236
+ if key && other_key_timed_series.any?
237
+ Series::Constructors.TIMED_UNION(key => self, **other_key_timed_series)
245
238
 
246
- elsif other_timed_series.any? && other_key_timed_series.empty?
247
- Series::TIMED_UNION(self, *other_timed_series)
239
+ elsif other_timed_series.any? && other_key_timed_series.empty?
240
+ Series::Constructors.TIMED_UNION(self, *other_timed_series)
248
241
 
249
- else
250
- raise ArgumentError, 'Can\'t union an array of series with a hash of series'
251
- end
242
+ else
243
+ raise ArgumentError, 'Can\'t union an array of series with a hash of series'
252
244
  end
245
+ end
253
246
 
254
- class TimedFlattener
255
- include Serie
256
-
257
- attr_reader :source
247
+ class TimedFlattener
248
+ include Series::Serie.with(source: true)
258
249
 
259
- def initialize(serie)
260
- @source = serie
261
- mark_regarding! @source
262
- end
250
+ def initialize(serie)
251
+ self.source = serie
252
+ init
253
+ end
263
254
 
264
- def _restart
265
- @source.restart
266
- end
255
+ private def _restart
256
+ @source.restart
257
+ end
267
258
 
268
- def _next_value
269
- source_value = @source.next_value
259
+ private def _next_value
260
+ source_value = @source.next_value
270
261
 
271
- if !source_value.nil?
272
- time = source_value[:time]
273
- source_value_value = source_value[:value]
262
+ if !source_value.nil?
263
+ time = source_value[:time]
264
+ source_value_value = source_value[:value]
274
265
 
275
- source_value_extra = (source_value.keys - [:time, :value]).collect do |attribute_name|
276
- [attribute_name, source_value[attribute_name]]
277
- end.to_h
266
+ source_value_extra = (source_value.keys - [:time, :value]).collect do |attribute_name|
267
+ [attribute_name, source_value[attribute_name]]
268
+ end.to_h
278
269
 
279
- case source_value_value
280
- when Hash
281
- result = {}
282
- source_value_value.each_pair do |key, value|
283
- result[key] = { time: time, value: value }.extend(Musa::Datasets::AbsTimed)
270
+ case source_value_value
271
+ when Hash
272
+ result = {}
273
+ source_value_value.each_pair do |key, value|
274
+ result[key] = { time: time, value: value }.extend(Musa::Datasets::AbsTimed)
284
275
 
285
- source_value_extra.each do |attribute_name, attribute_value|
286
- result[key][attribute_name] = attribute_value[key]
287
- end
276
+ source_value_extra.each do |attribute_name, attribute_value|
277
+ result[key][attribute_name] = attribute_value[key]
288
278
  end
279
+ end
289
280
 
290
- when Array
291
- result = []
292
- source_value_value.each_index do |index|
293
- result[index] = { time: time, value: source_value_value[index] }.extend(Musa::Datasets::AbsTimed)
281
+ when Array
282
+ result = []
283
+ source_value_value.each_index do |index|
284
+ result[index] = { time: time, value: source_value_value[index] }.extend(Musa::Datasets::AbsTimed)
294
285
 
295
- source_value_extra.each do |attribute_name, attribute_value|
296
- result[index][attribute_name] = attribute_value[index]
297
- end
286
+ source_value_extra.each do |attribute_name, attribute_value|
287
+ result[index][attribute_name] = attribute_value[index]
298
288
  end
299
- else
300
- result = source_value.clone.extend(Musa::Datasets::AbsTimed)
301
289
  end
302
-
303
- result
304
290
  else
305
- nil
291
+ result = source_value.clone.extend(Musa::Datasets::AbsTimed)
306
292
  end
307
- end
308
293
 
309
- def infinite?
310
- @source.infinite?
294
+ result.extend(Musa::Datasets::AbsTimed)
295
+ else
296
+ nil
311
297
  end
312
298
  end
313
299
 
314
- private_constant :TimedFlattener
300
+ def infinite?
301
+ @source.infinite?
302
+ end
315
303
  end
316
304
 
317
- class TimedCompacter
318
- include Serie
305
+ private_constant :TimedFlattener
306
+ end
319
307
 
320
- attr_reader :source
308
+ class TimedCompacter
309
+ include Series::Serie.with(source: true)
321
310
 
322
- def initialize(serie)
323
- @source = serie
324
- mark_regarding! @source
325
- end
311
+ def initialize(serie)
312
+ self.source = serie
313
+ init
314
+ end
326
315
 
327
- def _restart
328
- @source.restart
329
- end
316
+ private def _restart
317
+ @source.restart
318
+ end
330
319
 
331
- def _next_value
332
- while (source_value = @source.next_value) && skip_value?(source_value[:value]); end
333
- source_value
334
- end
320
+ private def _next_value
321
+ while (source_value = @source.next_value) && skip_value?(source_value[:value]); end
322
+ source_value
323
+ end
335
324
 
336
- def infinite?
337
- @source.infinite?
338
- end
325
+ def infinite?
326
+ @source.infinite?
327
+ end
339
328
 
340
- private def skip_value?(timed_value)
341
- case timed_value
342
- when Hash
343
- timed_value.all? { |_, v| v.nil? }
344
- when Array
345
- timed_value.all?(&:nil?)
346
- else
347
- timed_value.nil?
348
- end
329
+ private def skip_value?(timed_value)
330
+ case timed_value
331
+ when Hash
332
+ timed_value.all? { |_, v| v.nil? }
333
+ when Array
334
+ timed_value.all?(&:nil?)
335
+ else
336
+ timed_value.nil?
349
337
  end
350
338
  end
351
-
352
- private_constant :TimedCompacter
353
339
  end
340
+
341
+ private_constant :TimedCompacter
354
342
  end
343
+
data/musa-dsl.gemspec CHANGED
@@ -1,15 +1,25 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'musa-dsl'
3
- s.version = '0.22.5'
4
- s.date = '2020-11-18'
3
+ s.version = '0.23.3'
4
+ s.date = '2021-07-28'
5
5
  s.summary = 'A simple Ruby DSL for making complex music'
6
- s.description = 'Musa-DSL: A Ruby DSL for algorithmic music composition, device language neutral (MIDI, OSC, etc)'
6
+ s.description = 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical thinking and composition'
7
7
  s.authors = ['Javier Sánchez Yeste']
8
8
  s.email = 'javier.sy@gmail.com'
9
9
  s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|samples)/}) }
10
10
  s.homepage = 'https://github.com/javier-sy/musa-dsl'
11
11
  s.license = 'LGPL-3.0'
12
12
 
13
+ s.required_ruby_version = '~> 2.7'
14
+
15
+ # TODO
16
+ #s.metadata = {
17
+ # "source_code_uri" => "https://",
18
+ # "homepage_uri" => "",
19
+ # "documentation_uri" => "",
20
+ # "changelog_uri" => ""
21
+ #}
22
+
13
23
  s.add_runtime_dependency 'citrus', '~> 3.0.0', '>= 3.0.0'
14
24
 
15
25
  s.add_runtime_dependency 'midi-message', '~> 0.4', '>= 0.4.9'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: musa-dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.22.5
4
+ version: 0.23.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javier Sánchez Yeste
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-18 00:00:00.000000000 Z
11
+ date: 2021-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: citrus
@@ -70,15 +70,14 @@ dependencies:
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: 0.2.4
73
- description: 'Musa-DSL: A Ruby DSL for algorithmic music composition, device language
74
- neutral (MIDI, OSC, etc)'
73
+ description: 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical
74
+ thinking and composition'
75
75
  email: javier.sy@gmail.com
76
76
  executables: []
77
77
  extensions: []
78
78
  extra_rdoc_files: []
79
79
  files:
80
80
  - ".gitignore"
81
- - ".ruby-version"
82
81
  - Gemfile
83
82
  - LICENSE.md
84
83
  - README.md
@@ -179,13 +178,14 @@ files:
179
178
  - lib/musa-dsl/series.rb
180
179
  - lib/musa-dsl/series/array-to-serie.rb
181
180
  - lib/musa-dsl/series/base-series.rb
181
+ - lib/musa-dsl/series/buffer-serie.rb
182
182
  - lib/musa-dsl/series/hash-or-array-serie-splitter.rb
183
- - lib/musa-dsl/series/holder-serie.rb
184
183
  - lib/musa-dsl/series/main-serie-constructors.rb
185
184
  - lib/musa-dsl/series/main-serie-operations.rb
186
185
  - lib/musa-dsl/series/proxy-serie.rb
187
186
  - lib/musa-dsl/series/quantizer-serie.rb
188
187
  - lib/musa-dsl/series/queue-serie.rb
188
+ - lib/musa-dsl/series/series-composer.rb
189
189
  - lib/musa-dsl/series/series.rb
190
190
  - lib/musa-dsl/series/timed-serie.rb
191
191
  - lib/musa-dsl/transcription.rb
@@ -212,16 +212,16 @@ require_paths:
212
212
  - lib
213
213
  required_ruby_version: !ruby/object:Gem::Requirement
214
214
  requirements:
215
- - - ">="
215
+ - - "~>"
216
216
  - !ruby/object:Gem::Version
217
- version: '0'
217
+ version: '2.7'
218
218
  required_rubygems_version: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - ">="
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
223
  requirements: []
224
- rubygems_version: 3.1.4
224
+ rubygems_version: 3.1.6
225
225
  signing_key:
226
226
  specification_version: 4
227
227
  summary: A simple Ruby DSL for making complex music