stretto 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/CHANGELOG.markdown +0 -0
  2. data/README.markdown +67 -0
  3. data/Rakefile +9 -0
  4. data/lib/stretto.rb +14 -0
  5. data/lib/stretto/grammar/channel_pressure_grammar.treetop +9 -0
  6. data/lib/stretto/grammar/chord_grammar.treetop +60 -0
  7. data/lib/stretto/grammar/controller_change_grammar.treetop +9 -0
  8. data/lib/stretto/grammar/duration_grammar.treetop +60 -0
  9. data/lib/stretto/grammar/grammar_helper.rb +6 -0
  10. data/lib/stretto/grammar/harmonic_chord_grammar.treetop +15 -0
  11. data/lib/stretto/grammar/harmony_grammar.treetop +15 -0
  12. data/lib/stretto/grammar/instrument_grammar.treetop +9 -0
  13. data/lib/stretto/grammar/key_signature_grammar.treetop +10 -0
  14. data/lib/stretto/grammar/layer_change_grammar.treetop +9 -0
  15. data/lib/stretto/grammar/measure_grammar.treetop +7 -0
  16. data/lib/stretto/grammar/note_grammar.treetop +32 -0
  17. data/lib/stretto/grammar/pitch_bend_grammar.treetop +7 -0
  18. data/lib/stretto/grammar/polyphonic_pressure_grammar.treetop +9 -0
  19. data/lib/stretto/grammar/rest_grammar.treetop +9 -0
  20. data/lib/stretto/grammar/stretto_grammar.treetop +62 -0
  21. data/lib/stretto/grammar/tempo_grammar.treetop +9 -0
  22. data/lib/stretto/grammar/timing_grammar.treetop +9 -0
  23. data/lib/stretto/grammar/tokens/attack_decay_token.rb +42 -0
  24. data/lib/stretto/grammar/tokens/chord_token.rb +67 -0
  25. data/lib/stretto/grammar/tokens/controller_change_token.rb +26 -0
  26. data/lib/stretto/grammar/tokens/duration_token.rb +55 -0
  27. data/lib/stretto/grammar/tokens/harmonic_chord_token.rb +25 -0
  28. data/lib/stretto/grammar/tokens/harmony_with_melody_token.rb +66 -0
  29. data/lib/stretto/grammar/tokens/hash_token.rb +15 -0
  30. data/lib/stretto/grammar/tokens/key_signature_token.rb +30 -0
  31. data/lib/stretto/grammar/tokens/measure_token.rb +21 -0
  32. data/lib/stretto/grammar/tokens/modifier_token.rb +99 -0
  33. data/lib/stretto/grammar/tokens/note_string_token.rb +106 -0
  34. data/lib/stretto/grammar/tokens/note_token.rb +25 -0
  35. data/lib/stretto/grammar/tokens/pattern_token.rb +26 -0
  36. data/lib/stretto/grammar/tokens/polyphonic_pressure_token.rb +28 -0
  37. data/lib/stretto/grammar/tokens/rest_token.rb +21 -0
  38. data/lib/stretto/grammar/tokens/value_token.rb +28 -0
  39. data/lib/stretto/grammar/tokens/variable_definition_token.rb +30 -0
  40. data/lib/stretto/grammar/value_grammar.treetop +45 -0
  41. data/lib/stretto/grammar/variable_grammar.treetop +10 -0
  42. data/lib/stretto/grammar/voice_change_grammar.treetop +9 -0
  43. data/lib/stretto/music_elements/channel_pressure.rb +44 -0
  44. data/lib/stretto/music_elements/chord.rb +194 -0
  45. data/lib/stretto/music_elements/controller_change.rb +49 -0
  46. data/lib/stretto/music_elements/harmonic_chord.rb +56 -0
  47. data/lib/stretto/music_elements/harmony.rb +37 -0
  48. data/lib/stretto/music_elements/instrument.rb +57 -0
  49. data/lib/stretto/music_elements/key_signature.rb +110 -0
  50. data/lib/stretto/music_elements/layer.rb +22 -0
  51. data/lib/stretto/music_elements/layer_change.rb +39 -0
  52. data/lib/stretto/music_elements/measure.rb +38 -0
  53. data/lib/stretto/music_elements/melody.rb +72 -0
  54. data/lib/stretto/music_elements/modifiers/attack_decay.rb +55 -0
  55. data/lib/stretto/music_elements/modifiers/chord_intervals.rb +44 -0
  56. data/lib/stretto/music_elements/modifiers/duration.rb +180 -0
  57. data/lib/stretto/music_elements/modifiers/value.rb +172 -0
  58. data/lib/stretto/music_elements/modifiers/variables.rb +365 -0
  59. data/lib/stretto/music_elements/music_element.rb +88 -0
  60. data/lib/stretto/music_elements/note.rb +282 -0
  61. data/lib/stretto/music_elements/pattern.rb +100 -0
  62. data/lib/stretto/music_elements/pitch_bend.rb +46 -0
  63. data/lib/stretto/music_elements/polyphonic_pressure.rb +62 -0
  64. data/lib/stretto/music_elements/rest.rb +26 -0
  65. data/lib/stretto/music_elements/tempo.rb +42 -0
  66. data/lib/stretto/music_elements/timing.rb +33 -0
  67. data/lib/stretto/music_elements/variable.rb +49 -0
  68. data/lib/stretto/music_elements/voice.rb +49 -0
  69. data/lib/stretto/music_elements/voice_change.rb +39 -0
  70. data/lib/stretto/parsers/exceptions.rb +11 -0
  71. data/lib/stretto/parsers/parser.rb +89 -0
  72. data/lib/stretto/renderers/midiator/player.rb +200 -0
  73. data/lib/stretto/util/jfugue_format_parser.rb +20 -0
  74. data/lib/stretto/util/node.rb +5 -0
  75. data/lib/stretto/util/utils.rb +41 -0
  76. data/lib/stretto/version.rb +3 -0
  77. metadata +203 -0
