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.
- checksums.yaml +4 -4
- data/ChangeLog.md +27 -1
- data/README.md +153 -10
- data/bin/collidify +102 -0
- data/bin/lilify +57 -29
- data/bin/midify +64 -24
- data/bin/musicality +39 -0
- data/examples/composition/auto_counterpoint.rb +4 -5
- data/examples/composition/part_generator.rb +8 -2
- data/examples/composition/scale_exercise.rb +1 -1
- data/examples/notation/notes.rb +27 -0
- data/examples/notation/parts.rb +51 -0
- data/examples/notation/scores.rb +38 -0
- data/examples/notation/twinkle.rb +34 -0
- data/examples/notation/twinkle.score +33 -0
- data/lib/musicality.rb +46 -11
- data/lib/musicality/composition/dsl/score_dsl.rb +2 -2
- data/lib/musicality/composition/dsl/score_methods.rb +10 -7
- data/lib/musicality/notation/conversion/change_conversion.rb +1 -1
- data/lib/musicality/notation/conversion/note_time_converter.rb +6 -23
- data/lib/musicality/notation/conversion/score_conversion.rb +15 -15
- data/lib/musicality/notation/conversion/score_converter.rb +50 -67
- data/lib/musicality/notation/model/articulations.rb +3 -2
- data/lib/musicality/notation/model/change.rb +15 -6
- data/lib/musicality/notation/model/dynamics.rb +11 -8
- data/lib/musicality/notation/model/instrument.rb +61 -0
- data/lib/musicality/notation/model/instruments.rb +111 -0
- data/lib/musicality/notation/model/key.rb +137 -0
- data/lib/musicality/notation/model/keys.rb +37 -0
- data/lib/musicality/notation/model/link.rb +6 -19
- data/lib/musicality/notation/model/mark.rb +43 -0
- data/lib/musicality/notation/model/marks.rb +11 -0
- data/lib/musicality/notation/model/meter.rb +4 -0
- data/lib/musicality/notation/model/note.rb +42 -28
- data/lib/musicality/notation/model/part.rb +18 -5
- data/lib/musicality/notation/model/pitch.rb +13 -4
- data/lib/musicality/notation/model/score.rb +104 -66
- data/lib/musicality/notation/model/symbols.rb +16 -11
- data/lib/musicality/notation/parsing/articulation_parsing.rb +38 -38
- data/lib/musicality/notation/parsing/articulation_parsing.treetop +14 -14
- data/lib/musicality/notation/parsing/link_parsing.rb +6 -6
- data/lib/musicality/notation/parsing/link_parsing.treetop +3 -3
- data/lib/musicality/notation/parsing/mark_parsing.rb +138 -0
- data/lib/musicality/notation/parsing/mark_parsing.treetop +31 -0
- data/lib/musicality/notation/parsing/note_node.rb +19 -12
- data/lib/musicality/notation/parsing/note_parsing.rb +218 -87
- data/lib/musicality/notation/parsing/note_parsing.treetop +9 -5
- data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +7 -2
- data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.treetop +1 -1
- data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.rb +6 -4
- data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.treetop +1 -1
- data/lib/musicality/notation/util/function.rb +41 -18
- data/lib/musicality/packable.rb +156 -0
- data/lib/musicality/performance/conversion/glissando_converter.rb +2 -2
- data/lib/musicality/performance/conversion/note_sequence_extractor.rb +223 -70
- data/lib/musicality/performance/conversion/portamento_converter.rb +5 -2
- data/lib/musicality/performance/conversion/score_collator.rb +70 -64
- data/lib/musicality/performance/midi/midi_events.rb +3 -3
- data/lib/musicality/performance/midi/midi_settings.rb +127 -0
- data/lib/musicality/performance/midi/midi_util.rb +8 -2
- data/lib/musicality/performance/midi/part_sequencer.rb +19 -18
- data/lib/musicality/performance/midi/score_sequencer.rb +13 -9
- data/lib/musicality/performance/midi/score_sequencing.rb +5 -5
- data/lib/musicality/performance/model/attack.rb +8 -0
- data/lib/musicality/performance/model/duration_functions.rb +23 -0
- data/lib/musicality/performance/model/note_sequence.rb +52 -95
- data/lib/musicality/performance/model/separation.rb +10 -0
- data/lib/musicality/performance/supercollider/add_actions.rb +13 -0
- data/lib/musicality/performance/supercollider/bundle.rb +18 -0
- data/lib/musicality/performance/supercollider/conductor.rb +125 -0
- data/lib/musicality/performance/supercollider/group.rb +71 -0
- data/lib/musicality/performance/supercollider/message.rb +26 -0
- data/lib/musicality/performance/supercollider/node.rb +122 -0
- data/lib/musicality/performance/supercollider/performer.rb +123 -0
- data/lib/musicality/performance/supercollider/score_conducting.rb +17 -0
- data/lib/musicality/performance/supercollider/server.rb +8 -0
- data/lib/musicality/performance/supercollider/synth.rb +43 -0
- data/lib/musicality/performance/supercollider/synthdef.rb +57 -0
- data/lib/musicality/performance/supercollider/synthdef_settings.rb +23 -0
- data/lib/musicality/performance/supercollider/synthdefs.rb +1654 -0
- data/lib/musicality/{composition/model/pitch_class.rb → pitch_class.rb} +1 -1
- data/lib/musicality/{composition/model/pitch_classes.rb → pitch_classes.rb} +9 -9
- data/lib/musicality/printing/lilypond/clef.rb +12 -0
- data/lib/musicality/printing/lilypond/key_engraving.rb +9 -0
- data/lib/musicality/printing/lilypond/lilypond_settings.rb +105 -0
- data/lib/musicality/printing/lilypond/meter_engraving.rb +1 -1
- data/lib/musicality/printing/lilypond/note_engraving.rb +112 -30
- data/lib/musicality/printing/lilypond/part_engraver.rb +114 -3
- data/lib/musicality/printing/lilypond/pitch_class_engraving.rb +22 -0
- data/lib/musicality/printing/lilypond/pitch_engraving.rb +2 -15
- data/lib/musicality/printing/lilypond/score_engraver.rb +44 -73
- data/lib/musicality/printing/lilypond/score_engraving.rb +3 -3
- data/lib/musicality/project/create_tasks.rb +31 -0
- data/lib/musicality/project/file_cleaner.rb +19 -0
- data/lib/musicality/project/file_raker.rb +107 -0
- data/lib/musicality/project/load_config.rb +43 -0
- data/lib/musicality/project/project.rb +64 -0
- data/lib/musicality/version.rb +1 -1
- data/musicality.gemspec +3 -0
- data/spec/composition/util/random_sampler_spec.rb +1 -1
- data/spec/notation/conversion/measure_note_map_spec.rb +1 -1
- data/spec/notation/conversion/note_time_converter_spec.rb +5 -85
- data/spec/notation/conversion/score_conversion_spec.rb +6 -41
- data/spec/notation/conversion/score_converter_spec.rb +19 -137
- data/spec/notation/model/change_spec.rb +55 -0
- data/spec/notation/model/key_spec.rb +171 -0
- data/spec/notation/model/link_spec.rb +34 -5
- data/spec/notation/model/meter_spec.rb +15 -0
- data/spec/notation/model/note_spec.rb +33 -27
- data/spec/notation/model/part_spec.rb +53 -4
- data/spec/notation/model/pitch_spec.rb +15 -0
- data/spec/notation/model/score_spec.rb +64 -72
- data/spec/notation/parsing/link_nodes_spec.rb +3 -3
- data/spec/notation/parsing/link_parsing_spec.rb +6 -6
- data/spec/notation/parsing/note_node_spec.rb +34 -9
- data/spec/notation/parsing/note_parsing_spec.rb +11 -9
- data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +4 -0
- data/spec/notation/parsing/pitch_node_spec.rb +0 -1
- data/spec/notation/util/value_computer_spec.rb +2 -2
- data/spec/performance/conversion/glissando_converter_spec.rb +9 -9
- data/spec/performance/conversion/note_sequence_extractor_spec.rb +48 -53
- data/spec/performance/conversion/portamento_converter_spec.rb +11 -9
- data/spec/performance/conversion/score_collator_spec.rb +59 -63
- data/spec/performance/midi/midi_util_spec.rb +22 -8
- data/spec/performance/midi/part_sequencer_spec.rb +2 -2
- data/spec/performance/midi/score_sequencer_spec.rb +12 -10
- data/spec/performance/midi/score_sequencing_spec.rb +2 -2
- data/spec/performance/model/note_sequence_spec.rb +41 -134
- data/spec/printing/note_engraving_spec.rb +204 -0
- data/spec/printing/score_engraver_spec.rb +40 -0
- data/spec/spec_helper.rb +1 -0
- metadata +69 -23
- data/examples/notation/hip.rb +0 -32
- data/examples/notation/missed_connection.rb +0 -26
- data/examples/notation/song1.rb +0 -33
- data/examples/notation/song2.rb +0 -32
- data/lib/musicality/notation/model/links.rb +0 -11
- data/lib/musicality/notation/packing/change_packing.rb +0 -56
- data/lib/musicality/notation/packing/part_packing.rb +0 -31
- data/lib/musicality/notation/packing/score_packing.rb +0 -123
- data/lib/musicality/performance/model/note_attacks.rb +0 -19
- data/lib/musicality/performance/util/note_linker.rb +0 -28
- data/spec/notation/packing/change_packing_spec.rb +0 -304
- data/spec/notation/packing/part_packing_spec.rb +0 -66
- data/spec/notation/packing/score_packing_spec.rb +0 -255
- 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
|