musicality 0.1.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 (141) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +47 -0
  8. data/Rakefile +65 -0
  9. data/bin/midify +78 -0
  10. data/examples/hip.rb +32 -0
  11. data/examples/missed_connection.rb +26 -0
  12. data/examples/song1.rb +33 -0
  13. data/examples/song2.rb +32 -0
  14. data/lib/musicality/errors.rb +9 -0
  15. data/lib/musicality/notation/conversion/change_conversion.rb +19 -0
  16. data/lib/musicality/notation/conversion/measure_note_map.rb +40 -0
  17. data/lib/musicality/notation/conversion/measured_score_conversion.rb +70 -0
  18. data/lib/musicality/notation/conversion/measured_score_converter.rb +95 -0
  19. data/lib/musicality/notation/conversion/note_time_converter.rb +68 -0
  20. data/lib/musicality/notation/conversion/tempo_conversion.rb +25 -0
  21. data/lib/musicality/notation/conversion/unmeasured_score_conversion.rb +47 -0
  22. data/lib/musicality/notation/conversion/unmeasured_score_converter.rb +64 -0
  23. data/lib/musicality/notation/model/articulations.rb +13 -0
  24. data/lib/musicality/notation/model/change.rb +62 -0
  25. data/lib/musicality/notation/model/dynamics.rb +12 -0
  26. data/lib/musicality/notation/model/link.rb +73 -0
  27. data/lib/musicality/notation/model/meter.rb +54 -0
  28. data/lib/musicality/notation/model/meters.rb +9 -0
  29. data/lib/musicality/notation/model/note.rb +120 -0
  30. data/lib/musicality/notation/model/part.rb +54 -0
  31. data/lib/musicality/notation/model/pitch.rb +163 -0
  32. data/lib/musicality/notation/model/pitches.rb +21 -0
  33. data/lib/musicality/notation/model/program.rb +53 -0
  34. data/lib/musicality/notation/model/score.rb +132 -0
  35. data/lib/musicality/notation/packing/change_packing.rb +46 -0
  36. data/lib/musicality/notation/packing/part_packing.rb +31 -0
  37. data/lib/musicality/notation/packing/program_packing.rb +16 -0
  38. data/lib/musicality/notation/packing/score_packing.rb +108 -0
  39. data/lib/musicality/notation/parsing/articulation_parsing.rb +264 -0
  40. data/lib/musicality/notation/parsing/articulation_parsing.treetop +59 -0
  41. data/lib/musicality/notation/parsing/convenience_methods.rb +74 -0
  42. data/lib/musicality/notation/parsing/duration_nodes.rb +21 -0
  43. data/lib/musicality/notation/parsing/duration_parsing.rb +205 -0
  44. data/lib/musicality/notation/parsing/duration_parsing.treetop +25 -0
  45. data/lib/musicality/notation/parsing/link_nodes.rb +35 -0
  46. data/lib/musicality/notation/parsing/link_parsing.rb +270 -0
  47. data/lib/musicality/notation/parsing/link_parsing.treetop +33 -0
  48. data/lib/musicality/notation/parsing/meter_parsing.rb +190 -0
  49. data/lib/musicality/notation/parsing/meter_parsing.treetop +29 -0
  50. data/lib/musicality/notation/parsing/note_node.rb +40 -0
  51. data/lib/musicality/notation/parsing/note_parsing.rb +229 -0
  52. data/lib/musicality/notation/parsing/note_parsing.treetop +28 -0
  53. data/lib/musicality/notation/parsing/numbers/nonnegative_float_parsing.rb +289 -0
  54. data/lib/musicality/notation/parsing/numbers/nonnegative_float_parsing.treetop +29 -0
  55. data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +64 -0
  56. data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.treetop +17 -0
  57. data/lib/musicality/notation/parsing/numbers/nonnegative_rational_parsing.rb +86 -0
  58. data/lib/musicality/notation/parsing/numbers/nonnegative_rational_parsing.treetop +20 -0
  59. data/lib/musicality/notation/parsing/numbers/positive_float_parsing.rb +503 -0
  60. data/lib/musicality/notation/parsing/numbers/positive_float_parsing.treetop +33 -0
  61. data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.rb +95 -0
  62. data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.treetop +19 -0
  63. data/lib/musicality/notation/parsing/numbers/positive_rational_parsing.rb +84 -0
  64. data/lib/musicality/notation/parsing/numbers/positive_rational_parsing.treetop +19 -0
  65. data/lib/musicality/notation/parsing/parseable.rb +30 -0
  66. data/lib/musicality/notation/parsing/pitch_node.rb +23 -0
  67. data/lib/musicality/notation/parsing/pitch_parsing.rb +448 -0
  68. data/lib/musicality/notation/parsing/pitch_parsing.treetop +52 -0
  69. data/lib/musicality/notation/parsing/segment_parsing.rb +141 -0
  70. data/lib/musicality/notation/parsing/segment_parsing.treetop +23 -0
  71. data/lib/musicality/notation/util/interpolation.rb +16 -0
  72. data/lib/musicality/notation/util/piecewise_function.rb +122 -0
  73. data/lib/musicality/notation/util/value_computer.rb +170 -0
  74. data/lib/musicality/performance/conversion/glissando_converter.rb +34 -0
  75. data/lib/musicality/performance/conversion/note_sequence_extractor.rb +98 -0
  76. data/lib/musicality/performance/conversion/portamento_converter.rb +24 -0
  77. data/lib/musicality/performance/conversion/score_collator.rb +126 -0
  78. data/lib/musicality/performance/midi/midi_events.rb +34 -0
  79. data/lib/musicality/performance/midi/midi_util.rb +31 -0
  80. data/lib/musicality/performance/midi/part_sequencer.rb +123 -0
  81. data/lib/musicality/performance/midi/score_sequencer.rb +45 -0
  82. data/lib/musicality/performance/model/note_attacks.rb +19 -0
  83. data/lib/musicality/performance/model/note_sequence.rb +111 -0
  84. data/lib/musicality/performance/util/note_linker.rb +28 -0
  85. data/lib/musicality/performance/util/optimization.rb +31 -0
  86. data/lib/musicality/validatable.rb +38 -0
  87. data/lib/musicality/version.rb +3 -0
  88. data/lib/musicality.rb +81 -0
  89. data/musicality.gemspec +30 -0
  90. data/spec/musicality_spec.rb +7 -0
  91. data/spec/notation/conversion/change_conversion_spec.rb +40 -0
  92. data/spec/notation/conversion/measure_note_map_spec.rb +73 -0
  93. data/spec/notation/conversion/measured_score_conversion_spec.rb +141 -0
  94. data/spec/notation/conversion/measured_score_converter_spec.rb +329 -0
  95. data/spec/notation/conversion/note_time_converter_spec.rb +81 -0
  96. data/spec/notation/conversion/tempo_conversion_spec.rb +40 -0
  97. data/spec/notation/conversion/unmeasured_score_conversion_spec.rb +71 -0
  98. data/spec/notation/conversion/unmeasured_score_converter_spec.rb +116 -0
  99. data/spec/notation/model/change_spec.rb +90 -0
  100. data/spec/notation/model/link_spec.rb +83 -0
  101. data/spec/notation/model/meter_spec.rb +97 -0
  102. data/spec/notation/model/note_spec.rb +183 -0
  103. data/spec/notation/model/part_spec.rb +69 -0
  104. data/spec/notation/model/pitch_spec.rb +180 -0
  105. data/spec/notation/model/program_spec.rb +50 -0
  106. data/spec/notation/model/score_spec.rb +211 -0
  107. data/spec/notation/packing/change_packing_spec.rb +153 -0
  108. data/spec/notation/packing/part_packing_spec.rb +66 -0
  109. data/spec/notation/packing/program_packing_spec.rb +33 -0
  110. data/spec/notation/packing/score_packing_spec.rb +301 -0
  111. data/spec/notation/parsing/articulation_parsing_spec.rb +23 -0
  112. data/spec/notation/parsing/convenience_methods_spec.rb +99 -0
  113. data/spec/notation/parsing/duration_nodes_spec.rb +83 -0
  114. data/spec/notation/parsing/duration_parsing_spec.rb +70 -0
  115. data/spec/notation/parsing/link_nodes_spec.rb +30 -0
  116. data/spec/notation/parsing/link_parsing_spec.rb +13 -0
  117. data/spec/notation/parsing/meter_parsing_spec.rb +23 -0
  118. data/spec/notation/parsing/note_node_spec.rb +87 -0
  119. data/spec/notation/parsing/note_parsing_spec.rb +46 -0
  120. data/spec/notation/parsing/numbers/nonnegative_float_spec.rb +28 -0
  121. data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +11 -0
  122. data/spec/notation/parsing/numbers/nonnegative_rational_spec.rb +11 -0
  123. data/spec/notation/parsing/numbers/positive_float_spec.rb +28 -0
  124. data/spec/notation/parsing/numbers/positive_integer_spec.rb +28 -0
  125. data/spec/notation/parsing/numbers/positive_rational_spec.rb +28 -0
  126. data/spec/notation/parsing/pitch_node_spec.rb +38 -0
  127. data/spec/notation/parsing/pitch_parsing_spec.rb +14 -0
  128. data/spec/notation/parsing/segment_parsing_spec.rb +27 -0
  129. data/spec/notation/util/value_computer_spec.rb +146 -0
  130. data/spec/performance/conversion/glissando_converter_spec.rb +93 -0
  131. data/spec/performance/conversion/note_sequence_extractor_spec.rb +230 -0
  132. data/spec/performance/conversion/portamento_converter_spec.rb +91 -0
  133. data/spec/performance/conversion/score_collator_spec.rb +183 -0
  134. data/spec/performance/midi/midi_util_spec.rb +110 -0
  135. data/spec/performance/midi/part_sequencer_spec.rb +40 -0
  136. data/spec/performance/midi/score_sequencer_spec.rb +50 -0
  137. data/spec/performance/model/note_sequence_spec.rb +147 -0
  138. data/spec/performance/util/note_linker_spec.rb +68 -0
  139. data/spec/performance/util/optimization_spec.rb +73 -0
  140. data/spec/spec_helper.rb +43 -0
  141. metadata +323 -0
