musa-dsl 0.22.3 → 0.23.1

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 (43) 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 +41 -16
  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/matrix/matrix.rb +9 -7
  16. data/lib/musa-dsl/midi/midi-voices.rb +8 -7
  17. data/lib/musa-dsl/music/scales.rb +1 -1
  18. data/lib/musa-dsl/neumalang/neumalang.rb +1 -1
  19. data/lib/musa-dsl/neumas/array-to-neumas.rb +1 -1
  20. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +9 -4
  21. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +30 -129
  22. data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +10 -24
  23. data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +9 -9
  24. data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +3 -5
  25. data/lib/musa-dsl/sequencer/base-sequencer.rb +14 -23
  26. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +9 -7
  27. data/lib/musa-dsl/sequencer/sequencer.rb +7 -0
  28. data/lib/musa-dsl/series/base-series.rb +293 -144
  29. data/lib/musa-dsl/series/buffer-serie.rb +237 -0
  30. data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +136 -105
  31. data/lib/musa-dsl/series/main-serie-constructors.rb +251 -156
  32. data/lib/musa-dsl/series/main-serie-operations.rb +308 -303
  33. data/lib/musa-dsl/series/proxy-serie.rb +21 -41
  34. data/lib/musa-dsl/series/quantizer-serie.rb +44 -46
  35. data/lib/musa-dsl/series/queue-serie.rb +39 -43
  36. data/lib/musa-dsl/series/series-composer.rb +149 -0
  37. data/lib/musa-dsl/series/series.rb +6 -3
  38. data/lib/musa-dsl/series/timed-serie.rb +343 -0
  39. data/musa-dsl.gemspec +13 -3
  40. metadata +10 -11
  41. data/lib/musa-dsl/series/flattener-timed-serie.rb +0 -61
  42. data/lib/musa-dsl/series/holder-serie.rb +0 -87
  43. data/lib/musa-dsl/series/union-timed-series.rb +0 -109