@@ -0,0 +1,365 @@
1
+ module Stretto
2
+
3
+ # Module that holds the predefined variables according to JFugue
4
+ module Variables
5
+
6
+ INSTRUMENT_VARIABLES = {
7
+ 'PIANO' => 0,
8
+ 'ACOUSTIC_GRAND' => 0,
9
+ 'BRIGHT_ACOUSTIC' => 1,
10
+ 'ELECTRIC_GRAND' => 2,
11
+ 'HONKEY_TONK' => 3,
12
+ 'ELECTRIC_PIANO' => 4,
13
+ 'ELECTRIC_PIANO_1' => 4,
14
+ 'ELECTRIC_PIANO_2' => 5,
15
+ 'HARPISCHORD' => 6,
16
+ 'CLAVINET' => 7,
17
+ 'CELESTA' => 8,
18
+ 'GLOCKENSPIEL' => 9,
19
+ 'MUSIC_BOX' => 10,
20
+ 'VIBRAPHONE' => 11,
21
+ 'MARIMBA' => 12,
22
+ 'XYLOPHONE' => 13,
23
+ 'TUBULAR_BELLS' => 14,
24
+ 'DULCIMER' => 15,
25
+ 'DRAWBAR_ORGAN' => 16,
26
+ 'PERCUSSIVE_ORGAN' => 17,
27
+ 'ROCK_ORGAN' => 18,
28
+ 'CHURCH_ORGAN' => 19,
29
+ 'REED_ORGAN' => 20,
30
+ 'ACCORDION' => 21,
31
+ 'HARMONICA' => 22,
32
+ 'TANGO_ACCORDION' => 23,
33
+ 'GUITAR' => 24,
34
+ 'NYLON_STRING_GUITAR' => 24,
35
+ 'STEEL_STRING_GUITAR' => 25,
36
+ 'ELECTRIC_JAZZ_GUITAR' => 26,
37
+ 'ELECTRIC_CLEAN_GUITAR' => 27,
38
+ 'ELECTRIC_MUTED_GUITAR' => 28,
39
+ 'OVERDRIVEN_GUITAR' => 29,
40
+ 'DISTORTION_GUITAR' => 30,
41
+ 'GUITAR_HARMONICS' => 31,
42
+ 'ACOUSTIC_BASS' => 32,
43
+ 'ELECTRIC_BASS_FINGER' => 33,
44
+ 'ELECTRIC_BASS_PICK' => 34,
45
+ 'FRETLESS_BASS' => 35,
46
+ 'SLAP_BASS_1' => 36,
47
+ 'SLAP_BASS_2' => 37,
48
+ 'SYNTH_BASS_1' => 38,
49
+ 'SYNTH_BASS_2' => 39,
50
+ 'VIOLIN' => 40,
51
+ 'VIOLA' => 41,
52
+ 'CELLO' => 42,
53
+ 'CONTRABASS' => 43,
54
+ 'TREMOLO_STRINGS' => 44,
55
+ 'PIZZICATO_STRINGS' => 45,
56
+ 'ORCHESTRAL_STRINGS' => 46,
57
+ 'TIMPANI' => 47,
58
+ 'STRING_ENSEMBLE_1' => 48,
59
+ 'STRING_ENSEMBLE_2' => 49,
60
+ 'SYNTH_STRINGS_1' => 50,
61
+ 'SYNTH_STRINGS_2' => 51,
62
+ 'CHOIR_AAHS' => 52,
63
+ 'VOICE_OOHS' => 53,
64
+ 'SYNTH_VOICE' => 54,
65
+ 'ORCHESTRA_HIT' => 55,
66
+ 'TRUMPET' => 56,
67
+ 'TROMBONE' => 57,
68
+ 'TUBA' => 58,
69
+ 'MUTED_TRUMPET' => 59,
70
+ 'FRENCH_HORN' => 60,
71
+ 'BRASS_SECTION' => 61,
72
+ 'SYNTHBRASS_1' => 62,
73
+ 'SYNTHBRASS_2' => 63,
74
+ 'SOPRANO_SAX' => 64,
75
+ 'ALTO_SAX' => 65,
76
+ 'TENOR_SAX' => 66,
77
+ 'BARITONE_SAX' => 67,
78
+ 'OBOE' => 68,
79
+ 'ENGLISH_HORN' => 69,
80
+ 'BASOON' => 70,
81
+ 'CLARINET' => 71,
82
+ 'PICCOLO' => 72,
83
+ 'FLUTE' => 73,
84
+ 'RECORDER' => 74,
85
+ 'PAN_FLUTE' => 75,
86
+ 'BLOWN_BOTTLE' => 76,
87
+ 'SHAKUHACHI' => 77,
88
+ 'WHISTLE' => 78,
89
+ 'OCARINA' => 79,
90
+ 'LEAD_SQUARE' => 80,
91
+ 'SQUARE' => 80,
92
+ 'LEAD_SAWTOOTH' => 81,
93
+ 'SAWTOOTH' => 81,
94
+ 'LEAD_CALLIOPE' => 82,
95
+ 'CALLIOPE' => 82,
96
+ 'LEAD_CHIFF' => 83,
97
+ 'CHIFF' => 83,
98
+ 'LEAD_CHARANG' => 84,
99
+ 'CHARANG' => 84,
100
+ 'LEAD_VOICE' => 85,
101
+ 'VOICE' => 85,
102
+ 'LEAD_FIFTHS' => 86,
103
+ 'FIFTHS' => 86,
104
+ 'LEAD_BASSLEAD' => 87,
105
+ 'BASSLEAD' => 87,
106
+ 'PAD_NEW_AGE' => 88,
107
+ 'NEW_AGE' => 88,
108
+ 'PAD_WARM' => 89,
109
+ 'WARM' => 89,
110
+ 'PAD_POLYSYNTH' => 90,
111
+ 'POLYSYNTH' => 90,
112
+ 'PAD_CHOIR' => 91,
113
+ 'CHOIR' => 91,
114
+ 'PAD_BOWED' => 92,
115
+ 'BOWED' => 92,
116
+ 'PAD_METALLIC' => 93,
117
+ 'METALLIC' => 93,
118
+ 'PAD_HALO' => 94,
119
+ 'HALO' => 94,
120
+ 'PAD_SWEEP' => 95,
121
+ 'SWEEP' => 95,
122
+ 'FX_RAIN' => 96,
123
+ 'RAIN' => 96,
124
+ 'FX_SOUNDTRACK' => 97,
125
+ 'SOUNDTRACK' => 97,
126
+ 'FX_CRYSTAL' => 98,
127
+ 'CRYSTAL' => 98,
128
+ 'FX_ATMOSPHERE' => 99,
129
+ 'ATMOSPHERE' => 99,
130
+ 'FX_BRIGHTNESS' => 100,
131
+ 'BRIGHTNESS' => 100,
132
+ 'FX_GOBLINS' => 101,
133
+ 'GOBLINS' => 101,
134
+ 'FX_ECHOES' => 102,
135
+ 'ECHOES' => 102,
136
+ 'FX_SCI_FI' => 103,
137
+ 'SCI_FI' => 103,
138
+ 'SITAR' => 104,
139
+ 'BANJO' => 105,
140
+ 'SHAMISEN' => 106,
141
+ 'KOTO' => 107,
142
+ 'KALIMBA' => 108,
143
+ 'BAGPIPE' => 109,
144
+ 'FIDDLE' => 110,
145
+ 'SHANAI' => 111,
146
+ 'TINKLE_BELL' => 112,
147
+ 'AGOGO' => 113,
148
+ 'STEEL_DRUMS' => 114,
149
+ 'WOODBLOCK' => 115,
150
+ 'TAIKO_DRUM' => 116,
151
+ 'MELODIC_TOM' => 117,
152
+ 'SYNTH_DRUM' => 118,
153
+ 'REVERSE_CYMBAL' => 119,
154
+ 'GUITAR_FRET_NOISE' => 120,
155
+ 'BREATH_NOISE' => 121,
156
+ 'SEASHORE' => 122,
157
+ 'BIRD_TWEET' => 123,
158
+ 'TELEPHONE_RING' => 124,
159
+ 'HELICOPTER' => 125,
160
+ 'APPLAUSE' => 126,
161
+ 'GUNSHOT' => 127,
162
+ }
163
+
164
+ PERCUSSION_VARIABLES = {
165
+ 'ACOUSTIC_BASE_DRUM' => 35,
166
+ 'BASS_DRUM' => 36,
167
+ 'SIDE_KICK' => 37,
168
+ 'ACOUSTIC_SNARE' => 38,
169
+ 'HAND_CLAP' => 39,
170
+ 'ELECTRIC_SNARE' => 40,
171
+ 'LOW_FLOOR_TOM' => 41,
172
+ 'CLOSED_HI_HAT' => 42,
173
+ 'HIGH_FLOOR_TOM' => 43,
174
+ 'PEDAL_HI_TOM' => 44,
175
+ 'LOW_TOM' => 45,
176
+ 'OPEN_HI_HAT' => 46,
177
+ 'LOW_MID_TOM' => 47,
178
+ 'HI_MID_TOM' => 48,
179
+ 'CRASH_CYMBAL_1' => 49,
180
+ 'HIGH_TOM' => 50,
181
+ 'RIDE_CYMBAL_1' => 51,
182
+ 'CHINESE_CYMBAL' => 52,
183
+ 'RIDE_BELL' => 53,
184
+ 'TAMBOURINE' => 54,
185
+ 'SPLASH_CYMBAL' => 55,
186
+ 'COWBELL' => 56,
187
+ 'CRASH_CYMBAL_2' => 57,
188
+ 'VIBRASLAP' => 58,
189
+ 'RIDE_CYMBAL_2' => 59,
190
+ 'HI_BONGO' => 60,
191
+ 'LOW_BONGO' => 61,
192
+ 'MUTE_HI_CONGA' => 62,
193
+ 'OPEN_HI_CONGA' => 63,
194
+ 'LOW_CONGO' => 64,
195
+ 'HIGH_TIMBALE' => 65,
196
+ 'LOW_TIMBALE' => 66,
197
+ 'HIGH_AGOGO' => 67,
198
+ 'LOW_AGOGO' => 68,
199
+ 'CABASA' => 69,
200
+ 'MARACAS' => 70,
201
+ 'SHORT_WHISTLE' => 71,
202
+ 'LONG_WHISTLE' => 72,
203
+ 'SHORT_GUIRO' => 73,
204
+ 'LONG_GUIRO' => 74,
205
+ 'CLAVES' => 75,
206
+ 'HI_WOOD_BLOCK' => 76,
207
+ 'LOW_WOOD_BLOCK' => 77,
208
+ 'MUTE_CUICA' => 78,
209
+ 'OPEN_CUICA' => 79,
210
+ 'MUTE_TRIANGLE' => 80,
211
+ 'OPEN_TRIANGLE' => 81,
212
+ }
213
+
214
+ TEMPO_VARIABLES = {
215
+ 'GRAVE' => 40,
216
+ 'LARGO' => 45,
217
+ 'LARGHETTO' => 50,
218
+ 'LENTO' => 55,
219
+ 'ADAGIO' => 60,
220
+ 'ADAGIETTO' => 65,
221
+ 'ANDANTE' => 70,
222
+ 'ANDANTINO' => 80,
223
+ 'MODERATO' => 95,
224
+ 'ALLEGRETTO' => 110,
225
+ 'ALLEGRO' => 120,
226
+ 'VIVACE' => 145,
227
+ 'PRESTO' => 180,
228
+ 'PRESTISSIMO' => 220,
229
+ }
230
+
231
+ CONTROLLER_VARIABLES = {
232
+ 'BANK_SELECT_COARSE' => 0,
233
+ 'MOD_WHEEL_COARSE' => 1,
234
+ 'BREATH_COARSE' => 2,
235
+ 'FOOT_PEDAL_COARSE' => 4,
236
+ 'PORTAMENTO_TIME_COARSE' => 5,
237
+ 'DATA_ENTRY_COARSE' => 6,
238
+ 'VOLUME_COARSE' => 7,
239
+ 'BALANCE_COARSE' => 8,
240
+ 'PAN_POSITION_COARSE' => 10,
241
+ 'EXPRESSION_COARSE' => 11,
242
+ 'EFFECT_CONTROL_1_COARSE' => 12,
243
+ 'EFFECT_CONTROL_2_COARSE' => 13,
244
+ 'SLIDER_1' => 16,
245
+ 'SLIDER_2' => 17,
246
+ 'SLIDER_3' => 18,
247
+ 'SLIDER_4' => 19,
248
+ 'BANK_SELECT_FINE' => 32,
249
+ 'MOD_WHEEL_FINE' => 33,
250
+ 'BREATH_FINE' => 34,
251
+ 'FOOT_PEDAL_FINE' => 36,
252
+ 'PORTAMENTO_TIME_FINE' => 37,
253
+ 'DATA_ENTRY_FINE' => 38,
254
+ 'VOLUME_FINE' => 39,
255
+ 'BALANCE_FINE' => 40,
256
+ 'PAN_POSITION_FINE' => 42,
257
+ 'EXPRESSION_FINE' => 43,
258
+ 'EFFECT_CONTROL_1_FINE' => 44,
259
+ 'EFFECT_CONTROL_2_FINE' => 45,
260
+ 'HOLD_PEDAL' => 64,
261
+ 'HOLD' => 64,
262
+ 'PORTAMENTO' => 65,
263
+ 'SUSTENUTO_PEDAL' => 66,
264
+ 'SUSTENUTO' => 66,
265
+ 'SOFT_PEDAL' => 67,
266
+ 'SOFT' => 67,
267
+ 'LEGATO_PEDAL' => 68,
268
+ 'LEGATO' => 68,
269
+ 'HOLD_2_PEDAL' => 69,
270
+ 'HOLD_2' => 69,
271
+ 'SOUND_VARIATION' => 70,
272
+ 'VARIATION' => 70,
273
+ 'SOUND_TIMBRE' => 71,
274
+ 'TIMBRE' => 71,
275
+ 'SOUND_RELEASE_TIME' => 72,
276
+ 'RELEASE_TIME' => 72,
277
+ 'SOUND_ATTACK_TIME' => 73,
278
+ 'ATTACK_TIME' => 73,
279
+ 'SOUND_BRIGHTNESS' => 74,
280
+ 'X_BRIGHTNESS' => 74,
281
+ 'SOUND_CONTROL_6' => 75,
282
+ 'CONTROL_6' => 75,
283
+ 'SOUND_CONTROL_7' => 76,
284
+ 'CONTROL_7' => 76,
285
+ 'SOUND_CONTROL_8' => 77,
286
+ 'CONTROL_8' => 77,
287
+ 'SOUND_CONTROL_9' => 78,
288
+ 'CONTROL_9' => 78,
289
+ 'SOUND_CONTROL_10' => 79,
290
+ 'CONTROL_10' => 79,
291
+ 'GENERAL_PURPOSE_BUTTON_1' => 80,
292
+ 'GENERAL_BUTTON_1' => 80,
293
+ 'BUTTON_1' => 80,
294
+ 'GENERAL_PURPOSE_BUTTON_2' => 81,
295
+ 'GENERAL_BUTTON_2' => 81,
296
+ 'BUTTON_2' => 81,
297
+ 'GENERAL_PURPOSE_BUTTON_3' => 82,
298
+ 'GENERAL_BUTTON_3' => 82,
299
+ 'BUTTON_3' => 82,
300
+ 'GENERAL_PURPOSE_BUTTON_4' => 83,
301
+ 'GENERAL_BUTTON_4' => 83,
302
+ 'BUTTON_4' => 83,
303
+ 'EFFECTS_LEVEL' => 91,
304
+ 'EFFECTS' => 91,
305
+ 'TREMOLO_LEVEL' => 92,
306
+ 'TREMOLO' => 92,
307
+ 'CHORUS_LEVEL' => 93,
308
+ 'CHORUS' => 93,
309
+ 'CELESTE_LEVEL' => 94,
310
+ 'CELESTE' => 94,
311
+ 'PHASER_LEVEL' => 95,
312
+ 'PHASER' => 95,
313
+ 'DATA_BUTTON_INCREMENT' => 96,
314
+ 'DATA_BUTTON_INC' => 96,
315
+ 'BUTTON_INC' => 96,
316
+ 'DATA_BUTTON_DECREMENT' => 97,
317
+ 'DATA_BUTTON_DEC' => 97,
318
+ 'BUTTON_DEC' => 97,
319
+ 'NON_REGISTERED_COARSE' => 98,
320
+ 'NON_REGISTERED_FINE' => 99,
321
+ 'REGISTERED_COARSE' => 100,
322
+ 'REGISTERED_FINE' => 101,
323
+ 'ALL_SOUND_OFF' => 120,
324
+ 'ALL_CONTROLLERS_OFF' => 121,
325
+ 'LOCAL_KEYBOARD' => 122,
326
+ 'ALL_NOTES_OFF' => 123,
327
+ 'OMNI_MODE_OFF' => 124,
328
+ 'OMNI_OFF' => 124,
329
+ 'OMNI_MODE_ON' => 125,
330
+ 'OMNI_ON' => 125,
331
+ 'MONO_OPERATION' => 126,
332
+ 'MONO' => 126,
333
+ 'POLY_OPERATION' => 127,
334
+ 'POLY' => 127,
335
+
336
+ #== Combined values ==
337
+ 'BANK_SELECT' => 16383,
338
+ 'MOD_WHEEL' => 161,
339
+ 'BREATH' => 290,
340
+ 'FOOT_PEDAL' => 548,
341
+ 'PORTAMENTO_TIME' => 677,
342
+ 'DATA_ENTRY' => 806,
343
+ 'VOLUME' => 935,
344
+ 'BALANCE' => 1064,
345
+ 'PAN_POSITION' => 1322,
346
+ 'EXPRESSION' => 1451,
347
+ 'EFFECT_CONTROL_1' => 1580,
348
+ 'EFFECT_CONTROL_2' => 1709,
349
+ 'NON_REGISTERED' => 12770,
350
+ 'REGISTERED' => 13208,
351
+
352
+ #== Controller values ==
353
+ 'ON' => 127,
354
+ 'OFF' => 0,
355
+ 'DEFAULT' => 64,
356
+ }
357
+
358
+ # All predefined variables for stretto
359
+ PREDEFINED_VARIABLES = INSTRUMENT_VARIABLES.
360
+ merge(PERCUSSION_VARIABLES).
361
+ merge(TEMPO_VARIABLES).
362
+ merge(CONTROLLER_VARIABLES)
363
+
364
+ end
365
+ end
@@ -0,0 +1,88 @@
1
+ require File.join(File.dirname(__FILE__), '../util/node')
2
+ require File.join(File.dirname(__FILE__), 'modifiers/duration')
3
+
4
+ module Stretto
5
+ module MusicElements
6
+
7
+ # Superclass of all music elements in Stretto.
8
+ #
9
+ # These are all the elements than can be added to a pattern, most of them represent some
10
+ # data to be sent to a MIDI channel, or are some notation element to aid in the composition.
11
+ class MusicElement
12
+
13
+ include Stretto::Node
14
+
15
+ # In the case of parsed element, this is the originating string.
16
+ # In the case of calculated elements, this should be an empty string, and its string
17
+ # representation must be provided by the element
18
+ #
19
+ # @return [String, nil]
20
+ attr_reader :original_string
21
+
22
+ # The pattern to where this element belongs. Used to make calculations about key signatures,
23
+ # ties, instruments, voices, etc. that may modify the element itself.
24
+ #
25
+ # @return [Pattern, nil]
26
+ attr_reader :pattern
27
+
28
+ # Stores the original string and an optional pattern
29
+ def initialize(original_string, pattern = nil)
30
+ @original_string = original_string # TODO: Validates always an original string?
31
+ @pattern = pattern
32
+ end
33
+
34
+ # @return The string representation of the element
35
+ # @todo No specs for this. Ideally, its string representation should be one that can be
36
+ # parsed again to retrieve the same element
37
+ def to_s
38
+ original_string || build_music_string
39
+ end
40
+
41
+ # @abstract
42
+ # @todo Not yet implemented
43
+ def build_music_string
44
+ raise "build_music_string not implemented in #{self.class}"
45
+ end
46
+
47
+ alias inspect to_s
48
+
49
+ # By default, it is true, so we can tie notes with elements in between
50
+ def start_of_tie?
51
+ true
52
+ end
53
+
54
+ # By default, it is true, so we can tie notes with elements in between
55
+ def end_of_tie?
56
+ true
57
+ end
58
+
59
+ # By default, duration is 0
60
+ #
61
+ # The correct duration should be overriden by subclasses
62
+ def duration
63
+ 0
64
+ end
65
+
66
+ # @private
67
+ #
68
+ # Called whenever an element is attached to a pattern, and its attributes need to be
69
+ # recalculated / validated (because of variables, key signatures, ties, etc.)
70
+ #
71
+ # Each element class must override this class to provide the callback when the element
72
+ # is added to a pattern.
73
+ def substitute_variables!
74
+ # TODO: Big TODO - Change this method's name for a callback.
75
+ end
76
+
77
+ # Assigns the pattern to the element, and runs any associated callback
78
+ #
79
+ # @see #substitute_variables!
80
+ def pattern=(pattern)
81
+ @pattern = pattern
82
+ substitute_variables! # TODO: Remove this call
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+ end