musa-dsl 0.14.32 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/README.md +5 -1
  4. data/lib/musa-dsl.rb +54 -11
  5. data/lib/musa-dsl/core-ext.rb +7 -13
  6. data/lib/musa-dsl/core-ext/array-explode-ranges.rb +15 -23
  7. data/lib/musa-dsl/core-ext/arrayfy.rb +30 -12
  8. data/lib/musa-dsl/core-ext/attribute-builder.rb +194 -0
  9. data/lib/musa-dsl/core-ext/deep-copy.rb +185 -0
  10. data/lib/musa-dsl/core-ext/dynamic-proxy.rb +44 -40
  11. data/lib/musa-dsl/core-ext/inspect-nice.rb +40 -22
  12. data/lib/musa-dsl/core-ext/smart-proc-binder.rb +108 -0
  13. data/lib/musa-dsl/core-ext/with.rb +26 -0
  14. data/lib/musa-dsl/datasets.rb +8 -3
  15. data/lib/musa-dsl/datasets/dataset.rb +3 -0
  16. data/lib/musa-dsl/datasets/delta-d.rb +12 -0
  17. data/lib/musa-dsl/datasets/e.rb +61 -0
  18. data/lib/musa-dsl/datasets/gdv.rb +51 -411
  19. data/lib/musa-dsl/datasets/gdvd.rb +179 -0
  20. data/lib/musa-dsl/datasets/helper.rb +41 -0
  21. data/lib/musa-dsl/datasets/p.rb +68 -0
  22. data/lib/musa-dsl/datasets/packed-v.rb +19 -0
  23. data/lib/musa-dsl/datasets/pdv.rb +22 -15
  24. data/lib/musa-dsl/datasets/ps.rb +113 -0
  25. data/lib/musa-dsl/datasets/score.rb +210 -0
  26. data/lib/musa-dsl/datasets/score/queriable.rb +48 -0
  27. data/lib/musa-dsl/datasets/score/render.rb +31 -0
  28. data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +160 -0
  29. data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +51 -0
  30. data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +153 -0
  31. data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +158 -0
  32. data/lib/musa-dsl/datasets/v.rb +23 -0
  33. data/lib/musa-dsl/generative.rb +5 -5
  34. data/lib/musa-dsl/generative/backboner.rb +274 -0
  35. data/lib/musa-dsl/generative/darwin.rb +102 -96
  36. data/lib/musa-dsl/generative/generative-grammar.rb +182 -187
  37. data/lib/musa-dsl/generative/markov.rb +56 -53
  38. data/lib/musa-dsl/generative/variatio.rb +234 -222
  39. data/lib/musa-dsl/logger.rb +1 -0
  40. data/lib/musa-dsl/logger/logger.rb +31 -0
  41. data/lib/musa-dsl/matrix.rb +1 -0
  42. data/lib/musa-dsl/matrix/matrix.rb +210 -0
  43. data/lib/musa-dsl/midi.rb +2 -2
  44. data/lib/musa-dsl/midi/midi-recorder.rb +54 -52
  45. data/lib/musa-dsl/midi/midi-voices.rb +183 -182
  46. data/lib/musa-dsl/music.rb +5 -5
  47. data/lib/musa-dsl/music/chord-definition.rb +54 -50
  48. data/lib/musa-dsl/music/chord-definitions.rb +13 -9
  49. data/lib/musa-dsl/music/chords.rb +236 -238
  50. data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +187 -183
  51. data/lib/musa-dsl/music/scales.rb +331 -332
  52. data/lib/musa-dsl/musicxml.rb +1 -0
  53. data/lib/musa-dsl/musicxml/builder/attributes.rb +155 -0
  54. data/lib/musa-dsl/musicxml/builder/backup-forward.rb +45 -0
  55. data/lib/musa-dsl/musicxml/builder/direction.rb +322 -0
  56. data/lib/musa-dsl/musicxml/builder/helper.rb +90 -0
  57. data/lib/musa-dsl/musicxml/builder/measure.rb +137 -0
  58. data/lib/musa-dsl/musicxml/builder/note-complexities.rb +152 -0
  59. data/lib/musa-dsl/musicxml/builder/note.rb +577 -0
  60. data/lib/musa-dsl/musicxml/builder/part-group.rb +44 -0
  61. data/lib/musa-dsl/musicxml/builder/part.rb +67 -0
  62. data/lib/musa-dsl/musicxml/builder/pitched-note.rb +126 -0
  63. data/lib/musa-dsl/musicxml/builder/rest.rb +117 -0
  64. data/lib/musa-dsl/musicxml/builder/score-partwise.rb +120 -0
  65. data/lib/musa-dsl/musicxml/builder/typed-text.rb +43 -0
  66. data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +112 -0
  67. data/lib/musa-dsl/neumalang.rb +1 -1
  68. data/lib/musa-dsl/neumalang/datatypes.citrus +79 -0
  69. data/lib/musa-dsl/neumalang/neuma.citrus +165 -0
  70. data/lib/musa-dsl/neumalang/neumalang.citrus +32 -242
  71. data/lib/musa-dsl/neumalang/neumalang.rb +373 -142
  72. data/lib/musa-dsl/neumalang/process.citrus +21 -0
  73. data/lib/musa-dsl/neumalang/terminals.citrus +67 -0
  74. data/lib/musa-dsl/neumalang/vectors.citrus +23 -0
  75. data/lib/musa-dsl/neumas.rb +5 -0
  76. data/lib/musa-dsl/neumas/array-to-neumas.rb +34 -0
  77. data/lib/musa-dsl/neumas/neuma-decoder.rb +63 -0
  78. data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +57 -0
  79. data/lib/musa-dsl/neumas/neuma-gdvd-decoder.rb +15 -0
  80. data/lib/musa-dsl/neumas/neumas.rb +37 -0
  81. data/lib/musa-dsl/neumas/string-to-neumas.rb +33 -0
  82. data/lib/musa-dsl/repl.rb +1 -1
  83. data/lib/musa-dsl/repl/repl.rb +103 -110
  84. data/lib/musa-dsl/sequencer.rb +1 -1
  85. data/lib/musa-dsl/sequencer/base-sequencer-implementation-control.rb +163 -136
  86. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +301 -286
  87. data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +548 -321
  88. data/lib/musa-dsl/sequencer/base-sequencer-public.rb +198 -176
  89. data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +77 -0
  90. data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +75 -0
  91. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +105 -85
  92. data/lib/musa-dsl/sequencer/timeslots.rb +34 -0
  93. data/lib/musa-dsl/series.rb +1 -1
  94. data/lib/musa-dsl/{core-ext → series}/array-to-serie.rb +1 -1
  95. data/lib/musa-dsl/series/base-series.rb +171 -168
  96. data/lib/musa-dsl/series/hash-serie-splitter.rb +134 -132
  97. data/lib/musa-dsl/series/holder-serie.rb +1 -1
  98. data/lib/musa-dsl/series/main-serie-constructors.rb +6 -1
  99. data/lib/musa-dsl/series/main-serie-operations.rb +807 -797
  100. data/lib/musa-dsl/series/proxy-serie.rb +6 -6
  101. data/lib/musa-dsl/series/queue-serie.rb +5 -5
  102. data/lib/musa-dsl/series/series.rb +2 -0
  103. data/lib/musa-dsl/transcription.rb +4 -0
  104. data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +227 -0
  105. data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +36 -0
  106. data/lib/musa-dsl/transcription/from-gdv.rb +17 -0
  107. data/lib/musa-dsl/transcription/transcription.rb +55 -0
  108. data/lib/musa-dsl/transport.rb +6 -6
  109. data/lib/musa-dsl/transport/clock.rb +26 -26
  110. data/lib/musa-dsl/transport/dummy-clock.rb +32 -30
  111. data/lib/musa-dsl/transport/external-tick-clock.rb +21 -20
  112. data/lib/musa-dsl/transport/input-midi-clock.rb +82 -80
  113. data/lib/musa-dsl/transport/timer-clock.rb +72 -71
  114. data/lib/musa-dsl/transport/timer.rb +28 -26
  115. data/lib/musa-dsl/transport/transport.rb +100 -95
  116. data/musa-dsl.gemspec +3 -3
  117. metadata +73 -24
  118. data/lib/musa-dsl/core-ext/array-apply-get.rb +0 -18
  119. data/lib/musa-dsl/core-ext/array-to-neumas.rb +0 -28
  120. data/lib/musa-dsl/core-ext/as-context-run.rb +0 -44
  121. data/lib/musa-dsl/core-ext/duplicate.rb +0 -134
  122. data/lib/musa-dsl/core-ext/key-parameters-procedure-binder.rb +0 -85
  123. data/lib/musa-dsl/core-ext/proc-nice.rb +0 -13
  124. data/lib/musa-dsl/core-ext/send-nice.rb +0 -21
  125. data/lib/musa-dsl/core-ext/string-to-neumas.rb +0 -27
  126. data/lib/musa-dsl/datasets/gdv-decorators.rb +0 -221
  127. data/lib/musa-dsl/generative/rules.rb +0 -282
  128. data/lib/musa-dsl/neuma.rb +0 -1
  129. data/lib/musa-dsl/neuma/neuma.rb +0 -181