@@ -0,0 +1,59 @@
1
+ module Musicality
2
+ module Parsing
3
+
4
+ grammar Articulation
5
+ rule articulation
6
+ slur / legato / tenuto / portato / staccato / staccatissimo
7
+ end
8
+
9
+ rule slur
10
+ "=" {
11
+ def to_articulation
12
+ Musicality::Articulations::SLUR
13
+ end
14
+ }
15
+ end
16
+
17
+ rule legato
18
+ "|" {
19
+ def to_articulation
20
+ Musicality::Articulations::LEGATO
21
+ end
22
+ }
23
+ end
24
+
25
+ rule tenuto
26
+ "_" {
27
+ def to_articulation
28
+ Musicality::Articulations::TENUTO
29
+ end
30
+ }
31
+ end
32
+
33
+ rule portato
34
+ "%" {
35
+ def to_articulation
36
+ Musicality::Articulations::PORTATO
37
+ end
38
+ }
39
+ end
40
+
41
+ rule staccato
42
+ "." {
43
+ def to_articulation
44
+ Musicality::Articulations::STACCATO
45
+ end
46
+ }
47
+ end
48
+
49
+ rule staccatissimo
50
+ "'" {
51
+ def to_articulation
52
+ Musicality::Articulations::STACCATISSIMO
53
+ end
54
+ }
55
+ end
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,74 @@
1
+ module Musicality
2
+
3
+ class Duration
4
+ PARSER = Parsing::DurationParser.new
5
+ CONVERSION_METHOD = :to_r
6
+ include Parseable
7
+ end
8
+
9
+ class Pitch
10
+ PARSER = Parsing::PitchParser.new
11
+ CONVERSION_METHOD = :to_pitch
12
+ include Parseable
13
+ end
14
+
15
+ class Note
16
+ PARSER = Parsing::NoteParser.new
17
+ CONVERSION_METHOD = :to_note
18
+ include Parseable
19
+ end
20
+
21
+ class Meter
22
+ PARSER = Parsing::MeterParser.new
23
+ CONVERSION_METHOD = :to_meter
24
+ include Parseable
25
+ end
26
+
27
+ class Segment
28
+ PARSER = Parsing::SegmentParser.new
29
+ CONVERSION_METHOD = :to_range
30
+ include Parseable
31
+ end
32
+ end
33
+
34
+ class String
35
+ def to_duration
36
+ Musicality::Duration.parse(self)
37
+ end
38
+ alias :to_dur :to_duration
39
+ alias :to_d :to_duration
40
+
41
+ def to_durations pattern=" "
42
+ Musicality::Duration.split_parse(self, pattern)
43
+ end
44
+ alias :to_durs :to_durations
45
+ alias :to_ds :to_durations
46
+
47
+ def to_pitch
48
+ Musicality::Pitch.parse(self)
49
+ end
50
+ alias :to_p :to_pitch
51
+
52
+ def to_pitches pattern=" "
53
+ Musicality::Pitch.split_parse(self, pattern)
54
+ end
55
+ alias :to_ps :to_pitches
56
+
57
+ def to_note
58
+ Musicality::Note.parse(self)
59
+ end
60
+ alias :to_n :to_note
61
+
62
+ def to_notes pattern=" "
63
+ Musicality::Note.split_parse(self, pattern)
64
+ end
65
+ alias :to_ns :to_notes
66
+
67
+ def to_meter
68
+ Musicality::Meter.parse(self)
69
+ end
70
+
71
+ def to_segment
72
+ Musicality::Segment.parse(self)
73
+ end
74
+ end
@@ -0,0 +1,21 @@
1
+ module Musicality
2
+ module Parsing
3
+ class NumDenNode < Treetop::Runtime::SyntaxNode
4
+ def to_r
5
+ text_value.to_r
6
+ end
7
+ end
8
+
9
+ class NumOnlyNode < Treetop::Runtime::SyntaxNode
10
+ def to_r
11
+ Rational(numerator.text_value.to_i,1)
12
+ end
13
+ end
14
+
15
+ class DenOnlyNode < Treetop::Runtime::SyntaxNode
16
+ def to_r
17
+ Rational(1,denominator.text_value.to_i)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,205 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Musicality
5
+ module Parsing
6
+
7
+ module Duration
8
+ include Treetop::Runtime
9
+
10
+ def root
11
+ @root ||= :duration
12
+ end
13
+
14
+ include PositiveInteger
15
+
16
+ def _nt_duration
17
+ start_index = index
18
+ if node_cache[:duration].has_key?(index)
19
+ cached = node_cache[:duration][index]
20
+ if cached
21
+ node_cache[:duration][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
22
+ @index = cached.interval.end
23
+ end
24
+ return cached
25
+ end
26
+
27
+ i0 = index
28
+ r1 = _nt_num_and_den
29
+ if r1
30
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
31
+ r0 = r1
32
+ else
33
+ r2 = _nt_num_only
34
+ if r2
35
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
36
+ r0 = r2
37
+ else
38
+ r3 = _nt_den_only
39
+ if r3
40
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
41
+ r0 = r3
42
+ else
43
+ @index = i0
44
+ r0 = nil
45
+ end
46
+ end
47
+ end
48
+
49
+ node_cache[:duration][start_index] = r0
50
+
51
+ r0
52
+ end
53
+
54
+ module NumAndDen0
55
+ def positive_integer1
56
+ elements[0]
57
+ end
58
+
59
+ def positive_integer2
60
+ elements[2]
61
+ end
62
+ end
63
+
64
+ def _nt_num_and_den
65
+ start_index = index
66
+ if node_cache[:num_and_den].has_key?(index)
67
+ cached = node_cache[:num_and_den][index]
68
+ if cached
69
+ node_cache[:num_and_den][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
70
+ @index = cached.interval.end
71
+ end
72
+ return cached
73
+ end
74
+
75
+ i0, s0 = index, []
76
+ r1 = _nt_positive_integer
77
+ s0 << r1
78
+ if r1
79
+ if (match_len = has_terminal?("/", false, index))
80
+ r2 = true
81
+ @index += match_len
82
+ else
83
+ terminal_parse_failure("/")
84
+ r2 = nil
85
+ end
86
+ s0 << r2
87
+ if r2
88
+ r3 = _nt_positive_integer
89
+ s0 << r3
90
+ end
91
+ end
92
+ if s0.last
93
+ r0 = instantiate_node(NumDenNode,input, i0...index, s0)
94
+ r0.extend(NumAndDen0)
95
+ else
96
+ @index = i0
97
+ r0 = nil
98
+ end
99
+
100
+ node_cache[:num_and_den][start_index] = r0
101
+
102
+ r0
103
+ end
104
+
105
+ module NumOnly0
106
+ def numerator
107
+ elements[0]
108
+ end
109
+
110
+ end
111
+
112
+ def _nt_num_only
113
+ start_index = index
114
+ if node_cache[:num_only].has_key?(index)
115
+ cached = node_cache[:num_only][index]
116
+ if cached
117
+ node_cache[:num_only][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
118
+ @index = cached.interval.end
119
+ end
120
+ return cached
121
+ end
122
+
123
+ i0, s0 = index, []
124
+ r1 = _nt_positive_integer
125
+ s0 << r1
126
+ if r1
127
+ if (match_len = has_terminal?("/", false, index))
128
+ r3 = true
129
+ @index += match_len
130
+ else
131
+ terminal_parse_failure("/")
132
+ r3 = nil
133
+ end
134
+ if r3
135
+ r2 = r3
136
+ else
137
+ r2 = instantiate_node(SyntaxNode,input, index...index)
138
+ end
139
+ s0 << r2
140
+ end
141
+ if s0.last
142
+ r0 = instantiate_node(NumOnlyNode,input, i0...index, s0)
143
+ r0.extend(NumOnly0)
144
+ else
145
+ @index = i0
146
+ r0 = nil
147
+ end
148
+
149
+ node_cache[:num_only][start_index] = r0
150
+
151
+ r0
152
+ end
153
+
154
+ module DenOnly0
155
+ def denominator
156
+ elements[1]
157
+ end
158
+ end
159
+
160
+ def _nt_den_only
161
+ start_index = index
162
+ if node_cache[:den_only].has_key?(index)
163
+ cached = node_cache[:den_only][index]
164
+ if cached
165
+ node_cache[:den_only][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
166
+ @index = cached.interval.end
167
+ end
168
+ return cached
169
+ end
170
+
171
+ i0, s0 = index, []
172
+ if (match_len = has_terminal?("/", false, index))
173
+ r1 = true
174
+ @index += match_len
175
+ else
176
+ terminal_parse_failure("/")
177
+ r1 = nil
178
+ end
179
+ s0 << r1
180
+ if r1
181
+ r2 = _nt_positive_integer
182
+ s0 << r2
183
+ end
184
+ if s0.last
185
+ r0 = instantiate_node(DenOnlyNode,input, i0...index, s0)
186
+ r0.extend(DenOnly0)
187
+ else
188
+ @index = i0
189
+ r0 = nil
190
+ end
191
+
192
+ node_cache[:den_only][start_index] = r0
193
+
194
+ r0
195
+ end
196
+
197
+ end
198
+
199
+ class DurationParser < Treetop::Runtime::CompiledParser
200
+ include Duration
201
+ end
202
+
203
+
204
+ end
205
+ end
@@ -0,0 +1,25 @@
1
+ module Musicality
2
+ module Parsing
3
+
4
+ grammar Duration
5
+ include PositiveInteger
6
+
7
+ rule duration
8
+ num_and_den / num_only / den_only
9
+ end
10
+
11
+ rule num_and_den
12
+ positive_integer "/" positive_integer <NumDenNode>
13
+ end
14
+
15
+ rule num_only
16
+ numerator:positive_integer "/"? <NumOnlyNode>
17
+ end
18
+
19
+ rule den_only
20
+ "/" denominator:positive_integer <DenOnlyNode>
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ module Musicality
2
+ module Parsing
3
+ class LinkNode < Treetop::Runtime::SyntaxNode; end
4
+
5
+ class SlurNode < LinkNode
6
+ def to_link
7
+ Musicality::Link::Slur.new(target.to_pitch)
8
+ end
9
+ end
10
+
11
+ class LegatoNode < LinkNode
12
+ def to_link
13
+ Musicality::Link::Legato.new(target.to_pitch)
14
+ end
15
+ end
16
+
17
+ class GlissandoNode < LinkNode
18
+ def to_link
19
+ Musicality::Link::Glissando.new(target.to_pitch)
20
+ end
21
+ end
22
+
23
+ class PortamentoNode < LinkNode
24
+ def to_link
25
+ Musicality::Link::Portamento.new(target.to_pitch)
26
+ end
27
+ end
28
+
29
+ class TieNode < LinkNode
30
+ def to_link
31
+ Musicality::Link::Tie.new
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,270 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Musicality
5
+ module Parsing
6
+
7
+ module Link
8
+ include Treetop::Runtime
9
+
10
+ def root
11
+ @root ||= :link
12
+ end
13
+
14
+ include Pitch
15
+
16
+ def _nt_link
17
+ start_index = index
18
+ if node_cache[:link].has_key?(index)
19
+ cached = node_cache[:link][index]
20
+ if cached
21
+ node_cache[:link][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
22
+ @index = cached.interval.end
23
+ end
24
+ return cached
25
+ end
26
+
27
+ i0 = index
28
+ r1 = _nt_slur_link
29
+ if r1
30
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
31
+ r0 = r1
32
+ else
33
+ r2 = _nt_tie
34
+ if r2
35
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
36
+ r0 = r2
37
+ else
38
+ r3 = _nt_legato_link
39
+ if r3
40
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
41
+ r0 = r3
42
+ else
43
+ r4 = _nt_glissando
44
+ if r4
45
+ r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
46
+ r0 = r4
47
+ else
48
+ r5 = _nt_portamento
49
+ if r5
50
+ r5 = SyntaxNode.new(input, (index-1)...index) if r5 == true
51
+ r0 = r5
52
+ else
53
+ @index = i0
54
+ r0 = nil
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ node_cache[:link][start_index] = r0
62
+
63
+ r0
64
+ end
65
+
66
+ module SlurLink0
67
+ def target
68
+ elements[1]
69
+ end
70
+ end
71
+
72
+ def _nt_slur_link
73
+ start_index = index
74
+ if node_cache[:slur_link].has_key?(index)
75
+ cached = node_cache[:slur_link][index]
76
+ if cached
77
+ node_cache[:slur_link][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
78
+ @index = cached.interval.end
79
+ end
80
+ return cached
81
+ end
82
+
83
+ i0, s0 = index, []
84
+ if (match_len = has_terminal?("=", false, index))
85
+ r1 = true
86
+ @index += match_len
87
+ else
88
+ terminal_parse_failure("=")
89
+ r1 = nil
90
+ end
91
+ s0 << r1
92
+ if r1
93
+ r2 = _nt_pitch
94
+ s0 << r2
95
+ end
96
+ if s0.last
97
+ r0 = instantiate_node(SlurNode,input, i0...index, s0)
98
+ r0.extend(SlurLink0)
99
+ else
100
+ @index = i0
101
+ r0 = nil
102
+ end
103
+
104
+ node_cache[:slur_link][start_index] = r0
105
+
106
+ r0
107
+ end
108
+
109
+ def _nt_tie
110
+ start_index = index
111
+ if node_cache[:tie].has_key?(index)
112
+ cached = node_cache[:tie][index]
113
+ if cached
114
+ node_cache[:tie][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
115
+ @index = cached.interval.end
116
+ end
117
+ return cached
118
+ end
119
+
120
+ if (match_len = has_terminal?("=", false, index))
121
+ r0 = instantiate_node(TieNode,input, index...(index + match_len))
122
+ @index += match_len
123
+ else
124
+ terminal_parse_failure("=")
125
+ r0 = nil
126
+ end
127
+
128
+ node_cache[:tie][start_index] = r0
129
+
130
+ r0
131
+ end
132
+
133
+ module LegatoLink0
134
+ def target
135
+ elements[1]
136
+ end
137
+ end
138
+
139
+ def _nt_legato_link
140
+ start_index = index
141
+ if node_cache[:legato_link].has_key?(index)
142
+ cached = node_cache[:legato_link][index]
143
+ if cached
144
+ node_cache[:legato_link][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
145
+ @index = cached.interval.end
146
+ end
147
+ return cached
148
+ end
149
+
150
+ i0, s0 = index, []
151
+ if (match_len = has_terminal?("|", false, index))
152
+ r1 = true
153
+ @index += match_len
154
+ else
155
+ terminal_parse_failure("|")
156
+ r1 = nil
157
+ end
158
+ s0 << r1
159
+ if r1
160
+ r2 = _nt_pitch
161
+ s0 << r2
162
+ end
163
+ if s0.last
164
+ r0 = instantiate_node(LegatoNode,input, i0...index, s0)
165
+ r0.extend(LegatoLink0)
166
+ else
167
+ @index = i0
168
+ r0 = nil
169
+ end
170
+
171
+ node_cache[:legato_link][start_index] = r0
172
+
173
+ r0
174
+ end
175
+
176
+ module Glissando0
177
+ def target
178
+ elements[1]
179
+ end
180
+ end
181
+
182
+ def _nt_glissando
183
+ start_index = index
184
+ if node_cache[:glissando].has_key?(index)
185
+ cached = node_cache[:glissando][index]
186
+ if cached
187
+ node_cache[:glissando][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
188
+ @index = cached.interval.end
189
+ end
190
+ return cached
191
+ end
192
+
193
+ i0, s0 = index, []
194
+ if (match_len = has_terminal?("~", false, index))
195
+ r1 = true
196
+ @index += match_len
197
+ else
198
+ terminal_parse_failure("~")
199
+ r1 = nil
200
+ end
201
+ s0 << r1
202
+ if r1
203
+ r2 = _nt_pitch
204
+ s0 << r2
205
+ end
206
+ if s0.last
207
+ r0 = instantiate_node(GlissandoNode,input, i0...index, s0)
208
+ r0.extend(Glissando0)
209
+ else
210
+ @index = i0
211
+ r0 = nil
212
+ end
213
+
214
+ node_cache[:glissando][start_index] = r0
215
+
216
+ r0
217
+ end
218
+
219
+ module Portamento0
220
+ def target
221
+ elements[1]
222
+ end
223
+ end
224
+
225
+ def _nt_portamento
226
+ start_index = index
227
+ if node_cache[:portamento].has_key?(index)
228
+ cached = node_cache[:portamento][index]
229
+ if cached
230
+ node_cache[:portamento][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
231
+ @index = cached.interval.end
232
+ end
233
+ return cached
234
+ end
235
+
236
+ i0, s0 = index, []
237
+ if (match_len = has_terminal?("/", false, index))
238
+ r1 = true
239
+ @index += match_len
240
+ else
241
+ terminal_parse_failure("/")
242
+ r1 = nil
243
+ end
244
+ s0 << r1
245
+ if r1
246
+ r2 = _nt_pitch
247
+ s0 << r2
248
+ end
249
+ if s0.last
250
+ r0 = instantiate_node(PortamentoNode,input, i0...index, s0)
251
+ r0.extend(Portamento0)
252
+ else
253
+ @index = i0
254
+ r0 = nil
255
+ end
256
+
257
+ node_cache[:portamento][start_index] = r0
258
+
259
+ r0
260
+ end
261
+
262
+ end
263
+
264
+ class LinkParser < Treetop::Runtime::CompiledParser
265
+ include Link
266
+ end
267
+
268
+
269
+ end
270
+ end
@@ -0,0 +1,33 @@
1
+ module Musicality
2
+ module Parsing
3
+
4
+ grammar Link
5
+ include Pitch
6
+
7
+ rule link
8
+ slur_link / tie / legato_link / glissando / portamento
9
+ end
10
+
11
+ rule slur_link
12
+ "=" target:pitch <SlurNode>
13
+ end
14
+
15
+ rule tie
16
+ "=" <TieNode>
17
+ end
18
+
19
+ rule legato_link
20
+ "|" target:pitch <LegatoNode>
21
+ end
22
+
23
+ rule glissando
24
+ "~" target:pitch <GlissandoNode>
25
+ end
26
+
27
+ rule portamento
28
+ "/" target:pitch <PortamentoNode>
29
+ end
30
+ end
31
+
32
+ end
33
+ end