musa-dsl 0.21.5 → 0.22.0
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/lib/musa-dsl.rb +1 -1
- data/lib/musa-dsl/core-ext.rb +1 -0
- data/lib/musa-dsl/core-ext/arrayfy.rb +9 -9
- data/lib/musa-dsl/core-ext/hashify.rb +42 -0
- data/lib/musa-dsl/core-ext/inspect-nice.rb +6 -1
- data/lib/musa-dsl/datasets/e.rb +22 -5
- data/lib/musa-dsl/datasets/gdv.rb +0 -1
- data/lib/musa-dsl/datasets/p.rb +28 -37
- data/lib/musa-dsl/datasets/pdv.rb +0 -1
- data/lib/musa-dsl/datasets/ps.rb +10 -78
- data/lib/musa-dsl/logger/logger.rb +2 -2
- data/lib/musa-dsl/matrix/matrix.rb +0 -57
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-every.rb +87 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-move.rb +439 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +2 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +210 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb +178 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +150 -597
- data/lib/musa-dsl/sequencer/base-sequencer-public.rb +58 -5
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +6 -8
- data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +1 -5
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +8 -0
- data/lib/musa-dsl/series/base-series.rb +43 -78
- data/lib/musa-dsl/series/flattener-timed-serie.rb +61 -0
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +95 -0
- data/lib/musa-dsl/series/holder-serie.rb +1 -1
- data/lib/musa-dsl/series/main-serie-constructors.rb +29 -83
- data/lib/musa-dsl/series/main-serie-operations.rb +60 -215
- data/lib/musa-dsl/series/proxy-serie.rb +1 -1
- data/lib/musa-dsl/series/quantizer-serie.rb +546 -0
- data/lib/musa-dsl/series/queue-serie.rb +1 -1
- data/lib/musa-dsl/series/series.rb +7 -2
- data/musa-dsl.gemspec +2 -2
- metadata +10 -4
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-control.rb +0 -216
- data/lib/musa-dsl/series/hash-serie-splitter.rb +0 -196
@@ -2,9 +2,14 @@ require_relative 'base-series'
|
|
2
2
|
|
3
3
|
require_relative 'main-serie-constructors'
|
4
4
|
require_relative 'main-serie-operations'
|
5
|
-
|
5
|
+
|
6
|
+
require_relative 'array-to-serie'
|
7
|
+
|
6
8
|
require_relative 'holder-serie'
|
7
9
|
require_relative 'proxy-serie'
|
8
10
|
require_relative 'queue-serie'
|
9
11
|
|
10
|
-
require_relative 'array-
|
12
|
+
require_relative 'hash-or-array-serie-splitter'
|
13
|
+
|
14
|
+
require_relative 'quantizer-serie'
|
15
|
+
require_relative 'flattener-timed-serie'
|
data/musa-dsl.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'musa-dsl'
|
3
|
-
s.version = '0.
|
4
|
-
s.date = '2020-10
|
3
|
+
s.version = '0.22.0'
|
4
|
+
s.date = '2020-11-10'
|
5
5
|
s.summary = 'A simple Ruby DSL for making complex music'
|
6
6
|
s.description = 'Musa-DSL: A Ruby DSL for algorithmic music composition, device language neutral (MIDI, OSC, etc)'
|
7
7
|
s.authors = ['Javier Sánchez Yeste']
|
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.
|
4
|
+
version: 0.22.0
|
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-10
|
11
|
+
date: 2020-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: citrus
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- lib/musa-dsl/core-ext/attribute-builder.rb
|
90
90
|
- lib/musa-dsl/core-ext/deep-copy.rb
|
91
91
|
- lib/musa-dsl/core-ext/dynamic-proxy.rb
|
92
|
+
- lib/musa-dsl/core-ext/hashify.rb
|
92
93
|
- lib/musa-dsl/core-ext/inspect-nice.rb
|
93
94
|
- lib/musa-dsl/core-ext/smart-proc-binder.rb
|
94
95
|
- lib/musa-dsl/core-ext/with.rb
|
@@ -163,8 +164,11 @@ files:
|
|
163
164
|
- lib/musa-dsl/repl.rb
|
164
165
|
- lib/musa-dsl/repl/repl.rb
|
165
166
|
- lib/musa-dsl/sequencer.rb
|
166
|
-
- lib/musa-dsl/sequencer/base-sequencer-implementation-
|
167
|
+
- lib/musa-dsl/sequencer/base-sequencer-implementation-every.rb
|
168
|
+
- lib/musa-dsl/sequencer/base-sequencer-implementation-move.rb
|
167
169
|
- lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb
|
170
|
+
- lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb
|
171
|
+
- lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb
|
168
172
|
- lib/musa-dsl/sequencer/base-sequencer-implementation.rb
|
169
173
|
- lib/musa-dsl/sequencer/base-sequencer-public.rb
|
170
174
|
- lib/musa-dsl/sequencer/base-sequencer-tick-based.rb
|
@@ -175,11 +179,13 @@ files:
|
|
175
179
|
- lib/musa-dsl/series.rb
|
176
180
|
- lib/musa-dsl/series/array-to-serie.rb
|
177
181
|
- lib/musa-dsl/series/base-series.rb
|
178
|
-
- lib/musa-dsl/series/
|
182
|
+
- lib/musa-dsl/series/flattener-timed-serie.rb
|
183
|
+
- lib/musa-dsl/series/hash-or-array-serie-splitter.rb
|
179
184
|
- lib/musa-dsl/series/holder-serie.rb
|
180
185
|
- lib/musa-dsl/series/main-serie-constructors.rb
|
181
186
|
- lib/musa-dsl/series/main-serie-operations.rb
|
182
187
|
- lib/musa-dsl/series/proxy-serie.rb
|
188
|
+
- lib/musa-dsl/series/quantizer-serie.rb
|
183
189
|
- lib/musa-dsl/series/queue-serie.rb
|
184
190
|
- lib/musa-dsl/series/series.rb
|
185
191
|
- lib/musa-dsl/transcription.rb
|
@@ -1,216 +0,0 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
|
3
|
-
module Musa
|
4
|
-
module Sequencer
|
5
|
-
class BaseSequencer
|
6
|
-
class EventHandler
|
7
|
-
include Musa::Extension::SmartProcBinder
|
8
|
-
|
9
|
-
attr_accessor :continue_parameters
|
10
|
-
|
11
|
-
@@counter = 0
|
12
|
-
|
13
|
-
def initialize(parent = nil)
|
14
|
-
@id = (@@counter += 1)
|
15
|
-
|
16
|
-
@parent = parent
|
17
|
-
@handlers = {}
|
18
|
-
|
19
|
-
@stop = false
|
20
|
-
end
|
21
|
-
|
22
|
-
def stop
|
23
|
-
@stop = true
|
24
|
-
end
|
25
|
-
|
26
|
-
def stopped?
|
27
|
-
@stop
|
28
|
-
end
|
29
|
-
|
30
|
-
def pause
|
31
|
-
raise NotImplementedError
|
32
|
-
end
|
33
|
-
|
34
|
-
def continue
|
35
|
-
@paused = false
|
36
|
-
end
|
37
|
-
|
38
|
-
def paused?
|
39
|
-
@paused
|
40
|
-
end
|
41
|
-
|
42
|
-
def on(event, name: nil, only_once: nil, &block)
|
43
|
-
only_once ||= false
|
44
|
-
|
45
|
-
@handlers[event] ||= {}
|
46
|
-
|
47
|
-
# TODO: add on_rescue: proc { |e| _rescue_block_error(e) } [this method is on Sequencer, not in EventHandler]
|
48
|
-
@handlers[event][name] = {block: SmartProcBinder.new(block), only_once: only_once }
|
49
|
-
end
|
50
|
-
|
51
|
-
def launch(event, *value_parameters, **key_parameters)
|
52
|
-
_launch event, value_parameters, key_parameters
|
53
|
-
end
|
54
|
-
|
55
|
-
def _launch(event, value_parameters = nil, key_parameters = nil)
|
56
|
-
value_parameters ||= []
|
57
|
-
key_parameters ||= {}
|
58
|
-
processed = false
|
59
|
-
|
60
|
-
if @handlers.key? event
|
61
|
-
@handlers[event].each do |name, handler|
|
62
|
-
handler[:block].call *value_parameters, **key_parameters
|
63
|
-
@handlers[event].delete name if handler[:only_once]
|
64
|
-
processed = true
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
@parent._launch event, value_parameters, key_parameters if @parent && !processed
|
69
|
-
end
|
70
|
-
|
71
|
-
def inspect
|
72
|
-
"EventHandler #{id}"
|
73
|
-
end
|
74
|
-
|
75
|
-
def id
|
76
|
-
if @parent
|
77
|
-
"#{@parent.id}.#{self.class.name.split('::').last}-#{@id}"
|
78
|
-
else
|
79
|
-
"#{self.class.name.split('::').last}-#{@id.to_s}"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
alias to_s inspect
|
84
|
-
end
|
85
|
-
|
86
|
-
private_constant :EventHandler
|
87
|
-
|
88
|
-
class PlayControl < EventHandler
|
89
|
-
attr_reader :do_after
|
90
|
-
|
91
|
-
def initialize(parent, after: nil)
|
92
|
-
super parent
|
93
|
-
|
94
|
-
@do_after = []
|
95
|
-
|
96
|
-
self.after &after if after
|
97
|
-
end
|
98
|
-
|
99
|
-
def pause
|
100
|
-
@paused = true
|
101
|
-
end
|
102
|
-
|
103
|
-
def store_continuation(sequencer:, serie:, nl_context:, mode:, decoder:, play_eval:, mode_args:)
|
104
|
-
@continuation_sequencer = sequencer
|
105
|
-
@continuation_parameters = {
|
106
|
-
serie: serie,
|
107
|
-
control: self,
|
108
|
-
nl_context: nl_context,
|
109
|
-
mode: mode,
|
110
|
-
decoder: decoder,
|
111
|
-
play_eval: play_eval,
|
112
|
-
mode_args: mode_args
|
113
|
-
}
|
114
|
-
end
|
115
|
-
|
116
|
-
def continue
|
117
|
-
super
|
118
|
-
@continuation_sequencer.continuation_play(@continuation_parameters) if @continuation_sequencer
|
119
|
-
end
|
120
|
-
|
121
|
-
def after(_bars = nil, &block)
|
122
|
-
# TODO implementar parámetro _bars (?)
|
123
|
-
@do_after << block
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
private_constant :PlayControl
|
128
|
-
|
129
|
-
class EveryControl < EventHandler
|
130
|
-
attr_reader :duration_value, :till_value, :condition_block, :do_on_stop, :do_after
|
131
|
-
|
132
|
-
attr_accessor :_start_position
|
133
|
-
attr_accessor :_execution_counter
|
134
|
-
|
135
|
-
def initialize(parent, duration: nil, till: nil, condition: nil, on_stop: nil, after_bars: nil, after: nil)
|
136
|
-
super parent
|
137
|
-
|
138
|
-
@duration_value = duration
|
139
|
-
@till_value = till
|
140
|
-
@condition_block = condition
|
141
|
-
|
142
|
-
@do_on_stop = []
|
143
|
-
@do_after = []
|
144
|
-
|
145
|
-
@do_on_stop << on_stop if on_stop
|
146
|
-
|
147
|
-
self.after after_bars, &after if after
|
148
|
-
end
|
149
|
-
|
150
|
-
def duration(value)
|
151
|
-
@duration_value = value.rationalize
|
152
|
-
end
|
153
|
-
|
154
|
-
def till(value)
|
155
|
-
@till_value = value.rationalize
|
156
|
-
end
|
157
|
-
|
158
|
-
def condition(&block)
|
159
|
-
@condition_block = block
|
160
|
-
end
|
161
|
-
|
162
|
-
def on_stop(&block)
|
163
|
-
@do_on_stop << block
|
164
|
-
end
|
165
|
-
|
166
|
-
def after(bars = nil, &block)
|
167
|
-
bars ||= 0
|
168
|
-
@do_after << { bars: bars.rationalize, block: block }
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
private_constant :EveryControl
|
173
|
-
|
174
|
-
class MoveControl < EventHandler
|
175
|
-
attr_reader :every_control, :do_on_stop, :do_after
|
176
|
-
|
177
|
-
def initialize(parent, duration: nil, till: nil, on_stop: nil, after_bars: nil, after: nil)
|
178
|
-
super parent
|
179
|
-
|
180
|
-
@every_control = EveryControl.new(self, duration: duration, till: till)
|
181
|
-
|
182
|
-
@do_on_stop = []
|
183
|
-
@do_after = []
|
184
|
-
|
185
|
-
@do_on_stop << on_stop if on_stop
|
186
|
-
self.after after_bars, &after if after
|
187
|
-
|
188
|
-
@every_control.on_stop do
|
189
|
-
@stop = true
|
190
|
-
@do_on_stop.each(&:call)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
def on_stop(&block)
|
195
|
-
@do_on_stop << block
|
196
|
-
end
|
197
|
-
|
198
|
-
def after(bars = nil, &block)
|
199
|
-
bars ||= 0
|
200
|
-
@do_after << { bars: bars.rationalize, block: block }
|
201
|
-
end
|
202
|
-
|
203
|
-
def stop
|
204
|
-
@every_control.stop
|
205
|
-
end
|
206
|
-
|
207
|
-
def stopped?
|
208
|
-
@stop
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
private_constant :MoveControl
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
@@ -1,196 +0,0 @@
|
|
1
|
-
module Musa
|
2
|
-
# TODO: adapt to series prototyping
|
3
|
-
# TODO: full test cases
|
4
|
-
|
5
|
-
module Series
|
6
|
-
module SerieOperations
|
7
|
-
def split(buffered: nil, master: nil)
|
8
|
-
buffered ||= false
|
9
|
-
|
10
|
-
return HashSplitter.new HashSplitter::KeyProxy.new(self) if master.nil? && !buffered
|
11
|
-
return HashSplitter.new HashSplitter::MasterSlaveKeyProxy.new(self, master) if !master.nil? && !buffered
|
12
|
-
return HashSplitter.new HashSplitter::BufferedKeyProxy.new(self) if buffered
|
13
|
-
end
|
14
|
-
|
15
|
-
class HashSplitter
|
16
|
-
def initialize(proxy)
|
17
|
-
@proxy = proxy
|
18
|
-
@series = {}
|
19
|
-
end
|
20
|
-
|
21
|
-
def [](key)
|
22
|
-
serie = if @series.key? key
|
23
|
-
@series[key]
|
24
|
-
else
|
25
|
-
@series[key] = Splitted.new(@proxy, key: key)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class KeyProxy
|
30
|
-
def initialize(hash_serie)
|
31
|
-
@serie = hash_serie.instance
|
32
|
-
@values = {}
|
33
|
-
end
|
34
|
-
|
35
|
-
def restart
|
36
|
-
@serie.restart
|
37
|
-
@values = {}
|
38
|
-
end
|
39
|
-
|
40
|
-
def next_value(key)
|
41
|
-
return nil unless @values
|
42
|
-
|
43
|
-
value = @values[key]
|
44
|
-
|
45
|
-
if value.nil?
|
46
|
-
before_values = @values.collect { |k, v| [k, v] unless v.nil? }.compact.to_h
|
47
|
-
|
48
|
-
@values = @serie.next_value
|
49
|
-
value = @values[key] if @values
|
50
|
-
|
51
|
-
warn "Warning: splitted serie #{@serie} values #{before_values} are being lost" if !value.nil? && !before_values.empty?
|
52
|
-
end
|
53
|
-
|
54
|
-
@values[key] = nil if @values
|
55
|
-
|
56
|
-
value
|
57
|
-
end
|
58
|
-
|
59
|
-
def peek_next_value(key)
|
60
|
-
value = @values[key]
|
61
|
-
|
62
|
-
if value.nil?
|
63
|
-
peek_values = @serie.peek_next_value
|
64
|
-
value = peek_values[key] if peek_values
|
65
|
-
end
|
66
|
-
|
67
|
-
value
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
class BufferedKeyProxy
|
72
|
-
def initialize(hash_serie)
|
73
|
-
@serie = hash_serie.instance
|
74
|
-
@values = {}
|
75
|
-
end
|
76
|
-
|
77
|
-
def restart
|
78
|
-
@serie.restart
|
79
|
-
@values = {}
|
80
|
-
end
|
81
|
-
|
82
|
-
def next_value(key)
|
83
|
-
value = nil
|
84
|
-
|
85
|
-
if @values[key].nil? || @values[key].empty?
|
86
|
-
hash_value = @serie.next_value
|
87
|
-
|
88
|
-
if hash_value
|
89
|
-
hash_value.each do |k, v|
|
90
|
-
@values[k] = [] if @values[k].nil?
|
91
|
-
@values[k] << v
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
value = @values[key].shift if @values[key]
|
97
|
-
|
98
|
-
value
|
99
|
-
end
|
100
|
-
|
101
|
-
def peek_next_value(key)
|
102
|
-
value = nil
|
103
|
-
|
104
|
-
if @values[key] && !@values[key].empty?
|
105
|
-
value = @values[key].first
|
106
|
-
else
|
107
|
-
peek_values = @serie.peek_next_value
|
108
|
-
value = peek_values[key] if peek_values
|
109
|
-
end
|
110
|
-
|
111
|
-
value
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
class MasterSlaveKeyProxy
|
116
|
-
def initialize(hash_serie, master)
|
117
|
-
@serie = hash_serie.instance
|
118
|
-
@master = master
|
119
|
-
@values = {}
|
120
|
-
@values_counter = {}
|
121
|
-
end
|
122
|
-
|
123
|
-
def restart
|
124
|
-
@serie.restart
|
125
|
-
@values = {}
|
126
|
-
@values_counter = {}
|
127
|
-
end
|
128
|
-
|
129
|
-
def next_value(key)
|
130
|
-
return nil unless @values
|
131
|
-
|
132
|
-
value = @values[key]
|
133
|
-
|
134
|
-
if value.nil?
|
135
|
-
@values = @serie.next_value
|
136
|
-
|
137
|
-
value = @values[key] if @values
|
138
|
-
|
139
|
-
# warn "Info: splitted serie #{@serie} use count on next_value: #{@values_counter}"
|
140
|
-
@values_counter = {}
|
141
|
-
end
|
142
|
-
|
143
|
-
@values_counter[key] ||= 0
|
144
|
-
@values_counter[key] += 1
|
145
|
-
|
146
|
-
@values[key] = nil if key == @master && @values
|
147
|
-
|
148
|
-
value
|
149
|
-
end
|
150
|
-
|
151
|
-
def peek_next_value(key)
|
152
|
-
return nil unless @values
|
153
|
-
|
154
|
-
value = @values[key]
|
155
|
-
|
156
|
-
if value.nil?
|
157
|
-
peek_values = @serie.peek_next_value
|
158
|
-
value = peek_values[key] if peek_values
|
159
|
-
end
|
160
|
-
|
161
|
-
value
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
class Splitted
|
166
|
-
include Serie
|
167
|
-
|
168
|
-
def initialize(proxy, key:)
|
169
|
-
@proxy = proxy
|
170
|
-
@key = key
|
171
|
-
|
172
|
-
mark_as_instance!
|
173
|
-
end
|
174
|
-
|
175
|
-
def _prototype
|
176
|
-
raise PrototypingSerieError, 'Cannot get prototype of a splitted serie'
|
177
|
-
end
|
178
|
-
|
179
|
-
def _restart
|
180
|
-
@proxy.restart
|
181
|
-
end
|
182
|
-
|
183
|
-
def next_value
|
184
|
-
@proxy.next_value(@key)
|
185
|
-
end
|
186
|
-
|
187
|
-
def peek_next_value
|
188
|
-
@proxy.peek_next_value(@key)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
private_constant :HashSplitter
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|