musa-dsl 0.30.2 → 0.40.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.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.version +6 -0
  4. data/.yardopts +7 -0
  5. data/README.md +227 -6
  6. data/docs/README.md +83 -0
  7. data/docs/api-reference.md +86 -0
  8. data/docs/getting-started/quick-start.md +93 -0
  9. data/docs/getting-started/tutorial.md +58 -0
  10. data/docs/subsystems/core-extensions.md +316 -0
  11. data/docs/subsystems/datasets.md +465 -0
  12. data/docs/subsystems/generative.md +290 -0
  13. data/docs/subsystems/matrix.md +63 -0
  14. data/docs/subsystems/midi.md +123 -0
  15. data/docs/subsystems/music.md +233 -0
  16. data/docs/subsystems/musicxml-builder.md +264 -0
  17. data/docs/subsystems/neumas.md +71 -0
  18. data/docs/subsystems/repl.md +135 -0
  19. data/docs/subsystems/sequencer.md +98 -0
  20. data/docs/subsystems/series.md +302 -0
  21. data/docs/subsystems/transcription.md +152 -0
  22. data/docs/subsystems/transport.md +177 -0
  23. data/lib/musa-dsl/core-ext/array-explode-ranges.rb +68 -0
  24. data/lib/musa-dsl/core-ext/arrayfy.rb +110 -0
  25. data/lib/musa-dsl/core-ext/attribute-builder.rb +91 -30
  26. data/lib/musa-dsl/core-ext/deep-copy.rb +125 -2
  27. data/lib/musa-dsl/core-ext/dynamic-proxy.rb +78 -0
  28. data/lib/musa-dsl/core-ext/extension.rb +53 -0
  29. data/lib/musa-dsl/core-ext/hashify.rb +162 -1
  30. data/lib/musa-dsl/core-ext/inspect-nice.rb +154 -0
  31. data/lib/musa-dsl/core-ext/smart-proc-binder.rb +117 -0
  32. data/lib/musa-dsl/core-ext/with.rb +114 -0
  33. data/lib/musa-dsl/datasets/dataset.rb +109 -0
  34. data/lib/musa-dsl/datasets/delta-d.rb +78 -0
  35. data/lib/musa-dsl/datasets/e.rb +186 -2
  36. data/lib/musa-dsl/datasets/gdv.rb +279 -2
  37. data/lib/musa-dsl/datasets/gdvd.rb +201 -0
  38. data/lib/musa-dsl/datasets/helper.rb +75 -0
  39. data/lib/musa-dsl/datasets/p.rb +177 -2
  40. data/lib/musa-dsl/datasets/packed-v.rb +91 -0
  41. data/lib/musa-dsl/datasets/pdv.rb +136 -1
  42. data/lib/musa-dsl/datasets/ps.rb +134 -4
  43. data/lib/musa-dsl/datasets/score/queriable.rb +143 -1
  44. data/lib/musa-dsl/datasets/score/render.rb +105 -1
  45. data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +138 -1
  46. data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +111 -0
  47. data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +200 -1
  48. data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +145 -1
  49. data/lib/musa-dsl/datasets/score.rb +279 -0
  50. data/lib/musa-dsl/datasets/v.rb +88 -0
  51. data/lib/musa-dsl/generative/darwin.rb +180 -1
  52. data/lib/musa-dsl/generative/generative-grammar.rb +359 -0
  53. data/lib/musa-dsl/generative/markov.rb +133 -3
  54. data/lib/musa-dsl/generative/rules.rb +258 -4
  55. data/lib/musa-dsl/generative/variatio.rb +217 -2
  56. data/lib/musa-dsl/logger/logger.rb +267 -2
  57. data/lib/musa-dsl/matrix/matrix.rb +256 -10
  58. data/lib/musa-dsl/midi/midi-recorder.rb +108 -1
  59. data/lib/musa-dsl/midi/midi-voices.rb +265 -4
  60. data/lib/musa-dsl/music/chord-definition.rb +233 -1
  61. data/lib/musa-dsl/music/chord-definitions.rb +33 -6
  62. data/lib/musa-dsl/music/chords.rb +308 -2
  63. data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +315 -0
  64. data/lib/musa-dsl/music/scales.rb +957 -40
  65. data/lib/musa-dsl/musicxml/builder/attributes.rb +483 -3
  66. data/lib/musa-dsl/musicxml/builder/backup-forward.rb +166 -1
  67. data/lib/musa-dsl/musicxml/builder/direction.rb +243 -0
  68. data/lib/musa-dsl/musicxml/builder/helper.rb +240 -0
  69. data/lib/musa-dsl/musicxml/builder/measure.rb +284 -0
  70. data/lib/musa-dsl/musicxml/builder/note-complexities.rb +324 -8
  71. data/lib/musa-dsl/musicxml/builder/note.rb +285 -0
  72. data/lib/musa-dsl/musicxml/builder/part-group.rb +108 -1
  73. data/lib/musa-dsl/musicxml/builder/part.rb +139 -0
  74. data/lib/musa-dsl/musicxml/builder/pitched-note.rb +124 -0
  75. data/lib/musa-dsl/musicxml/builder/rest.rb +93 -0
  76. data/lib/musa-dsl/musicxml/builder/score-partwise.rb +276 -0
  77. data/lib/musa-dsl/musicxml/builder/typed-text.rb +62 -1
  78. data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +83 -0
  79. data/lib/musa-dsl/neumalang/neumalang.rb +675 -0
  80. data/lib/musa-dsl/neumas/array-to-neumas.rb +149 -0
  81. data/lib/musa-dsl/neumas/neuma-decoder.rb +253 -0
  82. data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +142 -2
  83. data/lib/musa-dsl/neumas/neuma-gdvd-decoder.rb +82 -0
  84. data/lib/musa-dsl/neumas/neumas.rb +67 -0
  85. data/lib/musa-dsl/neumas/string-to-neumas.rb +233 -1
  86. data/lib/musa-dsl/repl/repl.rb +550 -0
  87. data/lib/musa-dsl/sequencer/base-sequencer-implementation-every.rb +118 -2
  88. data/lib/musa-dsl/sequencer/base-sequencer-implementation-move.rb +149 -2
  89. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +296 -0
  90. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +88 -2
  91. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb +161 -0
  92. data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +263 -0
  93. data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +173 -1
  94. data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +177 -0
  95. data/lib/musa-dsl/sequencer/base-sequencer.rb +710 -10
  96. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +210 -0
  97. data/lib/musa-dsl/sequencer/timeslots.rb +79 -0
  98. data/lib/musa-dsl/series/array-to-serie.rb +37 -1
  99. data/lib/musa-dsl/series/base-series.rb +843 -5
  100. data/lib/musa-dsl/series/buffer-serie.rb +48 -0
  101. data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +41 -0
  102. data/lib/musa-dsl/series/main-serie-constructors.rb +398 -2
  103. data/lib/musa-dsl/series/main-serie-operations.rb +538 -16
  104. data/lib/musa-dsl/series/proxy-serie.rb +67 -0
  105. data/lib/musa-dsl/series/quantizer-serie.rb +45 -7
  106. data/lib/musa-dsl/series/queue-serie.rb +65 -0
  107. data/lib/musa-dsl/series/series-composer.rb +701 -0
  108. data/lib/musa-dsl/series/timed-serie.rb +473 -28
  109. data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +404 -1
  110. data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +118 -0
  111. data/lib/musa-dsl/transcription/from-gdv.rb +84 -1
  112. data/lib/musa-dsl/transcription/transcription.rb +265 -0
  113. data/lib/musa-dsl/transport/clock.rb +125 -0
  114. data/lib/musa-dsl/transport/dummy-clock.rb +89 -2
  115. data/lib/musa-dsl/transport/external-tick-clock.rb +91 -0
  116. data/lib/musa-dsl/transport/input-midi-clock.rb +133 -1
  117. data/lib/musa-dsl/transport/timer-clock.rb +183 -1
  118. data/lib/musa-dsl/transport/timer.rb +83 -0
  119. data/lib/musa-dsl/transport/transport.rb +318 -0
  120. data/lib/musa-dsl/version.rb +1 -1
  121. data/lib/musa-dsl.rb +132 -25
  122. data/musa-dsl.gemspec +12 -10
  123. metadata +87 -8