@@ -0,0 +1,237 @@
1
+ module Musa
2
+ module Series::Operations
3
+ def buffered(sync: false)
4
+ if sync
5
+ SyncBufferSerie.new(self)
6
+ else
7
+ BufferSerie.new(self)
8
+ end
9
+ end
10
+
11
+ class SyncBufferSerie
12
+ include Series::Serie.with(source: true)
13
+
14
+ def initialize(serie)
15
+ self.source = serie
16
+ @history = []
17
+ @buffers = Set[]
18
+
19
+ init
20
+ end
21
+
22
+ private def _restart
23
+ @source.restart
24
+ clear_old_history
25
+ end
26
+
27
+ private def _next_value
28
+ @source.next_value.tap { |value| @history << value unless value.nil? && !@history.empty? && @history.last.nil? }
29
+ end
30
+
31
+ def buffer
32
+ @buffer ||= Buffer.new(@history)
33
+ @buffer.send(@get).tap { |_| @buffers << _ }
34
+ end
35
+
36
+ private def clear_old_history
37
+ min_last_nil_index = @buffers.collect(&:last_nil_index).min
38
+
39
+ if min_last_nil_index && min_last_nil_index >=0
40
+ @history = @history.drop(min_last_nil_index)
41
+
42
+ @buffers.each do |b|
43
+ b._reindex(@history, min_last_nil_index)
44
+ end
45
+ end
46
+ end
47
+
48
+ class Buffer
49
+ include Series::Serie.base
50
+
51
+ def initialize(history)
52
+ @history = history
53
+ @last_nil_index = -1
54
+ init
55
+ end
56
+
57
+ attr_reader :last_nil_index
58
+
59
+ def _reindex(history, offset)
60
+ @history = history
61
+
62
+ @last_nil_index -= offset
63
+ @index -= offset
64
+ end
65
+
66
+ private def _init
67
+ @index = @last_nil_index
68
+ @wait_restart = false
69
+ end
70
+
71
+ private def _next_value
72
+ @index += 1 if @index + 1 < @history.size && !@wait_restart
73
+
74
+ if @history[@index].nil? && @index < @history.size
75
+
76
+ @wait_restart = true
77
+
78
+ if @index + 1 < @history.size
79
+ @last_nil_index = @index
80
+ end
81
+ end
82
+
83
+ @history[@index]
84
+ end
85
+ end
86
+
87
+ private_constant :Buffer
88
+ end
89
+
90
+ private_constant :SyncBufferSerie
91
+
92
+ class BufferSerie
93
+ # modo fill_on_restart: cuando una serie hace restart, las demás no se ven afectadas porque siguen recibiendo
94
+ # todos los elementos de la serie original
95
+
96
+ include Series::Serie.with(source: true)
97
+
98
+ def initialize(serie)
99
+ self.source = serie
100
+
101
+ @history = [nil]
102
+ @nils = [0]
103
+ @buffers = Set[]
104
+
105
+ @singleton = nil
106
+ @buffer = nil
107
+
108
+ init
109
+ end
110
+
111
+ def instance
112
+ @singleton ||= super
113
+ end
114
+
115
+ def buffer
116
+ @buffer ||= Buffer.new(self)
117
+ @buffer
118
+ end
119
+
120
+ private def _restart(main)
121
+ raise ArgumentError, "Can't restart a BufferSerie directly. Should use a buffer instance instead." unless main
122
+ return if @source_just_restarted
123
+
124
+ next_nil = @nils.find { |_| _ > main.index }
125
+
126
+ if next_nil && main.index < next_nil
127
+ main.last_nil_index = main.index = next_nil
128
+
129
+ else
130
+ until _next_value.nil?; end
131
+ main.last_nil_index = main.index = @nils.last
132
+ end
133
+
134
+ clear_old_history
135
+
136
+ @source.restart
137
+ @source_just_restarted = true
138
+ end
139
+
140
+ private def _next_value
141
+ @source_just_restarted = false
142
+ value = @source.next_value
143
+
144
+ if value.nil?
145
+ unless @history.last.nil?
146
+ @history << nil
147
+ @nils << @history.size - 1
148
+ end
149
+ else
150
+ @history << value
151
+ end
152
+
153
+ value
154
+ end
155
+
156
+ def _register(buffer)
157
+ @buffers << buffer
158
+
159
+ buffer.history = @history
160
+ buffer.last_nil_index = 0
161
+ end
162
+
163
+ private def clear_old_history
164
+ min_last_nil_index = @buffers.collect(&:last_nil_index).min
165
+
166
+ if min_last_nil_index && min_last_nil_index >=0
167
+
168
+ pre_nils = @nils.clone
169
+ @history = @history.drop(min_last_nil_index)
170
+
171
+ @nils.collect! { |_| _ - min_last_nil_index }
172
+ @nils.delete_if(&:negative?)
173
+
174
+ @buffers.each do |b|
175
+ b._reindex(@history, min_last_nil_index)
176
+ end
177
+ end
178
+ end
179
+
180
+ class Buffer
181
+ include Series::Serie.with(source: true, private_source: true)
182
+
183
+ def initialize(base)
184
+ self.source = base
185
+
186
+ mark_as_prototype! # necesario para que se creen instancias diferentes cada vez que se ejecute BufferSerie.buffer()
187
+
188
+ init
189
+ end
190
+
191
+ attr_accessor :history
192
+ attr_accessor :last_nil_index
193
+ attr_accessor :index
194
+
195
+ def _reindex(history, offset)
196
+ @history = history
197
+ @last_nil_index -= offset
198
+ @index -= offset
199
+ end
200
+
201
+ private def _init
202
+ @source._register(self) if instance?
203
+ @index = @last_nil_index
204
+ end
205
+
206
+ private def _restart
207
+ @source.restart(self)
208
+ @needs_restart = false
209
+ end
210
+
211
+ private def _next_value
212
+ value = nil
213
+
214
+ unless @needs_restart
215
+ if @index + 1 < @history.size
216
+ @index += 1
217
+ value = @history[@index]
218
+ else
219
+ @source.next_value
220
+ value = _next_value
221
+ end
222
+
223
+ if value.nil?
224
+ @needs_restart = true
225
+ end
226
+ end
227
+
228
+ value
229
+ end
230
+ end
231
+
232
+ private_constant :Buffer
233
+ end
234
+
235
+ private_constant :BufferSerie
236
+ end
237
+ end
@@ -1,143 +1,174 @@
1
1
  module Musa
