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
@@ -4,10 +4,74 @@ module Musa
4
4
  module MusicXML
5
5
  module Builder
6
6
  module Internal
7
+ # Tuplet time modification (ratio).
8
+ #
9
+ # TimeModification defines the rhythmic ratio for tuplets, indicating how
10
+ # many notes of one type fit in the time normally occupied by notes of
11
+ # another type. This modifies the playback duration without changing the
12
+ # visual note type.
13
+ #
14
+ # ## Tuplet Ratios
15
+ #
16
+ # Tuplets are expressed as **actual_notes : normal_notes**:
17
+ #
18
+ # ### Common Tuplets
19
+ # - **Triplet** (3:2): 3 notes in the time of 2
20
+ # - Quarter note triplet: 3 quarters in time of 2 quarters (half note)
21
+ # - Eighth note triplet: 3 eighths in time of 2 eighths (quarter note)
22
+ #
23
+ # - **Quintuplet** (5:4): 5 notes in the time of 4
24
+ #
25
+ # - **Sextuplet** (6:4): 6 notes in the time of 4
26
+ #
27
+ # - **Septuplet** (7:4 or 7:8): 7 notes in time of 4 or 8
28
+ #
29
+ # - **Duplet** (2:3): 2 notes in the time of 3 (in compound meter)
30
+ #
31
+ # ## Components
32
+ #
33
+ # - **actual_notes**: Number of notes actually played
34
+ # - **normal_notes**: Number of notes normally played in that duration
35
+ # - **normal_type**: Note type for normal notes (optional)
36
+ # - **normal_dots**: Augmentation dots on normal notes (optional)
37
+ #
38
+ # ## Relationship with Tuplet
39
+ #
40
+ # TimeModification affects playback timing, while {Tuplet} controls
41
+ # visual display (bracket, number). Both are typically used together.
42
+ #
43
+ # @example Triplet (3:2)
44
+ # TimeModification.new(actual_notes: 3, normal_notes: 2)
45
+ #
46
+ # @example Quintuplet (5:4)
47
+ # TimeModification.new(actual_notes: 5, normal_notes: 4)
48
+ #
49
+ # @example Triplet with explicit normal type
50
+ # TimeModification.new(actual_notes: 3, normal_notes: 2,
51
+ # normal_type: 'eighth')
52
+ #
53
+ # @example Duplet in compound meter (2:3)
54
+ # TimeModification.new(actual_notes: 2, normal_notes: 3)
55
+ #
56
+ # @see Tuplet Visual tuplet bracket notation
57
+ # @see Note Note class using time modifications
7
58
  class TimeModification
8
59
  include Helper
9
60
  include ToXML
10
61
 