@@ -0,0 +1,316 @@
1
+ # Core Extensions - Advanced Metaprogramming
2
+
3
+ **Note for Advanced Users:** This section covers low-level Ruby refinements and metaprogramming utilities that form the foundation of MusaDSL's flexible syntax. These tools are primarily intended for users who want to extend the DSL, create custom builders, or integrate Musa DSL deeply into their own frameworks.
4
+
5
+ Core Extensions provide Ruby refinements and metaprogramming utilities that enable MusaDSL's flexible DSL syntax. These are the building blocks used throughout the framework.
6
+
7
+ ## Ruby Refinements & Metaprogramming
8
+
9
+ **Arrayfy & Hashify** - Parameter Normalization:
10
+
11
+ Convert any object to array or hash with specified keys. Essential for flexible DSL method signatures.
12
+
13
+ ```ruby
14
+ require 'musa-dsl'
15
+
16
+ using Musa::Extension::Arrayfy
17
+ using Musa::Extension::Hashify
18
+
19
+ # Arrayfy: ensure parameter is array
20
+ value = 42
21
+ value.arrayfy # => [42]
22
+
23
+ array = [1, 2, 3]
24
+ array.arrayfy # => [1, 2, 3] (already array, unchanged)
25
+
26
+ # Hashify: convert to hash with specified keys
27
+ data = [60, 1r, 80]
28
+ data.hashify(:pitch, :duration, :velocity)
29
+ # => { pitch: 60, duration: 1r, velocity: 80 }
30
+
31
+ # Works with hashes (validates keys)
32
+ existing = { pitch: 64, duration: 1r }
33
+ existing.hashify(:pitch, :duration, :velocity)
34
+ # => { pitch: 64, duration: 1r, velocity: nil }
35
+ ```
36
+
37
+ **ExplodeRanges** - Range Expansion:
38
+
39
+ Expand Range objects within arrays, useful for parameter generation.
40
+
41
+ ```ruby
42
+ require 'musa-dsl'
43
+
44
+ using Musa::Extension::ExplodeRanges
45
+
46
+ # Expand ranges in arrays
47
+ [0, 2..4, 7].explode_ranges
48
+ # => [0, 2, 3, 4, 7]
49
+
50
+ # Works with nested structures
51
+ [1, 3..5, [10, 12..14]].explode_ranges
52
+ # => [1, 3, 4, 5, [10, 12, 13, 14]]
53
+
54
+ # Useful for pitch collections
55
+ chord = [60, 64..67, 72].explode_ranges
56
+ # => [60, 64, 65, 66, 67, 72]
57
+ ```
58
+
59
+ **DeepCopy** - Deep Object Cloning:
60
+
61
+ Create deep copies of objects with circular reference handling and singleton module preservation.
62
+
63
+ ```ruby
64
+ require 'musa-dsl'
65
+
66
+ using Musa::Extension::DeepCopy
67
+
68
+ original = { pitch: 60, envelope: { attack: 0.1, decay: 0.2 } }
69
+ copy = original.deep_copy
70
+
71
+ copy[:envelope][:attack] = 0.5
72
+
73
+ original[:envelope][:attack] # => 0.1 (unchanged)
74
+ copy[:envelope][:attack] # => 0.5 (modified)
75
+
76
+ # Preserves singleton modules (dataset types)
77
+ gdv = { grade: 0, duration: 1r }.extend(Musa::Datasets::GDV)
78
+ gdv_copy = gdv.deep_copy
79
+
80
+ gdv_copy.is_a?(Musa::Datasets::GDV) # => true (module preserved)
81
+ ```
82
+
83
+ **SmartProcBinder** - Intelligent Parameter Binding:
84
+
85
+ Automatically match Proc parameters with available values, enabling flexible block signatures in DSL methods.
86
+
87
+ ```ruby
88
+ require 'musa-dsl'
89
+
90
+ # SmartProcBinder is used internally by Series operations
91
+ # to match block parameters flexibly
92
+
93
+ using Musa::Extension::SmartProcBinder
94
+
95
+ # Example: .with operation uses SmartProcBinder
96
+ pitches = S(60, 64, 67)
97
+ durations = S(1r, 1/2r, 1/4r)
98
+
99
+ # Block can request any combination of parameters
100
+ notes = pitches.with(dur: durations) do |p, dur:|
101
+ { pitch: p, duration: dur }
102
+ end
103
+
104
+ # SmartProcBinder matches 'p' to pitch value, 'dur:' to duration value
105
+ # regardless of parameter order or naming
106
+ ```
107
+
108
+ **DynamicProxy** - Lazy Initialization Pattern:
109
+
110
+ Forward method calls to a lazily-initialized target. Used for deferred object creation.
111
+
112
+ ```ruby
113
+ require 'musa-dsl'
114
+
115
+ # DynamicProxy is used internally for lazy series evaluation
116
+ # and deferred resource allocation
117
+
118
+ # Example: Proxy pattern for expensive resource
119
+ class ExpensiveResource
120
+ def initialize
121
+ puts "Initializing expensive resource..."
122
+ @data = (1..1000000).to_a
123
+ end
124
+
125
+ def process
126
+ puts "Processing..."
127
+ end
128
+ end
129
+
130
+ # Create proxy (doesn't initialize resource yet)
131
+ proxy = Musa::Extension::DynamicProxy::DynamicProxy.new(ExpensiveResource)
132
+
133
+ # Resource is created only when first method is called
134
+ proxy.process # Outputs: "Initializing expensive resource..." then "Processing..."
135
+ proxy.process # Only outputs: "Processing..." (resource already initialized)
136
+ ```
137
+
138
+ **With** - Flexible Block Execution:
139
+
140
+ Execute blocks with flexible context switching (instance_eval vs call with self). Core utility for DSL builders.
141
+
142
+ ```ruby
143
+ require 'musa-dsl'
144
+
145
+ using Musa::Extension::With
146
+
147
+ # Used internally by DSL builders to execute configuration blocks
148
+ # Can switch between instance_eval (DSL style) and block.call (parameter style)
149
+
150
+ class Builder
151
+ def initialize(&block)
152
+ @items = []
153
+ # Execute block in builder context using With
154
+ self.with &block
155
+ end
156
+
157
+ def item(name)
158
+ @items << name
159
+ end
160
+
161
+ def items
162
+ @items
163
+ end
164
+ end
165
+
166
+ # DSL-style block (instance_eval)
167
+ builder = Builder.new do
168
+ item "first"
169
+ item "second"
170
+ end
171
+
172
+ builder.items # => ["first", "second"]
173
+ ```
174
+
175
+ **AttributeBuilder** - DSL Builder Macros:
176
+
177
+ Metaprogramming macros for creating DSL builder patterns. Automatically generates setter and getter methods.
178
+
179
+ ```ruby
180
+ require 'musa-dsl'
181
+
182
+ # AttributeBuilder is used internally by MusicXML Builder and other DSL components
183
+
184
+ class SynthConfig
185
+ include Musa::Extension::AttributeBuilder
186
+
187
+ # Define DSL attributes
188
+ attribute :waveform
189
+ attribute :frequency
190
+ attribute :amplitude
191
+
192
+ def initialize(&block)
193
+ self.with &block if block
194
+ end
195
+ end
196
+
197
+ # Use DSL to configure
198
+ synth = SynthConfig.new do
199
+ waveform :sine
200
+ frequency 440
201
+ amplitude 0.8
202
+ end
203
+
204
+ synth.waveform # => :sine
205
+ synth.frequency # => 440
206
+ synth.amplitude # => 0.8
207
+ ```
208
+
209
+ ## Logger - Sequencer-Aware Logging
210
+
211
+ Specialized logger that displays sequencer position alongside log messages. Essential for debugging temporal issues in compositions.
212
+
213
+ **Features:**
214
+ - Automatic sequencer position formatting
215
+ - Configurable position precision (integer and decimal digits)
216
+ - Integration with InspectNice for readable Rational display
217
+ - Standard Ruby Logger levels (DEBUG, INFO, WARN, ERROR, FATAL)
218
+
219
+ ```ruby
220
+ require 'musa-dsl'
221
+
222
+ # Create sequencer-aware logger
223
+ sequencer = Musa::Sequencer::Sequencer.new(4, 24)
224
+
225
+ logger = Musa::Logger.new(
226
+ sequencer: sequencer,
227
+ level: :debug,
228
+ position_format_integer_digits: 3, # Position: " 4" instead of "4"
229
+ position_format_decimal_digits: 3 # Position: "4.500" instead of "4.5"
230
+ )
231
+
232
+ # Use logger in sequencer context
233
+ sequencer.at 1 do
234
+ logger.info "Starting melody at bar 1"
235
+ end
236
+
237
+ sequencer.at 4.5r do
238
+ logger.debug "Halfway through bar 5"
239
+ end
240
+
241
+ sequencer.at 10 do
242
+ logger.warn "Approaching ending"
243
+ end
244
+
245
+ # Run sequencer to see logged output
246
+ sequencer.run
247
+
248
+ # Output:
249
+ # 001.000: [INFO] Starting melody at bar 1
250
+ # 004.500: [DEBUG] Halfway through bar 5
251
+ # 010.000: [WARN] Approaching ending
252
+ ```
253
+
254
+ **Use Cases:**
255
+ - **Temporal Debugging**: Track down timing issues by seeing exact musical position
256
+ - **MIDI Event Monitoring**: Log MIDI note-on/note-off with positions
257
+ - **Composition Development**: Monitor sequencer flow during development
258
+ - **Performance Analysis**: Identify bottlenecks by logging with timestamps
259
+
260
+ ## API Reference
261
+
262
+ **Complete API documentation:**
263
+ - [Musa::Extension](https://rubydoc.info/gems/musa-dsl/Musa/Extension) - Ruby refinements and metaprogramming utilities
264
+ - [Musa::Logger](https://rubydoc.info/gems/musa-dsl/Musa/Logger) - Structured logging system
265
+
266
+ **Source code:** `lib/core-ext/` and `lib/logger/`
267
+
268
+
269
+ ## Documentation
270
+
271
+ Full API documentation is available in YARD format. All files in the project are comprehensively documented with:
272
+
273
+ - Architecture overviews
274
+ - Usage examples
275
+ - Parameter descriptions
276
+ - Return values
277
+ - Integration examples
278
+
279
+ To generate and view the documentation locally:
280
+
281
+ ```bash
282
+ yard doc
283
+ yard server
284
+ ```
285
+
286
+ Then open http://localhost:8808 in your browser.
287
+
288
+ ## Examples & Works
289
+
290
+ Listen to compositions created with Musa-DSL: [yeste.studio](https://yeste.studio)
291
+
292
+ ## Contributing
293
+
294
+ Contributions are welcome! Please feel free to:
295
+
296
+ 1. Fork the repository
297
+ 2. Create a feature branch
298
+ 3. Make your changes with tests
299
+ 4. Submit a pull request
300
+
301
+ **Repository:** https://github.com/javier-sy/musa-dsl
302
+
303
+ ## License
304
+
305
+ Musa-DSL is released under the [LGPL-3.0-or-later](https://www.gnu.org/licenses/lgpl-3.0.html) license.
306
+
307
+ ## Acknowledgments
308
+
309
+ - **Author:** Javier Sánchez Yeste ([yeste.studio](https://yeste.studio))
310
+ - **Email:** javier (at) yeste.studio
311
+
312
+ Special thanks to [JetBrains](https://www.jetbrains.com/?from=Musa-DSL) for providing an Open Source project license for RubyMine IDE during several years.
313
+
314
+ ---
315
+
316
+ *Musa-DSL - Algorithmic sound and musical thinking through code*