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
@@ -23,6 +23,22 @@ describe Change::Immediate do
|
|
23
23
|
YAML.load(c.to_yaml).should eq c
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
describe '#pack' do
|
28
|
+
it 'should produce a Hash' do
|
29
|
+
h = Change::Immediate.new(2).pack
|
30
|
+
h.should be_a Hash
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.unpack' do
|
35
|
+
it 'should return a Change::Immediate equal to the original' do
|
36
|
+
c1 = Change::Immediate.new(2)
|
37
|
+
c2 = Change::Immediate.unpack(c1.pack)
|
38
|
+
c2.should be_a Change::Immediate
|
39
|
+
c2.should eq c1
|
40
|
+
end
|
41
|
+
end
|
26
42
|
end
|
27
43
|
|
28
44
|
describe Change::Gradual do
|
@@ -122,6 +138,22 @@ describe Change::Gradual do
|
|
122
138
|
YAML.load(c.to_yaml).should eq c
|
123
139
|
end
|
124
140
|
end
|
141
|
+
|
142
|
+
describe '#pack' do
|
143
|
+
it 'should produce a Hash' do
|
144
|
+
h = Change::Gradual.linear(4,2).pack
|
145
|
+
h.should be_a Hash
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe '.unpack' do
|
150
|
+
it 'should return a Change::Gradual equal to the original' do
|
151
|
+
c1 = Change::Gradual.linear(4,2)
|
152
|
+
c2 = Change::Gradual.unpack(c1.pack)
|
153
|
+
c2.should be_a Change::Gradual
|
154
|
+
c2.should eq c1
|
155
|
+
end
|
156
|
+
end
|
125
157
|
end
|
126
158
|
|
127
159
|
describe Change::Gradual::Trimmed do
|
@@ -190,4 +222,27 @@ describe Change::Gradual::Trimmed do
|
|
190
222
|
Change::Gradual.linear(41,19).trim(4,9).trailing.should eq(9)
|
191
223
|
end
|
192
224
|
end
|
225
|
+
|
226
|
+
describe '#to_yaml' do
|
227
|
+
it 'should produce YAML that can be loaded' do
|
228
|
+
c = Change::Gradual::Trimmed.linear(4,2, preceding: 1, remaining: 0.5)
|
229
|
+
YAML.load(c.to_yaml).should eq c
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe '#pack' do
|
234
|
+
it 'should produce a Hash' do
|
235
|
+
h = Change::Gradual::Trimmed.linear(4,2, preceding: 1, remaining: 0.5).pack
|
236
|
+
h.should be_a Hash
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe '.unpack' do
|
241
|
+
it 'should return a Change::Gradual::Trimmed equal to the original' do
|
242
|
+
c1 = Change::Gradual::Trimmed.linear(4,2, preceding: 1, remaining: 0.5)
|
243
|
+
c2 = Change::Gradual::Trimmed.unpack(c1.pack)
|
244
|
+
c2.should be_a Change::Gradual::Trimmed
|
245
|
+
c2.should eq c1
|
246
|
+
end
|
247
|
+
end
|
193
248
|
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Key do
|
4
|
+
describe '.major_flat' do
|
5
|
+
it 'should set triad to MAJOR and accidental_pref to FLAT' do
|
6
|
+
k = Key.major_flat(0)
|
7
|
+
k.triad.should eq(Key::MAJOR)
|
8
|
+
k.accidental_pref.should eq(Key::FLAT)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.minor_flat' do
|
13
|
+
it 'should set triad to MAJOR and accidental_pref to SHARP' do
|
14
|
+
k = Key.major_sharp(0)
|
15
|
+
k.triad.should eq(Key::MAJOR)
|
16
|
+
k.accidental_pref.should eq(Key::SHARP)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.major_sharp' do
|
21
|
+
it 'should set triad to MINOR and accidental_pref to FLAT' do
|
22
|
+
k = Key.minor_flat(0)
|
23
|
+
k.triad.should eq(Key::MINOR)
|
24
|
+
k.accidental_pref.should eq(Key::FLAT)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '.minor_sharp' do
|
29
|
+
it 'should set triad to MINOR and accidental_pref to SHARP' do
|
30
|
+
k = Key.minor_sharp(0)
|
31
|
+
k.triad.should eq(Key::MINOR)
|
32
|
+
k.accidental_pref.should eq(Key::SHARP)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '.new' do
|
37
|
+
context 'given tonic_pc that is not in 0..11' do
|
38
|
+
it 'should apply mod 12 to bring it in range' do
|
39
|
+
{ 12 => 0, 13 => 1, -1 => 11, 24 => 0, 18 => 6
|
40
|
+
}.each do |t1,t2|
|
41
|
+
Key.major_flat(t1).tonic_pc.should eq(t2)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'given tonic_pc in 0..11' do
|
47
|
+
it 'should not change' do
|
48
|
+
(0..11).each do |pc|
|
49
|
+
Key.major_flat(pc).tonic_pc.should eq(pc)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'given triad that is not MAJOR or MINOR' do
|
55
|
+
it 'should raise ArgumentError' do
|
56
|
+
expect { Key.new(0, triad: :flipping) }.to raise_error(ArgumentError)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'given accidental_pref that is not FLAT or SHARP' do
|
61
|
+
it 'should raise ArgumentError' do
|
62
|
+
expect { Key.new(0, accidental_pref: :squiggle) }.to raise_error(ArgumentError)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#flat?' do
|
68
|
+
context 'given accidental_pref is FLAT' do
|
69
|
+
it 'should return true' do
|
70
|
+
Key.major_flat(0).flat?.should be true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
context 'given accidental_pref is SHARP' do
|
74
|
+
it 'should return false' do
|
75
|
+
Key.major_sharp(0).flat?.should be false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#sharp?' do
|
81
|
+
context 'given accidental_pref is FLAT' do
|
82
|
+
it 'should return false' do
|
83
|
+
Key.major_flat(0).sharp?.should be false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
context 'given accidental_pref is SHARP' do
|
87
|
+
it 'should return true' do
|
88
|
+
Key.major_sharp(0).sharp?.should be true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#major?' do
|
94
|
+
context 'given triad is MAJOR' do
|
95
|
+
it 'should return true' do
|
96
|
+
Key.major_flat(0).major?.should be true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
context 'given triad is MINOR' do
|
100
|
+
it 'should return false' do
|
101
|
+
Key.minor_flat(0).major?.should be false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#minor?' do
|
107
|
+
context 'given triad is MAJOR' do
|
108
|
+
it 'should return false' do
|
109
|
+
Key.major_flat(0).minor?.should be false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
context 'given triad is MINOR' do
|
113
|
+
it 'should return true' do
|
114
|
+
Key.minor_flat(0).minor?.should be true
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '#==' do
|
120
|
+
context 'objects with different tonic_pc' do
|
121
|
+
it 'should return false' do
|
122
|
+
Key.major_flat(0).should_not eq(Key.major_flat(1))
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'objects with different triad' do
|
127
|
+
it 'should return false' do
|
128
|
+
Key.major_flat(0).should_not eq(Key.minor_flat(0))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'objects with different accidental_type' do
|
133
|
+
it 'should return false' do
|
134
|
+
Key.major_flat(0).should_not eq(Key.major_sharp(0))
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'objects with same tonic_pc, triad, and accidental_type' do
|
139
|
+
it 'should return true' do
|
140
|
+
Key.major_flat(0).should eq(Key.major_flat(0))
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#clone' do
|
146
|
+
it 'should return a different, equal object' do
|
147
|
+
k1 = Key.major_flat(0)
|
148
|
+
k2 = k1.clone
|
149
|
+
k1.should_not be k2
|
150
|
+
k1.should eq k2
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe '#accidentals' do
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#pack' do
|
158
|
+
it 'should return a Hash' do
|
159
|
+
Key.major_sharp(1).pack.should be_a Hash
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe '.unpack' do
|
164
|
+
it 'should return a Key object equal to the original' do
|
165
|
+
k1 = Key.major_sharp(1)
|
166
|
+
k2 = Key.unpack k1.pack
|
167
|
+
k2.should be_a Key
|
168
|
+
k2.should eq(k1)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
[
|
4
|
-
[Link::Glissando, Link::Portamento, LINK_SYMBOLS[
|
5
|
-
[Link::Portamento, Link::Glissando, LINK_SYMBOLS[
|
5
|
+
[Link::Glissando, Link::Portamento, LINK_SYMBOLS[Link::Glissando]],
|
6
|
+
[Link::Portamento, Link::Glissando, LINK_SYMBOLS[Link::Portamento]],
|
6
7
|
].each do |klass,klass2,link_symbol|
|
7
8
|
describe klass do
|
8
9
|
before :all do
|
@@ -41,6 +42,20 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
41
42
|
YAML.load(@obj.to_yaml).should eq @obj
|
42
43
|
end
|
43
44
|
end
|
45
|
+
|
46
|
+
describe '#pack' do
|
47
|
+
it 'should produce a Hash' do
|
48
|
+
@obj.pack.should be_a Hash
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'unpack' do
|
53
|
+
it 'should produce a Link object equal the original' do
|
54
|
+
obj2 = @obj.class.unpack @obj.pack
|
55
|
+
obj2.should be_a @obj.class
|
56
|
+
obj2.should eq @obj
|
57
|
+
end
|
58
|
+
end
|
44
59
|
|
45
60
|
describe '#to_s' do
|
46
61
|
it 'should produce string that include link char and target pitch str' do
|
@@ -76,10 +91,24 @@ describe Link::Tie do
|
|
76
91
|
YAML.load(@obj.to_yaml).should eq @obj
|
77
92
|
end
|
78
93
|
end
|
79
|
-
|
94
|
+
|
95
|
+
describe '#pack' do
|
96
|
+
it 'should produce a Hash' do
|
97
|
+
@obj.pack.should be_a Hash
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'unpack' do
|
102
|
+
it 'should produce a Link object equal the original' do
|
103
|
+
obj2 = @obj.class.unpack @obj.pack
|
104
|
+
obj2.should be_a @obj.class
|
105
|
+
obj2.should eq @obj
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
80
109
|
describe '#to_s' do
|
81
|
-
it "should return #{LINK_SYMBOLS[
|
82
|
-
@obj.to_s.should eq(LINK_SYMBOLS[
|
110
|
+
it "should return #{LINK_SYMBOLS[Link::Tie]}" do
|
111
|
+
@obj.to_s.should eq(LINK_SYMBOLS[Link::Tie])
|
83
112
|
end
|
84
113
|
end
|
85
114
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
describe Meter do
|
4
5
|
describe '#initialize' do
|
@@ -47,6 +48,20 @@ describe Meter do
|
|
47
48
|
YAML.load(m.to_yaml).should eq m
|
48
49
|
end
|
49
50
|
end
|
51
|
+
|
52
|
+
describe '#pack' do
|
53
|
+
it 'should produce a Hash' do
|
54
|
+
FOUR_FOUR.pack.should be_a Hash
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'unpack' do
|
59
|
+
it 'should produce an object equal the original' do
|
60
|
+
m2 = Meter.unpack FOUR_FOUR.pack
|
61
|
+
m2.should be_a Meter
|
62
|
+
m2.should eq(FOUR_FOUR)
|
63
|
+
end
|
64
|
+
end
|
50
65
|
|
51
66
|
describe '#to_s' do
|
52
67
|
context 'beat duration with 1 in denominator' do
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
describe Note do
|
4
5
|
before :all do
|
@@ -10,20 +11,24 @@ describe Note do
|
|
10
11
|
Note.new(2).duration.should eq(2)
|
11
12
|
end
|
12
13
|
|
13
|
-
it "should assign :articulation to
|
14
|
-
Note.new(2).articulation.should eq(
|
14
|
+
it "should assign :articulation to NORMAL if not given" do
|
15
|
+
Note.new(2).articulation.should eq(NORMAL)
|
15
16
|
end
|
16
17
|
|
17
18
|
it "should assign :articulation parameter if given during construction" do
|
18
19
|
Note.new(2, articulation: STACCATO).articulation.should eq(STACCATO)
|
19
20
|
end
|
20
21
|
|
21
|
-
it 'should assign :
|
22
|
-
Note.new(2).
|
22
|
+
it 'should assign :marks to [] if not given' do
|
23
|
+
Note.new(2).marks.should eq([])
|
23
24
|
end
|
24
25
|
|
25
|
-
it 'should assign :
|
26
|
-
|
26
|
+
it 'should assign :marks if given' do
|
27
|
+
[
|
28
|
+
[], [BEGIN_SLUR, BEGIN_TRIPLET]
|
29
|
+
].each do |marks|
|
30
|
+
Note.quarter(marks: marks).marks.should eq(marks)
|
31
|
+
end
|
27
32
|
end
|
28
33
|
|
29
34
|
it 'should have no pitches if not given' do
|
@@ -95,13 +100,10 @@ describe Note do
|
|
95
100
|
end
|
96
101
|
end
|
97
102
|
|
98
|
-
describe '#
|
99
|
-
it 'should
|
100
|
-
note = Note::quarter.
|
103
|
+
describe '#resize' do
|
104
|
+
it 'should return new note object with given duration' do
|
105
|
+
note = Note::quarter.resize("1/2".to_r)
|
101
106
|
note.duration.should eq(Rational(1,2))
|
102
|
-
|
103
|
-
note = Note::quarter.stretch(Rational(1,2))
|
104
|
-
note.duration.should eq(Rational(1,8))
|
105
107
|
end
|
106
108
|
end
|
107
109
|
|
@@ -114,7 +116,7 @@ describe Note do
|
|
114
116
|
it 'should produce string that when parsed produces an equal note' do
|
115
117
|
durations = ["1/8".to_r,"1".to_r,"5/3".to_r]
|
116
118
|
include Articulations
|
117
|
-
articulations = [NORMAL,
|
119
|
+
articulations = [NORMAL, TENUTO, MARCATO, ACCENT, PORTATO, STACCATO, STACCATISSIMO ]
|
118
120
|
pitches_links_sets = [
|
119
121
|
[[],{}],
|
120
122
|
[[C2],{}],
|
@@ -129,8 +131,8 @@ describe Note do
|
|
129
131
|
pitches,links = pitches_links_set
|
130
132
|
if pitches.any?
|
131
133
|
articulations.each do |art|
|
132
|
-
[
|
133
|
-
notes.push Note.new(d, pitches, articulation: art, links: links,
|
134
|
+
[[],[BEGIN_SLUR],[END_SLUR, BEGIN_TRIPLET]].each do |marks|
|
135
|
+
notes.push Note.new(d, pitches, articulation: art, links: links, marks: marks)
|
134
136
|
end
|
135
137
|
end
|
136
138
|
else
|
@@ -163,6 +165,22 @@ describe Note do
|
|
163
165
|
YAML.load(n.to_yaml).should eq n
|
164
166
|
end
|
165
167
|
end
|
168
|
+
|
169
|
+
describe '#pack' do
|
170
|
+
it 'should produce a Hash' do
|
171
|
+
n = Note.quarter([E2,F2,A2], articulation: STACCATO, marks: [BEGIN_SLUR], links: {E2 => Link::Tie.new, F2 => Link::Glissando.new(C3)})
|
172
|
+
n.pack.should be_a Hash
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'unpack' do
|
177
|
+
it 'should produce an object equal the original' do
|
178
|
+
n = Note.quarter([E2,F2,A2], articulation: STACCATO, marks: [BEGIN_SLUR], links: {E2 => Link::Tie.new, F2 => Link::Glissando.new(C3)})
|
179
|
+
n2 = Note.unpack n.pack
|
180
|
+
n2.should be_a Note
|
181
|
+
n2.should eq n
|
182
|
+
end
|
183
|
+
end
|
166
184
|
|
167
185
|
describe '#valid?' do
|
168
186
|
context 'note with positive duration' do
|
@@ -170,17 +188,5 @@ describe Note do
|
|
170
188
|
Note.new(1,[C2]).should be_valid
|
171
189
|
end
|
172
190
|
end
|
173
|
-
|
174
|
-
context 'note with 0 duration' do
|
175
|
-
it 'should return false' do
|
176
|
-
Note.new(0,[C2]).should be_invalid
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
context 'note with negative duration' do
|
181
|
-
it 'should be invalid' do
|
182
|
-
Note.new(-1,[C2]).should be_invalid
|
183
|
-
end
|
184
|
-
end
|
185
191
|
end
|
186
192
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
describe Part do
|
4
5
|
describe '#initialize' do
|
@@ -17,16 +18,66 @@ describe Part do
|
|
17
18
|
p = Part.new(Dynamics::FF, notes: notes, dynamic_changes: dcs)
|
18
19
|
p.notes.should eq notes
|
19
20
|
p.dynamic_changes.should eq dcs
|
21
|
+
|
22
|
+
p = Part.new(Dynamics::P, settings: [ "dummy" ])
|
23
|
+
p.settings.should eq [ "dummy" ]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#find_settings' do
|
28
|
+
context 'settings is empty' do
|
29
|
+
it 'should return nil' do
|
30
|
+
Part.new(Dynamics::P).find_settings(Integer).should be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'one or more objects in settings' do
|
35
|
+
before :all do
|
36
|
+
@part = Part.new(Dynamics::MF, settings: [ 5, "boy" ])
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'given class of object in settings' do
|
40
|
+
it 'should return the object' do
|
41
|
+
@part.find_settings(Integer).should be_a Integer
|
42
|
+
@part.find_settings(String).should be_a String
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'given class not of any object in settings' do
|
47
|
+
it 'should return nil' do
|
48
|
+
@part.find_settings(Float).should be_nil
|
49
|
+
end
|
50
|
+
end
|
20
51
|
end
|
21
52
|
end
|
22
|
-
|
53
|
+
|
23
54
|
describe '#to_yaml' do
|
24
55
|
it 'should produce YAML that can be loaded' do
|
25
56
|
p = Samples::SAMPLE_PART
|
26
57
|
YAML.load(p.to_yaml).should eq p
|
27
58
|
end
|
28
59
|
end
|
29
|
-
|
60
|
+
|
61
|
+
describe '#pack' do
|
62
|
+
it 'should produce a Hash' do
|
63
|
+
notes = [Note::whole([A2]), Note::half]
|
64
|
+
dcs = { "1/2".to_r => Change::Immediate.new(Dynamics::P), 1 => Change::Gradual.sigmoid(Dynamics::MF,1) }
|
65
|
+
p = Part.new(Dynamics::FF, notes: notes, dynamic_changes: dcs, settings: [ "dummy" ])
|
66
|
+
p.pack.should be_a Hash
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'unpack' do
|
71
|
+
it 'should produce an object equal the original' do
|
72
|
+
notes = [Note::whole([A2]), Note::half]
|
73
|
+
dcs = { "1/2".to_r => Change::Immediate.new(Dynamics::P), 1 => Change::Gradual.sigmoid(Dynamics::MF,1) }
|
74
|
+
p = Part.new(Dynamics::FF, notes: notes, dynamic_changes: dcs, settings: [ "dummy" ])
|
75
|
+
p2 = Part.unpack p.pack
|
76
|
+
p2.should be_a Part
|
77
|
+
p2.should eq p
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
30
81
|
describe '#valid?' do
|
31
82
|
{ 'negative start dynamic' => [-0.01],
|
32
83
|
'start dynamic > 1' => [1.01],
|
@@ -39,8 +90,6 @@ describe Part do
|
|
39
90
|
'dynamic change values outside 0..1' => [
|
40
91
|
0.5, :notes => [ Note::whole ],
|
41
92
|
:dynamic_changes => { 0.2 => Change::Immediate.new(-0.01), 0.3 => Change::Gradual.linear(1.01,0.2) }],
|
42
|
-
'notes with 0 duration' => [ 0.5, :notes => [ Note.new(0) ]],
|
43
|
-
'notes with negative duration' => [ 0.5, :notes => [ Note.new(-1) ]],
|
44
93
|
}.each do |context_str, args|
|
45
94
|
context context_str do
|
46
95
|
it 'should return false' do
|