62
+ # Creates a time modification.
63
+ #
64
+ # @param actual_notes [Integer] number of notes in the tuplet group
65
+ # @param normal_notes [Integer] number of normal notes in same duration
66
+ # @param normal_type [String, nil] note type of normal notes ('quarter', 'eighth', etc.)
67
+ # @param normal_dots [Integer, nil] augmentation dots on normal notes
68
+ #
69
+ # @example Quarter note triplet (3 in time of 2)
70
+ # TimeModification.new(actual_notes: 3, normal_notes: 2)
71
+ #
72
+ # @example Quintuplet with explicit normal type
73
+ # TimeModification.new(actual_notes: 5, normal_notes: 4,
74
+ # normal_type: 'quarter')
11
75
  def initialize(actual_notes:, # number
12
76
  normal_notes:, # number
13
77
  normal_type: nil, # quarter / ...
@@ -19,8 +83,30 @@ module Musa
19
83
  @normal_dots = normal_dots
20
84
  end
21
85
 
22
- attr_accessor :actual_notes, :normal_notes, :normal_type, :normal_dots
23
-
86
+ # Number of actual notes in the tuplet.
87
+ # @return [Integer]
88
+ attr_accessor :actual_notes
89
+
90
+ # Number of normal notes in the same duration.
91
+ # @return [Integer]
92
+ attr_accessor :normal_notes
93
+
94
+ # Note type of normal notes.
95
+ # @return [String, nil]
96
+ attr_accessor :normal_type
97
+
98
+ # Augmentation dots on normal notes.
99
+ # @return [Integer, nil]
100
+ attr_accessor :normal_dots
101
+
102
+ # Generates the time-modification XML element.
103
+ #
104
+ # @param io [IO] output stream
105
+ # @param indent [Integer] indentation level
106
+ # @param tabs [String] tab string
107
+ # @return [void]
108
+ #
109
+ # @api private
24
110
  def _to_xml(io, indent:, tabs:)
25
111
  io.puts "#{tabs}<time-modification>"
26
112
 
@@ -35,10 +121,98 @@ module Musa
35
121
  end
36
122
  end
37
123
 
124
+ # Visual tuplet bracket and number notation.
125
+ #
126
+ # Tuplet controls the visual appearance of tuplet markings: brackets,
127
+ # numbers, and note type indications. Unlike {TimeModification}, which
128
+ # affects playback timing, Tuplet is purely visual.
129
+ #
130
+ # ## Components
131
+ #
132
+ # ### Type
133
+ # - **start**: Begin tuplet bracket/number
134
+ # - **stop**: End tuplet bracket/number
135
+ #
136
+ # Multiple tuplets can overlap using different `number` attributes.
137
+ #
138
+ # ### Bracket
139
+ # - **true**: Show bracket
140
+ # - **false/nil**: Hide bracket (use number only)
141
+ #
142
+ # Common practice: show brackets for beam-breaking tuplets, hide for beamed.
143
+ #
144
+ # ### Number Display
145
+ # - **show_number**:
146
+ # - 'actual': Show only actual number (e.g., "3")
147
+ # - 'both': Show ratio (e.g., "3:2")
148
+ # - 'none': Hide number
149
+ #
150
+ # - **show_type**:
151
+ # - 'actual': Show note type for actual notes
152
+ # - 'both': Show note types for both
153
+ # - 'none': Hide note types
154
+ #
155
+ # ### Actual/Normal Specification
156
+ #
157
+ # Optional detailed specification of tuplet appearance:
158
+ # - **actual_number/actual_type/actual_dots**: Actual notes representation
159
+ # - **normal_number/normal_type/normal_dots**: Normal notes representation
160
+ #
161
+ # Typically inferred from {TimeModification} and note properties.
162
+ #
163
+ # ## Typical Usage
164
+ #
165
+ # Most tuplets only need `type` (start/stop) and optionally `bracket`:
166
+ #
167
+ # Tuplet.new(type: 'start', bracket: true) # First note of triplet
168
+ # Tuplet.new(type: 'stop') # Last note of triplet
169
+ #
170
+ # @example Simple triplet bracket (start)
171
+ # Tuplet.new(type: 'start', bracket: true)
172
+ #
173
+ # @example Triplet end
174
+ # Tuplet.new(type: 'stop')
175
+ #
176
+ # @example Tuplet without bracket
177
+ # Tuplet.new(type: 'start', bracket: false)
178
+ #
179
+ # @example Nested tuplets with numbers
180
+ # Tuplet.new(type: 'start', number: 1, bracket: true) # Outer
181
+ # Tuplet.new(type: 'start', number: 2, bracket: true) # Inner
182
+ # Tuplet.new(type: 'stop', number: 2) # End inner
183
+ # Tuplet.new(type: 'stop', number: 1) # End outer
184
+ #
185
+ # @example Custom display (show ratio)
186
+ # Tuplet.new(type: 'start', show_number: 'both') # Shows "3:2"
187
+ #
188
+ # @see TimeModification Tuplet timing ratio
189
+ # @see Note Note class with tuplet support
38
190
  class Tuplet
39
191
  include Helper
40
192
  include ToXML
41
193
 
194
+ # Creates a tuplet notation.
195
+ #
196
+ # @param type [String] 'start' or 'stop'
197
+ # @param number [Integer, nil] tuplet number for nesting (default 1)
198
+ # @param bracket [Boolean, nil] show bracket
199
+ # @param show_number [String, nil] number display: 'actual', 'both', 'none'
200
+ # @param show_type [String, nil] note type display: 'actual', 'both', 'none'
201
+ # @param actual_number [Integer, nil] actual number for display
202
+ # @param actual_type [String, nil] actual note type for display
203
+ # @param actual_dots [Integer, nil] actual dots for display
204
+ # @param normal_number [Integer, nil] normal number for display
205
+ # @param normal_type [String, nil] normal note type for display
206
+ # @param normal_dots [Integer, nil] normal dots for display
207
+ #
208
+ # @example Start a triplet bracket
209
+ # Tuplet.new(type: 'start', bracket: true)
210
+ #
211
+ # @example End a tuplet
212
+ # Tuplet.new(type: 'stop')
213
+ #
214
+ # @example Quintuplet with ratio display
215
+ # Tuplet.new(type: 'start', bracket: true, show_number: 'both')
42
216
  def initialize(type:, # start / stop
43
217
  number: nil, # number
44
218
  bracket: nil, # true
@@ -64,10 +238,58 @@ module Musa
64
238
  @normal_dots = normal_dots
65
239
  end
66
240
 
67
- attr_accessor :type, :number, :bracket, :show_number, :show_type
68
- attr_accessor :actual_number, :actual_type, :actual_dots
69
- attr_accessor :normal_number, :normal_type, :normal_dots
70
-
241
+ # Tuplet type ('start' or 'stop').
242
+ # @return [String]
243
+ attr_accessor :type
244
+
245
+ # Tuplet number for nesting.
246
+ # @return [Integer, nil]
247
+ attr_accessor :number
248
+
249
+ # Show bracket.
250
+ # @return [Boolean, nil]
251
+ attr_accessor :bracket
252
+
253
+ # Number display mode.
254
+ # @return [String, nil]
255
+ attr_accessor :show_number
256
+
257
+ # Note type display mode.
258
+ # @return [String, nil]
259
+ attr_accessor :show_type
260
+
261
+ # Actual number for display.
262
+ # @return [Integer, nil]
263
+ attr_accessor :actual_number
264
+
265
+ # Actual note type for display.
266
+ # @return [String, nil]
267
+ attr_accessor :actual_type
268
+
269
+ # Actual augmentation dots for display.
270
+ # @return [Integer, nil]
271
+ attr_accessor :actual_dots
272
+
273
+ # Normal number for display.
274
+ # @return [Integer, nil]
275
+ attr_accessor :normal_number
276
+
277
+ # Normal note type for display.
278
+ # @return [String, nil]
279
+ attr_accessor :normal_type
280
+
281
+ # Normal augmentation dots for display.
282
+ # @return [Integer, nil]
283
+ attr_accessor :normal_dots
284
+
285
+ # Generates the tuplet XML element.
286
+ #
287
+ # @param io [IO] output stream
288
+ # @param indent [Integer] indentation level
289
+ # @param tabs [String] tab string
290
+ # @return [void]
291
+ #
292
+ # @api private
71
293
  def _to_xml(io, indent:, tabs:)
72
294
  io.puts "#{tabs}<tuplet type=\"#{@type}\"" \
73
295
  "#{decode_bool_or_string_attribute(@number&.to_i, 'number')}" \
@@ -106,9 +328,64 @@ module Musa
106
328
  end
107
329
  end
108
330
 
331
+ # String harmonic technique.
332
+ #
333
+ # Harmonic represents natural and artificial harmonics for string instruments
334
+ # (violin, cello, guitar, etc.). Harmonics produce ethereal, whistle-like tones
335
+ # by lightly touching the string at specific node points.
336
+ #
337
+ # ## Harmonic Types
338
+ #
339
+ # ### Natural Harmonics
340
+ # Produced by lightly touching the string at natural node points (1/2, 1/3, 1/4, etc.):
341
+ # - **kind**: 'natural'
342
+ # - Common on open strings
343
+ # - Easier to execute
344
+ #
345
+ # ### Artificial Harmonics
346
+ # Produced by stopping the string at one point and lightly touching at another:
347
+ # - **kind**: 'artificial'
348
+ # - Requires two fingers
349
+ # - More versatile for chromaticism
350
+ #
351
+ # ## Pitch Specification
352
+ #
353
+ # Harmonics notation can indicate different pitches:
354
+ #
355
+ # - **base-pitch**: The stopped pitch (where finger presses firmly)
356
+ # - **touching-pitch**: Where finger lightly touches
357
+ # - **sounding-pitch**: The actual pitch that sounds (octave or more higher)
358
+ #
359
+ # Different notation conventions exist; MusicXML allows specifying which
360
+ # pitch the written note represents.
361
+ #
362
+ # @example Natural harmonic
363
+ # Harmonic.new(kind: 'natural')
364
+ #
365
+ # @example Artificial harmonic
366
+ # Harmonic.new(kind: 'artificial')
367
+ #
368
+ # @example Harmonic with sounding pitch notation
369
+ # Harmonic.new(kind: 'natural', pitch: 'sounding-pitch')
370
+ #
371
+ # @example Harmonic with touching pitch notation
372
+ # Harmonic.new(kind: 'artificial', pitch: 'touching-pitch')
373
+ #
374
+ # @see Note Note class with harmonic support
109
375
  class Harmonic
110
376
  include Helper::ToXML
111
377
 
378
+ # Creates a harmonic.
379
+ #
380
+ # @param kind [String, nil] 'natural' or 'artificial'
381
+ # @param pitch [String, nil] which pitch the note represents:
382
+ # 'base-pitch', 'sounding-pitch', or 'touching-pitch'
383
+ #
384
+ # @example Natural harmonic
385
+ # Harmonic.new(kind: 'natural')
386
+ #
387
+ # @example Artificial harmonic with sounding pitch
388
+ # Harmonic.new(kind: 'artificial', pitch: 'sounding-pitch')
112
389
  def initialize(kind: nil, # natural / artificial
113
390
  pitch: nil) # base-pitch / sounding-pitch / touching-pitch
114
391
 
@@ -116,8 +393,22 @@ module Musa
116
393
  @pitch = pitch
117
394
  end
118
395
 
119
- attr_accessor :kind, :pitch
120
-
396
+ # Harmonic type ('natural' or 'artificial').
397
+ # @return [String, nil]
398
+ attr_accessor :kind
399
+
400
+ # Which pitch the written note represents.
401
+ # @return [String, nil]
402
+ attr_accessor :pitch
403
+
404
+ # Generates the harmonic XML element.
405
+ #
406
+ # @param io [IO] output stream
407
+ # @param indent [Integer] indentation level
408
+ # @param tabs [String] tab string
409
+ # @return [void]
410
+ #
411
+ # @api private
121
412
  def _to_xml(io, indent:, tabs:)
122
413
  io.puts "#{tabs}<harmonic>"
123
414
  io.puts "#{tabs}\t<#{@kind} />" if @kind
@@ -126,22 +417,47 @@ module Musa
126
417
  end
127
418
  end
128
419
 
420
+ # Notehead style and properties (not yet implemented).
421
+ #
422
+ # Placeholder for notehead customization (shape, color, filled/hollow, etc.).
423
+ #
424
+ # @api private
129
425
  class Notehead
130
426
  include Helper::NotImplemented
131
427
  end
132
428
 
429
+ # Directional arrow notation (not yet implemented).
430
+ #
431
+ # Placeholder for arrow technical markings.
432
+ #
433
+ # @api private
133
434
  class Arrow
134
435
  include Helper::NotImplemented
135
436
  end
136
437
 
438
+ # String bend notation (not yet implemented).
439
+ #
440
+ # Placeholder for guitar/bass string bending.
441
+ #
442
+ # @api private
137
443
  class Bend
138
444
  include Helper::NotImplemented
139
445
  end
140
446
 
447
+ # Fingering indication (not yet implemented).
448
+ #
449
+ # Placeholder for finger numbers and substitution.
450
+ #
451
+ # @api private
141
452
  class Fingering
142
453
  include Helper::NotImplemented
143
454
  end
144
455
 
456
+ # Woodwind fingering hole (not yet implemented).
457
+ #
458
+ # Placeholder for woodwind fingering charts.
459
+ #
460
+ # @api private
145
461
  class Hole
146
462
  include Helper::NotImplemented
147
463
  end