musicality 0.8.0 → 0.9.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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +27 -1
  3. data/README.md +153 -10
  4. data/bin/collidify +102 -0
  5. data/bin/lilify +57 -29
  6. data/bin/midify +64 -24
  7. data/bin/musicality +39 -0
  8. data/examples/composition/auto_counterpoint.rb +4 -5
  9. data/examples/composition/part_generator.rb +8 -2
  10. data/examples/composition/scale_exercise.rb +1 -1
  11. data/examples/notation/notes.rb +27 -0
  12. data/examples/notation/parts.rb +51 -0
  13. data/examples/notation/scores.rb +38 -0
  14. data/examples/notation/twinkle.rb +34 -0
  15. data/examples/notation/twinkle.score +33 -0
  16. data/lib/musicality.rb +46 -11
  17. data/lib/musicality/composition/dsl/score_dsl.rb +2 -2
  18. data/lib/musicality/composition/dsl/score_methods.rb +10 -7
  19. data/lib/musicality/notation/conversion/change_conversion.rb +1 -1
  20. data/lib/musicality/notation/conversion/note_time_converter.rb +6 -23
  21. data/lib/musicality/notation/conversion/score_conversion.rb +15 -15
  22. data/lib/musicality/notation/conversion/score_converter.rb +50 -67
  23. data/lib/musicality/notation/model/articulations.rb +3 -2
  24. data/lib/musicality/notation/model/change.rb +15 -6
  25. data/lib/musicality/notation/model/dynamics.rb +11 -8
  26. data/lib/musicality/notation/model/instrument.rb +61 -0
  27. data/lib/musicality/notation/model/instruments.rb +111 -0
  28. data/lib/musicality/notation/model/key.rb +137 -0
  29. data/lib/musicality/notation/model/keys.rb +37 -0
  30. data/lib/musicality/notation/model/link.rb +6 -19
  31. data/lib/musicality/notation/model/mark.rb +43 -0
  32. data/lib/musicality/notation/model/marks.rb +11 -0
  33. data/lib/musicality/notation/model/meter.rb +4 -0
  34. data/lib/musicality/notation/model/note.rb +42 -28
  35. data/lib/musicality/notation/model/part.rb +18 -5
  36. data/lib/musicality/notation/model/pitch.rb +13 -4
  37. data/lib/musicality/notation/model/score.rb +104 -66
  38. data/lib/musicality/notation/model/symbols.rb +16 -11
  39. data/lib/musicality/notation/parsing/articulation_parsing.rb +38 -38
  40. data/lib/musicality/notation/parsing/articulation_parsing.treetop +14 -14
  41. data/lib/musicality/notation/parsing/link_parsing.rb +6 -6
  42. data/lib/musicality/notation/parsing/link_parsing.treetop +3 -3
  43. data/lib/musicality/notation/parsing/mark_parsing.rb +138 -0
  44. data/lib/musicality/notation/parsing/mark_parsing.treetop +31 -0
  45. data/lib/musicality/notation/parsing/note_node.rb +19 -12
  46. data/lib/musicality/notation/parsing/note_parsing.rb +218 -87
  47. data/lib/musicality/notation/parsing/note_parsing.treetop +9 -5
  48. data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +7 -2
  49. data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.treetop +1 -1
  50. data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.rb +6 -4
  51. data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.treetop +1 -1
  52. data/lib/musicality/notation/util/function.rb +41 -18
  53. data/lib/musicality/packable.rb +156 -0
  54. data/lib/musicality/performance/conversion/glissando_converter.rb +2 -2
  55. data/lib/musicality/performance/conversion/note_sequence_extractor.rb +223 -70
  56. data/lib/musicality/performance/conversion/portamento_converter.rb +5 -2
  57. data/lib/musicality/performance/conversion/score_collator.rb +70 -64
  58. data/lib/musicality/performance/midi/midi_events.rb +3 -3
  59. data/lib/musicality/performance/midi/midi_settings.rb +127 -0
  60. data/lib/musicality/performance/midi/midi_util.rb +8 -2
  61. data/lib/musicality/performance/midi/part_sequencer.rb +19 -18
  62. data/lib/musicality/performance/midi/score_sequencer.rb +13 -9
  63. data/lib/musicality/performance/midi/score_sequencing.rb +5 -5
  64. data/lib/musicality/performance/model/attack.rb +8 -0
  65. data/lib/musicality/performance/model/duration_functions.rb +23 -0
  66. data/lib/musicality/performance/model/note_sequence.rb +52 -95
  67. data/lib/musicality/performance/model/separation.rb +10 -0
  68. data/lib/musicality/performance/supercollider/add_actions.rb +13 -0
  69. data/lib/musicality/performance/supercollider/bundle.rb +18 -0
  70. data/lib/musicality/performance/supercollider/conductor.rb +125 -0
  71. data/lib/musicality/performance/supercollider/group.rb +71 -0
  72. data/lib/musicality/performance/supercollider/message.rb +26 -0
  73. data/lib/musicality/performance/supercollider/node.rb +122 -0
  74. data/lib/musicality/performance/supercollider/performer.rb +123 -0
  75. data/lib/musicality/performance/supercollider/score_conducting.rb +17 -0
  76. data/lib/musicality/performance/supercollider/server.rb +8 -0
  77. data/lib/musicality/performance/supercollider/synth.rb +43 -0
  78. data/lib/musicality/performance/supercollider/synthdef.rb +57 -0
  79. data/lib/musicality/performance/supercollider/synthdef_settings.rb +23 -0
  80. data/lib/musicality/performance/supercollider/synthdefs.rb +1654 -0
  81. data/lib/musicality/{composition/model/pitch_class.rb → pitch_class.rb} +1 -1
  82. data/lib/musicality/{composition/model/pitch_classes.rb → pitch_classes.rb} +9 -9
  83. data/lib/musicality/printing/lilypond/clef.rb +12 -0
  84. data/lib/musicality/printing/lilypond/key_engraving.rb +9 -0
  85. data/lib/musicality/printing/lilypond/lilypond_settings.rb +105 -0
  86. data/lib/musicality/printing/lilypond/meter_engraving.rb +1 -1
  87. data/lib/musicality/printing/lilypond/note_engraving.rb +112 -30
  88. data/lib/musicality/printing/lilypond/part_engraver.rb +114 -3
  89. data/lib/musicality/printing/lilypond/pitch_class_engraving.rb +22 -0
  90. data/lib/musicality/printing/lilypond/pitch_engraving.rb +2 -15
  91. data/lib/musicality/printing/lilypond/score_engraver.rb +44 -73
  92. data/lib/musicality/printing/lilypond/score_engraving.rb +3 -3
  93. data/lib/musicality/project/create_tasks.rb +31 -0
  94. data/lib/musicality/project/file_cleaner.rb +19 -0
  95. data/lib/musicality/project/file_raker.rb +107 -0
  96. data/lib/musicality/project/load_config.rb +43 -0
  97. data/lib/musicality/project/project.rb +64 -0
  98. data/lib/musicality/version.rb +1 -1
  99. data/musicality.gemspec +3 -0
  100. data/spec/composition/util/random_sampler_spec.rb +1 -1
  101. data/spec/notation/conversion/measure_note_map_spec.rb +1 -1
  102. data/spec/notation/conversion/note_time_converter_spec.rb +5 -85
  103. data/spec/notation/conversion/score_conversion_spec.rb +6 -41
  104. data/spec/notation/conversion/score_converter_spec.rb +19 -137
  105. data/spec/notation/model/change_spec.rb +55 -0
  106. data/spec/notation/model/key_spec.rb +171 -0
  107. data/spec/notation/model/link_spec.rb +34 -5
  108. data/spec/notation/model/meter_spec.rb +15 -0
  109. data/spec/notation/model/note_spec.rb +33 -27
  110. data/spec/notation/model/part_spec.rb +53 -4
  111. data/spec/notation/model/pitch_spec.rb +15 -0
  112. data/spec/notation/model/score_spec.rb +64 -72
  113. data/spec/notation/parsing/link_nodes_spec.rb +3 -3
  114. data/spec/notation/parsing/link_parsing_spec.rb +6 -6
  115. data/spec/notation/parsing/note_node_spec.rb +34 -9
  116. data/spec/notation/parsing/note_parsing_spec.rb +11 -9
  117. data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +4 -0
  118. data/spec/notation/parsing/pitch_node_spec.rb +0 -1
  119. data/spec/notation/util/value_computer_spec.rb +2 -2
  120. data/spec/performance/conversion/glissando_converter_spec.rb +9 -9
  121. data/spec/performance/conversion/note_sequence_extractor_spec.rb +48 -53
  122. data/spec/performance/conversion/portamento_converter_spec.rb +11 -9
  123. data/spec/performance/conversion/score_collator_spec.rb +59 -63
  124. data/spec/performance/midi/midi_util_spec.rb +22 -8
  125. data/spec/performance/midi/part_sequencer_spec.rb +2 -2
  126. data/spec/performance/midi/score_sequencer_spec.rb +12 -10
  127. data/spec/performance/midi/score_sequencing_spec.rb +2 -2
  128. data/spec/performance/model/note_sequence_spec.rb +41 -134
  129. data/spec/printing/note_engraving_spec.rb +204 -0
  130. data/spec/printing/score_engraver_spec.rb +40 -0
  131. data/spec/spec_helper.rb +1 -0
  132. metadata +69 -23
  133. data/examples/notation/hip.rb +0 -32
  134. data/examples/notation/missed_connection.rb +0 -26
  135. data/examples/notation/song1.rb +0 -33
  136. data/examples/notation/song2.rb +0 -32
  137. data/lib/musicality/notation/model/links.rb +0 -11
  138. data/lib/musicality/notation/packing/change_packing.rb +0 -56
  139. data/lib/musicality/notation/packing/part_packing.rb +0 -31
  140. data/lib/musicality/notation/packing/score_packing.rb +0 -123
  141. data/lib/musicality/performance/model/note_attacks.rb +0 -19
  142. data/lib/musicality/performance/util/note_linker.rb +0 -28
  143. data/spec/notation/packing/change_packing_spec.rb +0 -304
  144. data/spec/notation/packing/part_packing_spec.rb +0 -66
  145. data/spec/notation/packing/score_packing_spec.rb +0 -255
  146. data/spec/performance/util/note_linker_spec.rb +0 -68
