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.
- checksums.yaml +4 -4
- data/Gemfile +3 -1
- data/lib/musa-dsl.rb +14 -8
- data/lib/musa-dsl/core-ext/deep-copy.rb +12 -1
- data/lib/musa-dsl/core-ext/inspect-nice.rb +1 -2
- data/lib/musa-dsl/core-ext/smart-proc-binder.rb +13 -11
- data/lib/musa-dsl/datasets/p.rb +41 -16
- data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +14 -12
- data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +32 -6
- data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +24 -10
- data/lib/musa-dsl/generative/backboner.rb +6 -11
- data/lib/musa-dsl/generative/generative-grammar.rb +1 -3
- data/lib/musa-dsl/generative/markov.rb +10 -6
- data/lib/musa-dsl/logger/logger.rb +6 -1
- data/lib/musa-dsl/matrix/matrix.rb +9 -7
- data/lib/musa-dsl/midi/midi-voices.rb +8 -7
- data/lib/musa-dsl/music/scales.rb +1 -1
- data/lib/musa-dsl/neumalang/neumalang.rb +1 -1
- data/lib/musa-dsl/neumas/array-to-neumas.rb +1 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +9 -4
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +30 -129
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +10 -24
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +9 -9
- data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +3 -5
- data/lib/musa-dsl/sequencer/base-sequencer.rb +14 -23
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +9 -7
- data/lib/musa-dsl/sequencer/sequencer.rb +7 -0
- data/lib/musa-dsl/series/base-series.rb +293 -144
- data/lib/musa-dsl/series/buffer-serie.rb +237 -0
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +136 -105
- data/lib/musa-dsl/series/main-serie-constructors.rb +251 -156
- data/lib/musa-dsl/series/main-serie-operations.rb +308 -303
- data/lib/musa-dsl/series/proxy-serie.rb +21 -41
- data/lib/musa-dsl/series/quantizer-serie.rb +44 -46
- data/lib/musa-dsl/series/queue-serie.rb +39 -43
- data/lib/musa-dsl/series/series-composer.rb +149 -0
- data/lib/musa-dsl/series/series.rb +6 -3
- data/lib/musa-dsl/series/timed-serie.rb +343 -0
- data/musa-dsl.gemspec +13 -3
- metadata +10 -11
- data/lib/musa-dsl/series/flattener-timed-serie.rb +0 -61
- data/lib/musa-dsl/series/holder-serie.rb +0 -87
- 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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
2
|
+
module Series::Operations
|
3
|
+
def split
|
4
|
+
Splitter.new(Splitter::BufferedProxy.new(self))
|
5
|
+
end
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
class Splitter
|
8
|
+
include Enumerable
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
def initialize(proxy)
|
11
|
+
@proxy = proxy
|
12
|
+
@series = {}
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
49
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
56
|
-
|
63
|
+
class BufferedProxy
|
64
|
+
include Series::Serie::Prototyping
|
57
65
|
|
58
|
-
|
66
|
+
def initialize(hash_or_array_serie)
|
67
|
+
@source = hash_or_array_serie
|
68
|
+
mark_regarding! @source
|
59
69
|
|
60
|
-
|
61
|
-
|
70
|
+
init
|
71
|
+
end
|
62
72
|
|
63
|
-
|
64
|
-
super
|
65
|
-
restart
|
66
|
-
end
|
73
|
+
attr_reader :components
|
67
74
|
|
68
|
-
|
69
|
-
|
75
|
+
def hash_mode?; @hash_mode; end
|
76
|
+
def array_mode?; @array_mode; end
|
70
77
|
|
71
|
-
|
72
|
-
|
78
|
+
def init
|
79
|
+
infer_components
|
80
|
+
end
|
73
81
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
119
|
-
|
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
|
-
|
122
|
-
@source = proxy
|
123
|
-
@key_or_index = key_or_index
|
116
|
+
@asked_to_restart = {}
|
124
117
|
|
125
|
-
|
118
|
+
@components.each do |component|
|
119
|
+
@asked_to_restart[component] = false
|
126
120
|
end
|
121
|
+
end
|
127
122
|
|
128
|
-
|
129
|
-
|
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
|
-
|
133
|
-
@
|
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
|
-
|
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 :
|
169
|
+
private_constant :Split
|
141
170
|
end
|
171
|
+
|
172
|
+
private_constant :Splitter
|
142
173
|
end
|
143
174
|
end
|