musa-dsl 0.14.16

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 (72) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/Gemfile +20 -0
  4. data/LICENSE.md +157 -0
  5. data/README.md +8 -0
  6. data/lib/musa-dsl/core-ext/array-apply-get.rb +18 -0
  7. data/lib/musa-dsl/core-ext/array-explode-ranges.rb +29 -0
  8. data/lib/musa-dsl/core-ext/array-to-neumas.rb +28 -0
  9. data/lib/musa-dsl/core-ext/array-to-serie.rb +20 -0
  10. data/lib/musa-dsl/core-ext/arrayfy.rb +15 -0
  11. data/lib/musa-dsl/core-ext/as-context-run.rb +44 -0
  12. data/lib/musa-dsl/core-ext/duplicate.rb +134 -0
  13. data/lib/musa-dsl/core-ext/dynamic-proxy.rb +55 -0
  14. data/lib/musa-dsl/core-ext/inspect-nice.rb +28 -0
  15. data/lib/musa-dsl/core-ext/key-parameters-procedure-binder.rb +85 -0
  16. data/lib/musa-dsl/core-ext/proc-nice.rb +13 -0
  17. data/lib/musa-dsl/core-ext/send-nice.rb +21 -0
  18. data/lib/musa-dsl/core-ext/string-to-neumas.rb +27 -0
  19. data/lib/musa-dsl/core-ext.rb +13 -0
  20. data/lib/musa-dsl/datasets/gdv-decorators.rb +221 -0
  21. data/lib/musa-dsl/datasets/gdv.rb +499 -0
  22. data/lib/musa-dsl/datasets/pdv.rb +44 -0
  23. data/lib/musa-dsl/datasets.rb +5 -0
  24. data/lib/musa-dsl/generative/darwin.rb +145 -0
  25. data/lib/musa-dsl/generative/generative-grammar.rb +294 -0
  26. data/lib/musa-dsl/generative/markov.rb +78 -0
  27. data/lib/musa-dsl/generative/rules.rb +282 -0
  28. data/lib/musa-dsl/generative/variatio.rb +331 -0
  29. data/lib/musa-dsl/generative.rb +5 -0
  30. data/lib/musa-dsl/midi/midi-recorder.rb +83 -0
  31. data/lib/musa-dsl/midi/midi-voices.rb +274 -0
  32. data/lib/musa-dsl/midi.rb +2 -0
  33. data/lib/musa-dsl/music/chord-definition.rb +99 -0
  34. data/lib/musa-dsl/music/chord-definitions.rb +13 -0
  35. data/lib/musa-dsl/music/chords.rb +326 -0
  36. data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +204 -0
  37. data/lib/musa-dsl/music/scales.rb +584 -0
  38. data/lib/musa-dsl/music.rb +6 -0
  39. data/lib/musa-dsl/neuma/neuma.rb +181 -0
  40. data/lib/musa-dsl/neuma.rb +1 -0
  41. data/lib/musa-dsl/neumalang/neumalang.citrus +294 -0
  42. data/lib/musa-dsl/neumalang/neumalang.rb +179 -0
  43. data/lib/musa-dsl/neumalang.rb +3 -0
  44. data/lib/musa-dsl/repl/repl.rb +143 -0
  45. data/lib/musa-dsl/repl.rb +1 -0
  46. data/lib/musa-dsl/sequencer/base-sequencer-implementation-control.rb +189 -0
  47. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +354 -0
  48. data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +382 -0
  49. data/lib/musa-dsl/sequencer/base-sequencer-public.rb +261 -0
  50. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +94 -0
  51. data/lib/musa-dsl/sequencer/sequencer.rb +3 -0
  52. data/lib/musa-dsl/sequencer.rb +1 -0
  53. data/lib/musa-dsl/series/base-series.rb +245 -0
  54. data/lib/musa-dsl/series/hash-serie-splitter.rb +194 -0
  55. data/lib/musa-dsl/series/holder-serie.rb +87 -0
  56. data/lib/musa-dsl/series/main-serie-constructors.rb +726 -0
  57. data/lib/musa-dsl/series/main-serie-operations.rb +1151 -0
  58. data/lib/musa-dsl/series/proxy-serie.rb +69 -0
  59. data/lib/musa-dsl/series/queue-serie.rb +94 -0
  60. data/lib/musa-dsl/series/series.rb +8 -0
  61. data/lib/musa-dsl/series.rb +1 -0
  62. data/lib/musa-dsl/transport/clock.rb +36 -0
  63. data/lib/musa-dsl/transport/dummy-clock.rb +47 -0
  64. data/lib/musa-dsl/transport/external-tick-clock.rb +31 -0
  65. data/lib/musa-dsl/transport/input-midi-clock.rb +124 -0
  66. data/lib/musa-dsl/transport/timer-clock.rb +102 -0
  67. data/lib/musa-dsl/transport/timer.rb +40 -0
  68. data/lib/musa-dsl/transport/transport.rb +137 -0
  69. data/lib/musa-dsl/transport.rb +9 -0
  70. data/lib/musa-dsl.rb +17 -0
  71. data/musa-dsl.gemspec +17 -0
  72. metadata +174 -0