@@ -1,66 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- describe Part do
4
- before :all do
5
- @p = Part.new(
6
- Dynamics::MP,
7
- notes: Note.split_parse("/4Bb2 /8 /8F3= /2F3 /4Bb2 /8 /8F3= /2F3"),
8
- dynamic_changes: {
9
- 1 => Change::Immediate.new(Dynamics::PP),
10
- 2 => Change::Gradual.linear(Dynamics::FF, 2.0)
11
- }
12
- )
13
-
14
- @h = @p.pack
15
- end
16
-
17
- describe '#pack' do
18
- it 'should produce a hash' do
19
- @h.should be_a Hash
20
- end
21
-
22
- it 'should return a hash with keys: "notes", "start_dynamic", and "dynamic_changes"' do
23
- @h.keys.should include("notes")
24
- @h.keys.should include("start_dynamic")
25
- @h.keys.should include("dynamic_changes")
26
- end
27
-
28
- it 'should pack notes into a string' do
29
- @h['notes'].should be_a String
30
- end
31
-
32
- it 'should pack start dynamic as plain numeric value' do
33
- @h['start_dynamic'].should be_a Numeric
34
- end
35
-
36
- it 'should pack dynamic changes as whatver type Change#pack returns' do
37
- @h['dynamic_changes'].each do |offset,packed_v|
38
- change_v = @p.dynamic_changes[offset]
39
- t = change_v.pack.class
40
- packed_v.should be_a t
41
- end
42
- end
43
- end
44
-
45
- describe '.unpack' do
46
- before :all do
47
- @p2 = Part.unpack @h
48
- end
49
-
50
- it 'should return a Part' do
51
- @p2.should be_a Part
52
- end
53
-
54
- it 'should successfuly unpack the notes' do
55
- @p2.notes.should eq @p.notes
56
- end
57
-
58
- it 'should successfuly unpack the start dynamic' do
59
- @p2.start_dynamic.should eq @p.start_dynamic
60
- end
61
-
62
- it 'should successfuly unpack the dynamic changes' do
63
- @p2.dynamic_changes.should eq @p.dynamic_changes
64
- end
65
- end
66
- end
@@ -1,255 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- measured_score = Score::Measured.new(FOUR_FOUR,120) do |s|
4
- s.title "The best song ever"
5
- s.composer "James T."
6
-
7
- s.meter_changes[1] = Change::Immediate.new(THREE_FOUR)
8
- s.meter_changes[7] = Change::Immediate.new(SIX_EIGHT)
9
-
10
- s.tempo_changes[2] = Change::Immediate.new(100)
11
- s.tempo_changes[4] = Change::Gradual.linear(70,2)
12
- s.tempo_changes[9] = Change::Gradual.sigmoid(99,5).trim(2,2)
13
-
14
- s.program += [0...2, 0...2,2...4,0...2]
15
- s.parts["lead"] = Part.new(Dynamics::MF) do |p|
16
- riff = "/6Bb3 /4 /12Db4= /6Db4= /36Db4 /36Eb4 /36Db4 /6Ab3 /12Db4 \
17
- /6Bb3 /4 /12Db4= /4Db4= /8Db4= /8C4".to_notes
18
- p.notes = riff + riff.map {|n| n.transpose(2) }
19
- p.dynamic_changes[1] = Change::Gradual.linear(Dynamics::F,2)
20
- end
21
-
22
- s.parts["bass"] = Part.new(Dynamics::MP) do |p|
23
- riff = "/6Bb2 /4 /3Ab2 /6F2 /12Ab2 \
24
- /6Bb2 /4 /3Ab2 /4Ab2".to_notes
25
- p.notes = riff + riff.map {|n| n.transpose(2) }
26
- p.dynamic_changes[1] = Change::Immediate.new(Dynamics::F)
27
- p.dynamic_changes[3] = Change::Gradual.sigmoid(Dynamics::PP,4).trim(1,1)
28
- end
29
- end
30
-
31
- unmeasured_score = Score::Unmeasured.new(30) do |s|
32
- s.program = measured_score.program
33
- s.parts = measured_score.parts
34
- s.title measured_score.title
35
- s.composer measured_score.composer
36
- end
37
-
38
- timed_score = Score::Timed.new do |s|
39
- s.program = measured_score.program
40
- s.parts = measured_score.parts
41
- s.title measured_score.title
42
- s.composer measured_score.composer
43
- end
44
-
45
- [ measured_score, unmeasured_score, timed_score ].each do |score|
46
- describe score.class do
47
- before :all do
48
- @score = score
49
- @h = @score.pack
50
- end
51
-
52
- describe '#pack' do
53
- it 'should return a hash' do
54
- @h.should be_a Hash
55
- end
56
-
57
- it 'should return a hash with keys: "type","parts", and "program"' do
58
- ["type","parts","program"].each do |key|
59
- @h.should have_key(key)
60
- end
61
- end
62
-
63
- it 'should pack program as an array with same size' do
64
- @h['program'].should be_a Array
65
- @h['program'].size.should eq(@score.program.size)
66
- end
67
-
68
- it 'should pack program segments as strings' do
69
- @h['program'].each {|x| x.should be_a String }
70
- end
71
-
72
- it 'should pack parts as hash' do
73
- @h['parts'].should be_a Hash
74
- end
75
-
76
- it 'should pack parts as whatever Part#pack returns' do
77
- @score.parts.each do |name,part|
78
- packing = part.pack
79
- @h['parts'][name].should eq packing
80
- end
81
- end
82
-
83
- it 'should add title to packing' do
84
- @h.should have_key "title"
85
- @h["title"].should eq @score.title
86
- end
87
-
88
- it 'should add composer to packing' do
89
- @h.should have_key "composer"
90
- @h["composer"].should eq @score.composer
91
- end
92
- end
93
-
94
- describe '.unpack' do
95
- before :all do
96
- @score2 = score.class.unpack @h
97
- end
98
-
99
- it "should return a #{score.class}" do
100
- @score2.should be_a score.class
101
- end
102
-
103
- it 'should successfuly unpack the parts' do
104
- @score2.parts.should eq @score.parts
105
- end
106
-
107
- it 'should successfuly unpack the program' do
108
- @score2.program.should eq @score.program
109
- end
110
-
111
- it 'should successfuly unpack the title' do
112
- @score2.title.should eq @score.title
113
- end
114
-
115
- it 'should successfuly unpack the composer' do
116
- @score2.composer.should eq @score.composer
117
- end
118
- end
119
- end
120
- end
121
-
122
- [ measured_score, unmeasured_score ].each do |score|
123
- describe score.class do
124
- before :all do
125
- @score = score
126
- @h = @score.pack
127
- end
128
-
129
- describe '#pack' do
130
- it 'should return a hash with keys: "start_tempo" and "tempo_changes"' do
131
- ["start_tempo","tempo_changes"].each {|key| @h.should have_key(key) }
132
- end
133
-
134
- it 'should pack start tempo as numeric' do
135
- @h['start_tempo'].should be_a Numeric
136
- end
137
-
138
- it 'should pack tempo changes as a hash' do
139
- @h['tempo_changes'].should be_a Hash
140
- end
141
-
142
- it 'should pack tempo changes values using Change#pack' do
143
- @h['tempo_changes'].each do |offset,packed_v|
144
- change = @score.tempo_changes[offset]
145
- packed_v.should eq(change.pack)
146
- end
147
- end
148
- end
149
-
150
- describe '.unpack' do
151
- before :all do
152
- @score2 = score.class.unpack @h
153
- end
154
-
155
- it 'should successfuly unpack the start tempo' do
156
- @score2.start_tempo.should eq @score.start_tempo
157
- end
158
-
159
- it 'should successfuly unpack the tempo changes' do
160
- @score2.tempo_changes.should eq @score.tempo_changes
161
- end
162
- end
163
- end
164
- end
165
-
166
- describe Score::Measured do
167
- before :all do
168
- @score = measured_score
169
- @h = @score.pack
170
- end
171
-
172
- describe '#pack' do
173
- it 'should return a hash with keys: "start_meter" and "meter_changes"' do
174
- ["start_meter","meter_changes"].each { |key| @h.should have_key(key) }
175
- end
176
-
177
- it 'should set "type" key to "Measured"' do
178
- @h["type"].should eq("Measured")
179
- end
180
-
181
- it 'should pack start meter as a string' do
182
- @h['start_meter'].should be_a String
183
- end
184
-
185
- it 'should pack meter changes values using Change#pack(:with => :to_s)' do
186
- @h['meter_changes'].each do |offset,packed_v|
187
- change = @score.meter_changes[offset]
188
- packed_v.should eq(change.pack(:with => :to_s))
189
- end
190
- end
191
-
192
- it 'should pack meter change end values as strings' do
193
- @h['meter_changes'].each do |offset,packed_v|
194
- packed_v["end_value"].should be_a String
195
- end
196
- end
197
- end
198
-
199
- describe '.unpack' do
200
- before :all do
201
- @score2 = Score::Measured.unpack @h
202
- end
203
-
204
- it 'should successfuly unpack the start meter' do
205
- @score2.start_meter.should eq @score.start_meter
206
- end
207
-
208
- it 'should successfuly unpack the meter changes' do
209
- @score2.meter_changes.should eq @score.meter_changes
210
- end
211
- end
212
- end
213
-
214
- describe Score::Unmeasured do
215
- describe '#pack' do
216
- it 'should set "type" key to "Unmeasured"' do
217
- unmeasured_score.pack["type"].should eq("Unmeasured")
218
- end
219
- end
220
- end
221
-
222
- describe Score::Timed do
223
- before :all do
224
- @score = timed_score
225
- @h = @score.pack
226
- end
227
-
228
- describe '#pack' do
229
- it 'should set "type" key to "Timed"' do
230
- @h["type"].should eq("Timed")
231
- end
232
- end
233
- end
234
-
235
- describe Score do
236
- describe '.unpack' do
237
- [ timed_score, unmeasured_score, measured_score ].each do |score|
238
- context "given packing from a #{score.class} object" do
239
- before :all do
240
- @packing = score.pack
241
- @score2 = Score.unpack(@packing)
242
- end
243
-
244
- it "should return a #{score.class} object equal to original" do
245
- @score2.should be_a score.class
246
- @score2.should eq(score)
247
- end
248
-
249
- it "should return a score equal to what #{score.class}.unpack returns" do
250
- @score2.should eq(score.class.unpack(@packing))
251
- end
252
- end
253
- end
254
- end
255
- end
@@ -1,68 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- describe NoteLinker do
4
- describe '.find_unlinked_pitches' do
5
- {
6
- 'note has no pitches' => [Note.quarter,[]],
7
- 'note has 1 pitch, no links' => [Note.quarter([C4]),[C4]],
8
- 'note has 2 pitches, no links' => [Note.quarter([C4,E4]),[C4,E4]],
9
- 'note has 1 pitch, which is linked' => [Note.quarter([C4], links: {C4 => Link::Tie.new} ),[]],
10
- 'note has 2 pitch, 1 of which is linked' => [Note.quarter([C4,E4], links: {C4 => Link::Tie.new} ),[E4]],
11
- 'note has 2 pitches, both of which are linked' => [Note.quarter([C4,E4], links: {C4 => Link::Tie.new, E4 => Link::Tie.new} ),[]],
12
- 'note has 1 pitch, and 1 unrelated link' => [Note.quarter([C4], links: {D4 => Link::Tie.new}),[C4]],
13
- 'note has 2 pitch, and 2 unrelated links' => [Note.quarter([C4,E4], links: {D4 => Link::Tie.new, F4 => Link::Tie.new}),[C4,E4]],
14
- }.each do |descr,given_expected|
15
- context descr do
16
- given, expected = given_expected
17
- it "should return #{expected}" do
18
- actual = NoteLinker.find_unlinked_pitches(given)
19
- actual.should eq(expected)
20
- end
21
- end
22
- end
23
- end
24
-
25
- describe '.find_untargeted_pitches' do
26
- {
27
- 'note has no pitches, next note has no pitches' => [Note.quarter,Note.quarter,[]],
28
- 'note has no pitches, next note has 3 pitch' => [Note.quarter,Note.quarter([C3,E3,F3]),[C3,E3,F3]],
29
- 'note has 3 pitches + no links, next note has 2 pitches' => [Note.quarter([C3,E3,F3]),Note.quarter([D2,F2]),[D2,F2]],
30
- 'note has 1 pitch + 1 unrelated link, next note has 1 pitch' => [Note.quarter([C3], links: {C3 => Link::Slur.new(C2)}),Note.quarter([D2]),[D2]],
31
- 'note has 1 pitch + 1 related link, next note has 1 pitch' => [Note.quarter([C3], links: {C3 => Link::Slur.new(D2)}),Note.quarter([D2]),[]],
32
- 'note has 2 pitches + 2 related link, next note has 2 pitches' => [Note.quarter([C3,E3], links: {C3 => Link::Slur.new(D2), E3 => Link::Slur.new(E2) }),Note.quarter([D2,E2]),[]],
33
- 'note has 2 pitches + 1 unrelated link, next note has 2 pitches' => [Note.quarter([C3,E3], links: {C3 => Link::Slur.new(D2), E3 => Link::Slur.new(F2) }),Note.quarter([D2,E2]),[E2]],
34
- }.each do |descr,given_expected|
35
- context descr do
36
- given_note, given_next_note, expected = given_expected
37
- it "should return #{expected}" do
38
- actual = NoteLinker.find_untargeted_pitches(given_note, given_next_note)
39
- actual.should eq(expected)
40
- end
41
- end
42
- end
43
- end
44
-
45
- describe '.fully_link' do
46
- [
47
- [ Note.quarter([C4,E4,G4]), Note.quarter, Note.quarter([C4,E4,G4]) ],
48
- [ Note.quarter([G4]), Note.quarter([A4]), Note.quarter([G4], links: {G4 => Link::Slur.new(A4)}) ],
49
- [
50
- Note.quarter([G4,A4]),
51
- Note.quarter([A4]),
52
- Note.quarter([G4,A4], links: {A4 => Link::Slur.new(A4)})
53
- ],
54
- [
55
- Note.quarter([G4,A4], links: {A4 => Link::Slur.new(B4)}),
56
- Note.quarter([A4,B4]),
57
- Note.quarter([G4,A4], links: {G4 => Link::Slur.new(A4), A4 => Link::Slur.new(B4)})
58
- ],
59
- ].each do |note,next_note,modified|
60
- context "given note: #{note.to_s}, next_note: #{next_note.to_s}" do
61
- it "should modifiy note to equal #{modified.to_s}" do
62
- NoteLinker.fully_link(note, next_note, Link::Slur)
63
- note.should eq(modified)
64
- end
65
- end
66
- end
67
- end
68
- end