musa-dsl 0.14.16

Sign up to get free protection for your applications and to get access to all the features.
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