musicality 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|