@@ -0,0 +1,21 @@
1
+ class Object
2
+ def send_nice(method_name, *args, **key_args, &block)
3
+ _send_nice method_name, args, key_args, &block
4
+ end
5
+
6
+ def _send_nice(method_name, args, key_args, &block)
7
+ if args && !args.empty?
8
+ if key_args && !key_args.empty?
9
+ send method_name, *args, **key_args, &block
10
+ else
11
+ send method_name, *args, &block
12
+ end
13
+ else
14
+ if key_args && !key_args.empty?
15
+ send method_name, **key_args, &block
16
+ else
17
+ send method_name, &block
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ require 'musa-dsl/neumalang'
2
+ require 'musa-dsl/generative/generative-grammar'
3
+
4
+ class String
5
+ def to_neumas(language: nil, decode_with: nil, debug: nil)
6
+ Musa::Neumalang.parse(self, language: language, decode_with: decode_with, debug: debug)
7
+ end
8
+
9
+ def to_neumas_to_node(language: nil, decode_with: nil, debug: nil)
10
+ to_neumas(language: language, decode_with: decode_with, debug: debug).to_node
11
+ end
12
+
13
+ def |(other)
14
+ case other
15
+ when String
16
+ { kind: :parallel,
17
+ parallel: [{ kind: :serie, serie: self.to_neumas },
18
+ { kind: :serie, serie: other.to_neumas }] }.extend(Musa::Neumalang::Neuma::Parallel)
19
+ else
20
+ raise ArgumentError, "Don't know how to parallelize #{other}"
21
+ end
22
+ end
23
+
24
+ alias_method :neumas, :to_neumas
25
+ alias_method :n, :to_neumas
26
+ alias_method :nn, :to_neumas_to_node
27
+ end
@@ -0,0 +1,13 @@
1
+ require 'musa-dsl/core-ext/array-apply-get'
2
+ require 'musa-dsl/core-ext/array-explode-ranges'
3
+ require 'musa-dsl/core-ext/array-to-serie'
4
+ require 'musa-dsl/core-ext/string-to-neumas'
5
+ require 'musa-dsl/core-ext/array-to-neumas'
6
+ require 'musa-dsl/core-ext/arrayfy'
7
+ require 'musa-dsl/core-ext/duplicate'
8
+ require 'musa-dsl/core-ext/key-parameters-procedure-binder'
9
+ require 'musa-dsl/core-ext/as-context-run'
10
+ require 'musa-dsl/core-ext/inspect-nice'
11
+ require 'musa-dsl/core-ext/send-nice'
12
+ require 'musa-dsl/core-ext/proc-nice'
13
+ require 'musa-dsl/core-ext/dynamic-proxy'
@@ -0,0 +1,221 @@
1
+ module Musa::Datasets::GDV
2
+
3
+ # Process: appogiatura (neuma)neuma
4
+ class AppogiaturaDecorator < TwoNeumasDecorator
5
+ def process(gdv, base_duration:, tick_duration:)
6
+ if gdv_appogiatura = gdv[:appogiatura]
7
+ gdv.delete :appogiatura
8
+
9
+ # TODO process with Decorators the gdv_appogiatura
10
+ # TODO implement also posterior appogiatura neuma(neuma)
11
+ # TODO implement also multiple appogiatura with several notes (neuma neuma)neuma or neuma(neuma neuma)
12
+
13
+ gdv[:duration] = gdv[:duration] - gdv_appogiatura[:duration]
14
+
15
+ [ gdv_appogiatura, gdv ]
16
+ else
17
+ gdv
18
+ end
19
+ end
20
+ end
21
+
22
+ # Process: .mor
23
+ class MordentDecorator < Decorator
24
+ def initialize(duration_factor: nil)
25
+ @duration_factor = duration_factor || 1/4r
26
+ end
27
+
28
+ def process(gdv, base_duration:, tick_duration:)
29
+ mor = gdv.delete :mor
30
+
31
+ if mor
32
+ direction = :up
33
+
34
+ check(mor) do |mor|
35
+ case mor
36
+ when true, :up
37
+ direction = :up
38
+ when :down, :low
39
+ direction = :down
40
+ end
41
+ end
42
+
43
+ short_duration = [base_duration * @duration_factor, tick_duration].max
44
+
45
+ gdvs = []
46
+
47
+ gdvs << gdv.clone.tap { |gdv| gdv[:duration] = short_duration }
48
+
49
+ case direction
50
+ when :up
51
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 1; gdv[:duration] = short_duration }
52
+ when :down
53
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] -= 1; gdv[:duration] = short_duration }
54
+ end
55
+
56
+ gdvs << gdv.clone.tap { |gdv| gdv[:duration] -= 2 * short_duration }
57
+
58
+ gdvs
59
+ else
60
+ gdv
61
+ end
62
+ end
63
+ end
64
+
65
+ # Process: .turn
66
+ class TurnDecorator < Decorator
67
+ def process(gdv, base_duration:, tick_duration:)
68
+ turn = gdv.delete :turn
69
+
70
+ if turn
71
+ start = :up
72
+
73
+ check(turn) do |turn|
74
+ case turn
75
+ when :true, :up
76
+ start = :up
77
+ when :down, :low
78
+ start = :down
79
+ end
80
+ end
81
+
82
+ duration = gdv[:duration] / 4r
83
+
84
+ gdvs = []
85
+
86
+ case start
87
+ when :up
88
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 1; gdv[:duration] = duration }
89
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 0; gdv[:duration] = duration }
90
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += -1; gdv[:duration] = duration }
91
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 0; gdv[:duration] = duration }
92
+ when :down
93
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += -1; gdv[:duration] = duration }
94
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 0; gdv[:duration] = duration }
95
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 1; gdv[:duration] = duration }
96
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 0; gdv[:duration] = duration }
97
+ end
98
+
99
+ gdvs
100
+ else
101
+ gdv
102
+ end
103
+ end
104
+ end
105
+
106
+ # Process: .tr
107
+ class TrillDecorator < Decorator
108
+ def initialize(duration_factor: nil)
109
+ @duration_factor = duration_factor || 1/4r
110
+ end
111
+
112
+ def process(gdv, base_duration:, tick_duration:)
113
+ if gdv[:tr]
114
+ tr = gdv.delete :tr
115
+
116
+ note_duration = base_duration * @duration_factor
117
+
118
+ check(tr) do |tr|
119
+ case tr
120
+ when Numeric # duration factor
121
+ note_duration *= base_duration * tr.to_r
122
+ end
123
+ end
124
+
125
+ used_duration = 0r
126
+ last = nil
127
+
128
+ gdvs = []
129
+
130
+ check(tr) do |tr|
131
+ case tr
132
+ when :low # start with lower note
133
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = -1); gdv[:duration] = note_duration }
134
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }
135
+ used_duration += 2 * note_duration
136
+
137
+ when :low2 # start with upper note but go to lower note once
138
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 1); gdv[:duration] = note_duration }
139
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }
140
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = -1); gdv[:duration] = note_duration }
141
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }
142
+ used_duration += 4 * note_duration
143
+
144
+ when :same # start with the same note
145
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }
146
+ used_duration += note_duration
147
+ end
148
+ end
149
+
150
+ 2.times do
151
+ if used_duration + 2 * note_duration <= gdv[:duration]
152
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 1); gdv[:duration] = note_duration }
153
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }
154
+
155
+ used_duration += 2 * note_duration
156
+ end
157
+ end
158
+
159
+ while used_duration + 2 * note_duration * 2/3r <= gdv[:duration]
160
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 1); gdv[:duration] = note_duration * 2/3r }
161
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration * 2/3r }
162
+
163
+ used_duration += 2 * note_duration * 2/3r
164
+ end
165
+
166
+ duration_diff = gdv[:duration] - used_duration
167
+ if duration_diff >= note_duration
168
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 1); gdv[:duration] = duration_diff / 2 }
169
+ gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = duration_diff / 2 }
170
+
171
+ elsif duration_diff > 0
172
+ gdvs[-1][:duration] += duration_diff / 2
173
+ gdvs[-2][:duration] += duration_diff / 2
174
+ end
175
+
176
+ gdvs
177
+ else
178
+ gdv
179
+ end
180
+ end
181
+ end
182
+
183
+ # Process: .st .st(1) .st(2) .st(3): staccato level 1 2 3
184
+ class StaccatoDecorator < Decorator
185
+ def initialize(min_duration_factor: nil)
186
+ @min_duration_factor = min_duration_factor || 1/8r
187
+ end
188
+
189
+ def process(gdv, base_duration:, tick_duration:)
190
+ st = gdv.delete :st
191
+
192
+ if st
193
+ calculated = 0
194
+
195
+ check(st) do |st|
196
+ case st
197
+ when true
198
+ calculated = gdv[:duration] / 2r
199
+ when Numeric
200
+ calculated = gdv[:duration] / 2**st if st >= 1
201
+ end
202
+ end
203
+
204
+ gdv[:effective_duration] = [calculated, base_duration * @min_duration_factor].max
205
+ end
206
+
207
+ gdv
208
+ end
209
+ end
210
+
211
+ # Process: .base .b
212
+ class BaseDecorator < Decorator
213
+ def process(gdv, base_duration:, tick_duration:)
214
+ base = gdv.delete :base
215
+ base ||= gdv.delete :b
216
+
217
+ base ? { duration: 0 }.extend(Musa::Datasets::GDV) : gdv
218
+ end
219
+ end
220
+
221
+ end