2
- module Series
3
- module SerieOperations
4
- def split
5
- Splitter.new(Splitter::BufferedProxy.new(self))
6
- end
2
+ module Series::Operations
3
+ def split
4
+ Splitter.new(Splitter::BufferedProxy.new(self))
5
+ end
7
6
 
8
- class Splitter
9
- include Enumerable
7
+ class Splitter
8
+ include Enumerable
10
9
 
11
- def initialize(proxy)
12
- @proxy = proxy
13
- @series = {}
14
- end
10
+ def initialize(proxy)
11
+ @proxy = proxy
12
+ @series = {}
13
+ end
15
14
 
16
- def [](key_or_index)
17
- if @series.has_key?(key_or_index)
18
- @series[key_or_index]
19
- else
20
- @series[key_or_index] = Split.new(@proxy, key_or_index)
21
- end
15
+ def [](key_or_index)
16
+ if @series.has_key?(key_or_index)
17
+ @series[key_or_index]
18
+ else
19
+ @series[key_or_index] = Split.new(@proxy, key_or_index)
22
20
  end
21
+ end
23
22
 
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
23
+ def each
24
+ if block_given?
25
+ if @proxy.hash_mode?
26
+ @proxy.components.each do |key|
27
+ yield [key, self[key]]
36
28
  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
29
+ elsif @proxy.array_mode?
30
+ @proxy.components.each do |index|
31
+ yield self[index]
44
32
  end
33
+ else
34
+ # do nothing
35
+ end
36
+ else
37
+ if @proxy.hash_mode?
38
+ @proxy.components.collect { |key| [key, self[key]] }.each
39
+ elsif @proxy.array_mode?
40
+ @proxy.components.collect { |index| self[index] }.each
41
+ else
42
+ [].each
45
43
  end
46
44
  end
45
+ end
47
46
 
48
- class BufferedProxy
49
- include SeriePrototyping
47
+ def to_hash
48
+ if @proxy.hash_mode?
49
+ @proxy.components.collect { |key| [key, self[key]] }.to_h
50
+ else
51
+ raise RuntimeError, 'Splitter is not based on Hash: can\'t convert to Hash'
52
+ end
53
+ end
50
54
 
51
- def initialize(hash_or_array_serie)
52
- @source = hash_or_array_serie
53
- restart restart_source: false
55
+ def to_ary
56
+ if @proxy.array_mode?
57
+ [].tap { |_| @proxy.components.each { |i| _[i] = self[i] } }
58
+ else
59
+ raise RuntimeError, 'Splitter is not based on Array: can\'t convert to Array'
60
+ end
61
+ end
54
62
 
55
- mark_regarding! @source
56
- end
63
+ class BufferedProxy
64
+ include Series::Serie::Prototyping
57
65
 
58
- attr_reader :components
66
+ def initialize(hash_or_array_serie)
67
+ @source = hash_or_array_serie
68
+ mark_regarding! @source
59
69
 
60
- def hash_mode?; @hash_mode; end
61
- def array_mode?; @array_mode; end
70
+ init
71
+ end
62
72
 
63
- protected def _instance!
64
- super
65
- restart
66
- end
73
+ attr_reader :components
67
74
 
68
- def restart(restart_source: true)
69
- @source.restart if restart_source
75
+ def hash_mode?; @hash_mode; end
76
+ def array_mode?; @array_mode; end
70
77
 
71
- source = @source.instance
72
- sample = source.current_value || source.peek_next_value
78
+ def init
79
+ infer_components
80
+ end
73
81
 