@@ -1,282 +0,0 @@
1
- require 'musa-dsl/core-ext/as-context-run'
2
- require 'musa-dsl/core-ext/key-parameters-procedure-binder'
3
-
4
- module Musa
5
- class Rules
6
- def initialize(&block)
7
- @context = RulesEvalContext.new.tap { |_| _._as_context_run block }
8
- end
9
-
10
- def generate_possibilities(object, confirmed_node = nil, node = nil, rules = nil)
11
- node ||= Node.new
12
- rules ||= @context._rules
13
-
14
- history = confirmed_node.history if confirmed_node
15
- history ||= []
16
-
17
- rules = rules.clone
18
- rule = rules.shift
19
-
20
- if rule
21
- rule.generate_possibilities(object, history).each do |new_object|
22
- new_node = Node.new new_object, node
23
- new_node.mark_as_ended! if @context._ended? new_object
24
-
25
- rejection = @context._rejections.find { |rejection| rejection.rejects?(new_object, history) }
26
- # TODO: include rejection secondary reasons in rejection message
27
-
28
- new_node.reject! rejection if rejection
29
-
30
- node.children << new_node
31
- end
32
- end
33
-
34
- unless rules.empty?
35
- node.children.each do |node|
36
- generate_possibilities node.object, confirmed_node, node, rules unless node.rejected || node.ended?
37
- end
38
- end
39
-
40
- node
41
- end
42
-
43
- def apply(object_or_list, node = nil)
44
- list = object_or_list.arrayfy.clone
45
-
46
- node ||= Node.new
47
-
48
- seed = list.shift
49
-
50
- if seed
51
- result = generate_possibilities seed, node
52
-
53
- fished = result.fish
54
-
55
- node.reject! 'All children are rejected' if fished.empty?
56
-
57
- fished.each do |object|
58
- subnode = node.add(object).mark_as_ended!
59
- apply list, subnode
60
- end
61
- end
62
-
63
- node
64
- end
65
-
66
- class RulesEvalContext
67
- attr_reader :_rules, :_ended_when, :_rejections
68
-
69
- def rule(name, &block)
70
- @_rules ||= []
71
- @_rules << Rule.new(name, self, block)
72
- self
73
- end
74
-
75
- def ended_when(&block)
76
- @_ended_when = block
77
- self
78
- end
79
-
80
- def rejection(reason, &block)
81
- @_rejections ||= []
82
- @_rejections << Rejection.new(reason, self, block)
83
- self
84
- end
85
-
86
- def _ended?(object)
87
- as_context_run @_ended_when, object
88
- end
89
-
90
- class Rule
91
- attr_reader :name
92
-
93
- def initialize(name, context, block)
94
- @name = name
95
- @context = context
96
- @block = block
97
- end
98
-
99
- def generate_possibilities(object, history)
100
- # TODO: optimize context using only one instance for all genereate_possibilities calls
101
- context = RuleEvalContext.new @context
102
- context.as_context_run @block, object, history
103
-
104
- context._possibilities
105
- end
106
-
107
- class RuleEvalContext
108
- attr_reader :_possibilities
109
-
110
- def initialize(parent_context)
111
- @_parent_context = parent_context
112
- @_possibilities = []
113
- end
114
-
115
- def possibility(object)
116
- @_possibilities << object
117
- self
118
- end
119
-
120
- private
121
-
122
- def method_missing(method_name, *args, **key_args, &block)
123
- if @_parent_context.respond_to? method_name
124
- @_parent_context.send_nice method_name, *args, **key_args, &block
125
- else
126
- super
127
- end
128
- end
129
-
130
- def respond_to_missing?(method_name, include_private)
131
- @_parent_context.respond_to?(method_name, include_private) || super
132
- end
133
- end
134
-
135
- private_constant :RuleEvalContext
136
- end
137
-
138
- private_constant :Rule
139
-
140
- class Rejection
141
- attr_reader :reason
142
-
143
- def initialize(reason, context = nil, block = nil)
144
- @reason = reason
145
- @context = context
146
- @block = block
147
- end
148
-
149
- def rejects?(object, history)
150
- # TODO: optimize context using only one instance for all rejects? checks
151
- context = RejectionEvalContext.new @context
152
- context.as_context_run @block, object, history
153
-
154
- reasons = context._secondary_reasons.collect { |_| ("#{@reason} (#{_})" if _) || @reason }
155
-
156
- reasons.empty? ? nil : reasons
157
- end
158
-
159
- class RejectionEvalContext
160
- attr_reader :_secondary_reasons
161
-
162
- def initialize(parent_context)
163
- @_parent_context = parent_context
164
- @_secondary_reasons = []
165
- end
166
-
167
- def reject(secondary_reason = nil)
168
- @_secondary_reasons << secondary_reason
169
- self
170
- end
171
-
172
- private
173
-
174
- def method_missing(method_name, *args, **key_args, &block)
175
- if @_parent_context.respond_to? method_name
176
- @_parent_context.send_nice method_name, *args, **key_args, &block
177
- else
178
- super
179
- end
180
- end
181
-
182
- def respond_to_missing?(method_name, include_private)
183
- @_parent_context.respond_to?(method_name, include_private) || super
184
- end
185
- end
186
-
187
- private_constant :RejectionEvalContext
188
- end
189
-
190
- private_constant :Rejection
191
- end
192
-
193
- private_constant :RulesEvalContext
194
-
195
- class Node
196
- attr_reader :parent, :children, :object, :rejected
197
-
198
- def initialize(object = nil, parent = nil)
199
- @parent = parent
200
- @children = []
201
- @object = object
202
-
203
- @ended = false
204
- @rejected = nil
205
- end
206
-
207
- def add(object)
208
- Node.new(object, self).tap { |n| @children << n }
209
- end
210
-
211
- def reject!(rejection)
212
- @rejected = rejection
213
- self
214
- end
215
-
216
- def mark_as_ended!
217
- @children.each(&:update_rejection_by_children!)
218
-
219
- if !@children.empty? && !@children.find { |n| !n.rejected }
220
- reject! Rejection::AllChildrenRejected
221
- end
222
-
223
- @ended = true
224
-
225
- self
226
- end
227
-
228
- def ended?
229
- @ended
230
- end
231
-
232
- def history
233
- objects = []
234
- n = self
235
- while n && n.object
236
- objects << n.object
237
- n = n.parent
238
- end
239
-
240
- objects.reverse
241
- end
242
-
243
- def fish
244
- fished = []
245
-
246
- @children.each do |node|
247
- unless node.rejected
248
- if node.ended?
249
- fished << node.object
250
- else
251
- fished += node.fish
252
- end
253
- end
254
- end
255
-
256
- fished
257
- end
258
-
259
- def combinations(parent_combination = nil)
260
- parent_combination ||= []
261
-
262
- combinations = []
263
-
264
- unless rejected
265
- if @children.empty?
266
- combinations << parent_combination
267
- else
268
- @children.each do |node|
269
- node.combinations(parent_combination + [node.object]).each do |object|
270
- combinations << object
271
- end
272
- end
273
- end
274
- end
275
-
276
- combinations
277
- end
278
- end
279
-
280
- private_constant :Node
281
- end
282
- end
@@ -1 +0,0 @@
1
- require 'musa-dsl/neuma/neuma'
@@ -1,181 +0,0 @@
1
- module Musa::Neumalang
2
- module Neumas # Neumas serie
3
- # TODO implementar | ???? neumas | neumas = parallel neumas, no?
4
- end
5
-
6
- module Neuma
7
- module Parallel
8
- include Neuma
9
- end
10
-
11
- def |(other)
12
- if is_a?(Parallel)
13
- clone.tap { |_| _[:parallel] << convert_to_parallel_element(other) }.extend(Parallel)
14
- else
15
- { kind: :parallel,
16
- parallel: [clone, convert_to_parallel_element(other)]
17
- }.extend(Parallel)
18
- end
19
- end
20
-
21
- private
22
-
23
- def convert_to_parallel_element(e)
24
- case e
25
- when String then { kind: :serie, serie: e.to_neumas }.extend(Neuma)
26
- else
27
- raise ArgumentError, "Dont know how to convert to neuma #{e}"
28
- end
29
- end
30
- end
31
-
32
- module Dataset
33
- class Decorator
34
- def process(element, base_duration:, tick_duration:)
35
- element
36
- end
37
-
38
- def check(value_or_array, &block)
39
- if block_given?
40
- if value_or_array.is_a?(Array)
41
- value_or_array.each { |value| yield value }
42
- else
43
- yield value_or_array
44
- end
45
- end
46
- end
47
- end
48
-
49
- class TwoNeumasDecorator < Decorator
50
- def process(element1, element2, base_duration:, tick_duration:)
51
- element2
52
- end
53
- end
54
-
55
- class Decorators
56
- attr_reader :decorators
57
- attr_accessor :appogiatura_decorator
58
-
59
- def initialize(*decorators, appogiatura_decorator: nil, base_duration: nil, tick_duration: nil)
60
- @base_duration = 1/4r
61
- @tick_duration = tick_duration || 1/96r
62
-
63
- @appogiatura_decorator = appogiatura_decorator
64
- @decorators = decorators
65
- end
66
-
67
- def process(element)
68
- if @appogiatura_decorator
69
- element = @appogiatura_decorator.process(element, base_duration: @base_duration, tick_duration: @tick_duration)
70
- end
71
-
72
- @decorators.each do |processor|
73
- if element
74
- if element.is_a?(Array)
75
- element = element.collect { |element_i| processor.process(element_i, base_duration: @base_duration, tick_duration: @tick_duration) }.flatten(1)
76
- else
77
- element = processor.process(element, base_duration: @base_duration, tick_duration: @tick_duration)
78
- end
79
- end
80
- end
81
-
82
- element
83
- end
84
- end
85
-
86
- protected
87
-
88
- def positive_sign_of(x)
89
- x >= 0 ? '+' : ''
90
- end
91
-
92
- def sign_of(x)
93
- '++-'[x <=> 0]
94
- end
95
-
96
- def velocity_of(x)
97
- %w[ppp pp p mp mf f ff fff][x + 3]
98
- end
99
-
100
- def modificator_string(modificator, parameter_or_parameters)
101
- case parameter_or_parameters
102
- when true
103
- modificator.to_s
104
- when Array
105
- "#{modificator.to_s}(#{parameter_or_parameters.collect { |p| parameter_to_string(p) }.join(', ')})"
106
- else
107
- "#{modificator.to_s}(#{parameter_to_string(parameter_or_parameters)})"
108
- end
109
- end
110
-
111
- private
112
-
113
- def parameter_to_string(parameter)
114
- case parameter
115
- when String
116
- "\"#{parameter}\""
117
- when Numeric
118
- "#{parameter}"
119
- when Symbol
120
- "#{parameter}"
121
- end
122
- end
123
- end
124
-
125
- class ProtoDecoder
126
- def subcontext
127
- self
128
- end
129
-
130
- def decode(_element)
131
- raise NotImplementedError
132
- end
133
- end
134
-
135
- class DifferentialDecoder < ProtoDecoder
136
- def decode(attributes)
137
- parse attributes
138
- end
139
-
140
- def parse(_attributes)
141
- raise NotImplementedError
142
- end
143
- end
144
-
145
- class Decoder < DifferentialDecoder
146
- def initialize(base, processor: nil)
147
- @base = base
148
- @last = base.clone
149
-
150
- @processor = processor
151
- end
152
-
153
- attr_accessor :processor
154
- attr_reader :base
155
-
156
- def base=(base)
157
- @base = base
158
- @last = base.clone
159
- end
160
-
161
- def subcontext
162
- Decoder.new @base
163
- end
164
-
165
- def decode(attributes)
166
- result = apply parse(attributes), on: @last
167
-
168
- @last = result.clone
169
-
170
- if @processor
171
- @processor.process(result)
172
- else
173
- result
174
- end
175
- end
176
-
177
- def apply(_action, on:)
178
- raise NotImplementedError
179
- end
180
- end
181
- end