74
- case sample
75
- when Array
76
- @components = (0..sample.size-1).to_a
77
- @values = []
78
- @array_mode = true
79
- @hash_mode = false
80
- when Hash
81
- @components = sample.keys.clone
82
- @values = {}
83
- @array_mode = false
84
- @hash_mode = true
85
- else
86
- @components = []
87
- @values = nil
88
- @array_mode = @hash_mode = false
89
- end
82
+ def restart(key_or_index = nil)
83
+ if key_or_index
84
+ @asked_to_restart[key_or_index] = true
85
+ else
86
+ @components.each { |c| @asked_to_restart[c] = true }
90
87
  end
91
88
 
92
- def next_value(key_or_index)
93
- if @values[key_or_index].nil? || @values[key_or_index].empty?
94
- hash_or_array_value = @source.next_value
95
-
96
- case hash_or_array_value
97
- when Hash
98
- hash_or_array_value.each do |k, v|
99
- @values[k] ||= []
100
- @values[k] << v
101
- end
102
- when Array
103
- hash_or_array_value.each_index do |i|
104
- @values[i] ||= []
105
- @values[i] << hash_or_array_value[i]
106
- end
107
- end
108
- end
109
-
110
- if @values && !@values[key_or_index].nil?
111
- @values[key_or_index].shift
112
- else
113
- nil
114
- end
89
+ if @asked_to_restart.values.all?
90
+ @source.restart
91
+ infer_components
115
92
  end
116
93
  end
117
94
 
118
- class Split
119
- include Serie
95
+ private def infer_components
96
+ source = @source.instance
97
+ sample = source.current_value || source.peek_next_value
98
+
99
+ case sample
100
+ when Array
101
+ @components = (0..sample.size-1).to_a
102
+ @values = []
103
+ @array_mode = true
104
+ @hash_mode = false
105
+ when Hash
106
+ @components = sample.keys.clone
107
+ @values = {}
108
+ @array_mode = false
109
+ @hash_mode = true
110
+ else
111
+ @components = []
112
+ @values = nil
113
+ @array_mode = @hash_mode = false
114
+ end
120
115
 
121
- def initialize(proxy, key_or_index)
122
- @source = proxy
123
- @key_or_index = key_or_index
116
+ @asked_to_restart = {}
124
117
 
125
- mark_regarding! @source
118
+ @components.each do |component|
119
+ @asked_to_restart[component] = false
126
120
  end
121
+ end
127
122
 
128
- def _restart
129
- @source.restart
123
+ def next_value(key_or_index)
124
+ if @values[key_or_index].nil? || @values[key_or_index].empty?
125
+
126
+ hash_or_array_value = @source.next_value
127
+
128
+ case hash_or_array_value
129
+ when Hash
130
+ hash_or_array_value.each do |k, v|
131
+ @values[k] ||= []
132
+ @values[k] << v
133
+ end
134
+ when Array
135
+ hash_or_array_value.each_index do |i|
136
+ @values[i] ||= []
137
+ @values[i] << hash_or_array_value[i]
138
+ end
139
+ end
130
140
  end
131
141
 
132
- def _next_value
133
- @source.next_value(@key_or_index)
142
+ if @values && !@values[key_or_index].nil?
143
+ @values[key_or_index].shift
144
+ else
145
+ nil
134
146
  end
135
147
  end
148
+ end
149
+
150
+ class Split
151
+ include Series::Serie.base
152
+
153
+ def initialize(proxy, key_or_index)
154
+ @source = proxy
155
+ @key_or_index = key_or_index
136
156
 
137
- private_constant :Split
157
+ mark_regarding! @source
158
+ end
159
+
160
+ private def _restart
161
+ @source.restart @key_or_index
162
+ end
163
+
164
+ private def _next_value
165
+ @source.next_value(@key_or_index)
166
+ end
138
167
  end
139
168
 
140
- private_constant :Splitter
169
+ private_constant :Split
141
170
  end
171
+
172
+ private_constant :Splitter
142
173
  end
143
174
  end