musicality 0.11.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.coveralls.yml +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +4 -0
- data/ChangeLog.md +11 -0
- data/README.md +3 -0
- data/Rakefile +11 -3
- data/lib/musicality/composition/model/rhythm.rb +33 -0
- data/lib/musicality/composition/model/rhythm_class.rb +30 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_kit.rb +18 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_machine.rb +59 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_parts.rb +21 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_pattern.rb +66 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_patterns/pop_drum_patterns.rb +146 -0
- data/lib/musicality/composition/sequencing/note_array.rb +33 -0
- data/lib/musicality/composition/sequencing/note_fifo.rb +73 -0
- data/lib/musicality/composition/sequencing/sequenceable.rb +9 -0
- data/lib/musicality/composition/sequencing/sequencer.rb +35 -0
- data/lib/musicality/errors.rb +2 -2
- data/lib/musicality/notation/model/dynamics.rb +2 -2
- data/lib/musicality/notation/model/key.rb +42 -91
- data/lib/musicality/notation/model/keys.rb +35 -34
- data/lib/musicality/notation/model/note.rb +31 -9
- data/lib/musicality/notation/model/pitch.rb +2 -2
- data/lib/musicality/notation/parsing/convenience_methods.rb +23 -12
- data/lib/musicality/notation/parsing/duration_parsing.rb +3 -3
- data/lib/musicality/notation/parsing/key_parsing.rb +150 -0
- data/lib/musicality/notation/parsing/key_parsing.treetop +37 -0
- data/lib/musicality/notation/parsing/meter_parsing.rb +3 -3
- data/lib/musicality/notation/parsing/numbers/nonnegative_float_parsing.rb +3 -1
- data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +1 -0
- data/lib/musicality/notation/parsing/numbers/nonnegative_rational_parsing.rb +1 -1
- data/lib/musicality/notation/parsing/numbers/positive_float_parsing.rb +4 -1
- data/lib/musicality/notation/parsing/numbers/positive_rational_parsing.rb +1 -1
- data/lib/musicality/notation/parsing/parseable.rb +13 -17
- data/lib/musicality/notation/parsing/pitch_parsing.rb +7 -0
- data/lib/musicality/notation/parsing/segment_parsing.rb +3 -0
- data/lib/musicality/performance/conversion/note_sequence_extractor.rb +82 -134
- data/lib/musicality/performance/model/note_sequence.rb +22 -3
- data/lib/musicality/performance/supercollider/performer.rb +2 -2
- data/lib/musicality/performance/supercollider/sc_drum_kits.rb +29 -0
- data/lib/musicality/performance/supercollider/synthdefs/bass.rb +211 -0
- data/lib/musicality/performance/supercollider/synthdefs/claps.rb +80 -0
- data/lib/musicality/performance/supercollider/synthdefs/cymbals.rb +57 -0
- data/lib/musicality/performance/supercollider/synthdefs/hihats.rb +67 -0
- data/lib/musicality/performance/supercollider/synthdefs/kicks.rb +158 -0
- data/lib/musicality/performance/supercollider/synthdefs/mario.rb +49 -0
- data/lib/musicality/performance/supercollider/{synthdefs.rb → synthdefs/other.rb} +0 -767
- data/lib/musicality/performance/supercollider/synthdefs/pianos.rb +46 -0
- data/lib/musicality/performance/supercollider/synthdefs/snares.rb +169 -0
- data/lib/musicality/performance/supercollider/synthdefs/toms.rb +25 -0
- data/lib/musicality/performance/supercollider/synthdefs/volume.rb +20 -0
- data/lib/musicality/pitch_class.rb +1 -1
- data/lib/musicality/pitch_classes.rb +3 -5
- data/lib/musicality/version.rb +1 -1
- data/lib/musicality.rb +25 -1
- data/musicality.gemspec +3 -2
- data/spec/composition/convenience_methods_spec.rb +8 -8
- data/spec/composition/generation/random_rhythm_generator_spec.rb +5 -5
- data/spec/composition/model/pitch_class_spec.rb +22 -16
- data/spec/composition/model/pitch_classes_spec.rb +5 -5
- data/spec/composition/model/rhythm_class_spec.rb +42 -0
- data/spec/composition/model/rhythm_spec.rb +43 -0
- data/spec/composition/model/scale_class_spec.rb +26 -26
- data/spec/composition/model/scale_spec.rb +38 -38
- data/spec/composition/sequencing/drum_machine/drum_machine_spec.rb +67 -0
- data/spec/composition/sequencing/drum_machine/drum_pattern_spec.rb +58 -0
- data/spec/composition/sequencing/note_array_spec.rb +94 -0
- data/spec/composition/sequencing/note_fifo_spec.rb +183 -0
- data/spec/composition/sequencing/sequencer_spec.rb +76 -0
- data/spec/composition/util/adding_sequence_spec.rb +33 -33
- data/spec/composition/util/compound_sequence_spec.rb +6 -6
- data/spec/composition/util/note_generation_spec.rb +34 -34
- data/spec/composition/util/probabilities_spec.rb +7 -7
- data/spec/composition/util/random_sampler_spec.rb +3 -3
- data/spec/composition/util/repeating_sequence_spec.rb +28 -28
- data/spec/musicality_spec.rb +1 -1
- data/spec/notation/conversion/change_conversion_spec.rb +87 -87
- data/spec/notation/conversion/note_time_converter_spec.rb +22 -22
- data/spec/notation/conversion/score_conversion_spec.rb +1 -1
- data/spec/notation/conversion/score_converter_spec.rb +31 -31
- data/spec/notation/conversion/tempo_conversion_spec.rb +11 -11
- data/spec/notation/model/change_spec.rb +80 -80
- data/spec/notation/model/key_spec.rb +135 -69
- data/spec/notation/model/link_spec.rb +27 -27
- data/spec/notation/model/meter_spec.rb +28 -28
- data/spec/notation/model/note_spec.rb +68 -47
- data/spec/notation/model/part_spec.rb +19 -19
- data/spec/notation/model/pitch_spec.rb +69 -68
- data/spec/notation/model/score_spec.rb +50 -47
- data/spec/notation/parsing/articulation_parsing_spec.rb +4 -4
- data/spec/notation/parsing/convenience_methods_spec.rb +49 -10
- data/spec/notation/parsing/duration_nodes_spec.rb +13 -13
- data/spec/notation/parsing/duration_parsing_spec.rb +10 -10
- data/spec/notation/parsing/key_parsing_spec.rb +19 -0
- data/spec/notation/parsing/link_nodes_spec.rb +7 -7
- data/spec/notation/parsing/link_parsing_spec.rb +4 -4
- data/spec/notation/parsing/meter_parsing_spec.rb +5 -5
- data/spec/notation/parsing/note_node_spec.rb +19 -19
- data/spec/notation/parsing/note_parsing_spec.rb +4 -4
- data/spec/notation/parsing/numbers/nonnegative_float_spec.rb +8 -8
- data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +2 -2
- data/spec/notation/parsing/numbers/nonnegative_rational_spec.rb +1 -1
- data/spec/notation/parsing/numbers/positive_float_spec.rb +8 -8
- data/spec/notation/parsing/numbers/positive_integer_spec.rb +6 -6
- data/spec/notation/parsing/numbers/positive_rational_spec.rb +6 -6
- data/spec/notation/parsing/pitch_node_spec.rb +7 -7
- data/spec/notation/parsing/pitch_parsing_spec.rb +2 -2
- data/spec/notation/parsing/segment_parsing_spec.rb +3 -3
- data/spec/notation/util/function_spec.rb +15 -15
- data/spec/notation/util/transition_spec.rb +12 -12
- data/spec/notation/util/value_computer_spec.rb +35 -36
- data/spec/performance/conversion/glissando_converter_spec.rb +24 -24
- data/spec/performance/conversion/note_sequence_extractor_spec.rb +39 -39
- data/spec/performance/conversion/portamento_converter_spec.rb +23 -23
- data/spec/performance/midi/midi_util_spec.rb +41 -41
- data/spec/performance/midi/part_sequencer_spec.rb +10 -10
- data/spec/performance/midi/score_sequencer_spec.rb +15 -15
- data/spec/performance/midi/score_sequencing_spec.rb +2 -2
- data/spec/performance/util/optimization_spec.rb +9 -9
- data/spec/printing/note_engraving_spec.rb +16 -16
- data/spec/printing/score_engraver_spec.rb +5 -5
- data/spec/spec_helper.rb +5 -0
- metadata +85 -30
@@ -4,7 +4,7 @@ require 'yaml'
|
|
4
4
|
describe Pitch do
|
5
5
|
|
6
6
|
before :each do
|
7
|
-
@cases =
|
7
|
+
@cases =
|
8
8
|
[
|
9
9
|
{ :octave => 1, :semitone => 0, :cent => 0, :ratio => 2.0, :total_cents => 1200 },
|
10
10
|
{ :octave => 2, :semitone => 0, :cent => 0, :ratio => 4.0, :total_cents => 2400 },
|
@@ -21,32 +21,32 @@ describe Pitch do
|
|
21
21
|
{ :octave => -5, :semitone => -2, :cent => -77, :ratio => 0.02663, :total_cents => -6277 }
|
22
22
|
]
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it "should be constructable with no parameters (no error raised)" do
|
26
|
-
lambda { Pitch.new }.
|
26
|
+
expect(lambda { Pitch.new }).to_not raise_error
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it "should take keyword args" do
|
30
30
|
obj = Pitch.new octave: 4, semitone: 3, cent: 5
|
31
|
-
obj.octave.
|
32
|
-
obj.semitone.
|
33
|
-
obj.cent.
|
31
|
+
expect(obj.octave).to eq(4)
|
32
|
+
expect(obj.semitone).to eq(3)
|
33
|
+
expect(obj.cent).to eq(5)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
it "should use default octave, semitone, and cent if none is given" do
|
37
37
|
p = Pitch.new
|
38
|
-
p.ratio.
|
39
|
-
p.total_cents.
|
38
|
+
expect(p.ratio).to be_within(0.01).of(1.0)
|
39
|
+
expect(p.total_cents).to eq(0)
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
it "should use the octave and semitone given during construction" do
|
43
43
|
@cases.each do |case_data|
|
44
44
|
p = Pitch.new octave: case_data[:octave], semitone: case_data[:semitone], cent: case_data[:cent]
|
45
|
-
p.ratio.
|
46
|
-
p.total_cents.
|
45
|
+
expect(p.ratio).to be_within(0.01).of case_data[:ratio]
|
46
|
+
expect(p.total_cents).to be case_data[:total_cents]
|
47
47
|
end
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
describe '#diff' do
|
51
51
|
it 'should return the difference between the given pitch, in semitones' do
|
52
52
|
[
|
@@ -57,28 +57,28 @@ describe Pitch do
|
|
57
57
|
[A5,Pitch.new(octave:5, semitone: 5, cent: 22),378/100.0],
|
58
58
|
[A5,Pitch.new(octave:5, semitone: 11, cent: 85),-285/100.0],
|
59
59
|
].each do |a,b,c|
|
60
|
-
|
60
|
+
expect(a.diff(b)).to eq(c)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
describe '#transpose' do
|
66
66
|
it 'should make a new pitch, adding the given interval to total semitones' do
|
67
67
|
[0,1,2,5,12,13,-1,-2,-5,-12,-13].each do |interval|
|
68
68
|
pitch = Eb3.transpose(interval)
|
69
|
-
pitch.
|
70
|
-
pitch.diff(Eb3).
|
69
|
+
expect(pitch).to_not be Eb3
|
70
|
+
expect(pitch.diff(Eb3)).to eq(interval)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
describe '#+' do
|
76
76
|
it 'should produce same result as #transpose' do
|
77
77
|
[0,1,2,5,12,13,-1,-2,-5,-12,-13].each do |interval|
|
78
78
|
pitch = Eb3 + interval
|
79
|
-
pitch.
|
79
|
+
expect(pitch).to_not be Eb3
|
80
80
|
pitch2 = Eb3.transpose(interval)
|
81
|
-
pitch.
|
81
|
+
expect(pitch).to eq(pitch2)
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
@@ -87,37 +87,37 @@ describe Pitch do
|
|
87
87
|
it 'should produce same result as #transpose, with negative interval' do
|
88
88
|
[0,1,2,5,12,13,-1,-2,-5,-12,-13].each do |interval|
|
89
89
|
pitch = Eb3 - interval
|
90
|
-
pitch.
|
90
|
+
expect(pitch).to_not be Eb3
|
91
91
|
pitch2 = Eb3.transpose(-interval)
|
92
|
-
pitch.
|
92
|
+
expect(pitch).to eq(pitch2)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
97
|
describe '.total_semitones' do
|
98
98
|
it 'should convert to whole/fractional total semitones value' do
|
99
|
-
C4.total_semitones.
|
100
|
-
C5.total_semitones.
|
101
|
-
C4.transpose(0.1).total_semitones.
|
102
|
-
C5.transpose(0.19).total_semitones.
|
103
|
-
C5.transpose(-0.19).total_semitones.
|
99
|
+
expect(C4.total_semitones).to eq(48)
|
100
|
+
expect(C5.total_semitones).to eq(60)
|
101
|
+
expect(C4.transpose(0.1).total_semitones).to eq(48.1)
|
102
|
+
expect(C5.transpose(0.19).total_semitones).to eq(60.19)
|
103
|
+
expect(C5.transpose(-0.19).total_semitones).to eq(59.81)
|
104
104
|
end
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
describe '.from_semitones' do
|
108
108
|
it 'should convert (rounded) fractional part to cent value' do
|
109
|
-
Pitch.from_semitones(4).total_cents.
|
110
|
-
Pitch.from_semitones(4.11).total_cents.
|
111
|
-
Pitch.from_semitones(57.123).total_cents.
|
112
|
-
Pitch.from_semitones(57.125).total_cents.
|
109
|
+
expect(Pitch.from_semitones(4).total_cents).to eq(400)
|
110
|
+
expect(Pitch.from_semitones(4.11).total_cents).to eq(411)
|
111
|
+
expect(Pitch.from_semitones(57.123).total_cents).to eq(5712)
|
112
|
+
expect(Pitch.from_semitones(57.125).total_cents).to eq(5713)
|
113
113
|
end
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
describe '.from_ratio' do
|
117
117
|
it 'should return a Pitch with given ratio' do
|
118
118
|
@cases.each do |case_data|
|
119
119
|
p = Pitch.from_ratio case_data[:ratio]
|
120
|
-
p.total_cents.
|
120
|
+
expect(p.total_cents).to eq case_data[:total_cents]
|
121
121
|
end
|
122
122
|
end
|
123
123
|
end
|
@@ -125,93 +125,94 @@ describe Pitch do
|
|
125
125
|
describe '.from_freq' do
|
126
126
|
it 'should make a pitch whose freq is approximately the given freq' do
|
127
127
|
[16.35, 440.0, 987.77].each do |given_freq|
|
128
|
-
|
129
|
-
|
128
|
+
pitch = Pitch.from_freq given_freq
|
129
|
+
expect(pitch.freq).to be_within(0.01).of(given_freq)
|
130
130
|
end
|
131
131
|
end
|
132
132
|
end
|
133
|
-
|
133
|
+
|
134
134
|
it "should be comparable to other pitches" do
|
135
135
|
p1 = Pitch.new semitone: 1
|
136
136
|
p2 = Pitch.new semitone: 2
|
137
137
|
p3 = Pitch.new semitone: 3
|
138
138
|
|
139
|
-
p1.
|
140
|
-
p2.
|
141
|
-
p3.
|
142
|
-
|
143
|
-
p1.
|
144
|
-
p1.
|
145
|
-
p2.
|
146
|
-
p3.
|
147
|
-
p3.
|
148
|
-
p2.
|
149
|
-
end
|
150
|
-
|
139
|
+
expect(p1).to eq(Pitch.new semitone: 1)
|
140
|
+
expect(p2).to eq(Pitch.new semitone: 2)
|
141
|
+
expect(p3).to eq(Pitch.new semitone: 3)
|
142
|
+
|
143
|
+
expect(p1).to be < p2
|
144
|
+
expect(p1).to be < p3
|
145
|
+
expect(p2).to be < p3
|
146
|
+
expect(p3).to be > p2
|
147
|
+
expect(p3).to be > p1
|
148
|
+
expect(p2).to be > p1
|
149
|
+
end
|
150
|
+
|
151
151
|
it "should have freq of 440 for A4" do
|
152
152
|
a4 = Pitch.new octave: 4, semitone: 9
|
153
|
-
a4.freq.
|
153
|
+
expect(a4.freq).to be_within(0.01).of(440.0)
|
154
154
|
end
|
155
|
-
|
155
|
+
|
156
156
|
describe '#to_yaml' do
|
157
157
|
it 'should produce YAML that can be loaded' do
|
158
158
|
p = Pitch.new(octave: 1, semitone: 2)
|
159
|
-
YAML.load(p.to_yaml).
|
159
|
+
expect(YAML.load(p.to_yaml)).to eq p
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
163
163
|
describe '#pack' do
|
164
164
|
it 'should produce a Hash' do
|
165
|
-
Bb3.pack.
|
165
|
+
expect(Bb3.pack).to be_a Hash
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
169
169
|
describe 'unpack' do
|
170
170
|
it 'should produce an object equal the original' do
|
171
171
|
p2 = Pitch.unpack Bb3.pack
|
172
|
-
p2.
|
173
|
-
p2.
|
172
|
+
expect(p2).to be_a Pitch
|
173
|
+
expect(p2).to eq Bb3
|
174
174
|
end
|
175
175
|
end
|
176
|
-
|
176
|
+
|
177
177
|
describe '#to_s' do
|
178
178
|
context 'on-letter semitones' do
|
179
179
|
it 'should return the semitone letter + octave number' do
|
180
180
|
{ C0 => "C0", D1 => "D1", E7 => "E7",
|
181
181
|
F8 => "F8", G3 => "G3", A4 => "A4",
|
182
182
|
B5 => "B5", C2 => "C2" }.each do |p,s|
|
183
|
-
p.to_s.
|
183
|
+
expect(p.to_s).to eq s
|
184
184
|
end
|
185
185
|
end
|
186
186
|
end
|
187
|
-
|
187
|
+
|
188
188
|
context 'off-letter semitones' do
|
189
189
|
context 'sharpit set false' do
|
190
190
|
it 'should return semitone letter + "b" + octave number' do
|
191
191
|
{ Db0 => "Db0", Eb1 => "Eb1", Gb7 => "Gb7",
|
192
192
|
Ab4 => "Ab4", Bb1 => "Bb1" }.each do |p,s|
|
193
|
-
p.to_s(false).
|
193
|
+
expect(p.to_s(false)).to eq s
|
194
194
|
end
|
195
195
|
end
|
196
196
|
end
|
197
|
-
|
197
|
+
|
198
198
|
context 'sharpit set true' do
|
199
199
|
it 'should return semitone letter + "#" + octave number' do
|
200
200
|
{ Db0 => "C#0", Eb1 => "D#1", Gb7 => "F#7",
|
201
201
|
Ab4 => "G#4", Bb1 => "A#1" }.each do |p,s|
|
202
|
-
p.to_s(true).
|
202
|
+
expect(p.to_s(true)).to eq s
|
203
203
|
end
|
204
204
|
end
|
205
205
|
end
|
206
206
|
end
|
207
|
-
|
207
|
+
|
208
208
|
context 'non-zero cent value' do
|
209
209
|
it 'should append +n (n = cent value)' do
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
210
|
+
{
|
211
|
+
C0.transpose(0.01) => "C0+1", E1.transpose(0.15) => "E1+15",
|
212
|
+
G5.transpose(-0.55) => "Gb5+45"
|
213
|
+
}.each do |p,s|
|
214
|
+
expect(p.to_s).to eq s
|
215
|
+
end
|
215
216
|
end
|
216
217
|
end
|
217
218
|
end
|
@@ -4,7 +4,7 @@ describe Score do
|
|
4
4
|
describe '#title' do
|
5
5
|
context 'given no arg' do
|
6
6
|
it 'should return the title' do
|
7
|
-
Score.new(:title => "MyTitle").title.
|
7
|
+
expect(Score.new(:title => "MyTitle").title).to eq("MyTitle")
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
@@ -12,7 +12,7 @@ describe Score do
|
|
12
12
|
it 'should assign the given value to title' do
|
13
13
|
score = Score.new(:title => "MyTitle")
|
14
14
|
score.title("A Better Title")
|
15
|
-
score.title.
|
15
|
+
expect(score.title).to eq("A Better Title")
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -20,7 +20,7 @@ describe Score do
|
|
20
20
|
describe '#composer' do
|
21
21
|
context 'given no arg' do
|
22
22
|
it 'should return the composer' do
|
23
|
-
Score.new(:composer => "Beethoven").composer.
|
23
|
+
expect(Score.new(:composer => "Beethoven").composer).to eq("Beethoven")
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -28,7 +28,7 @@ describe Score do
|
|
28
28
|
it 'should assign the given value to composer' do
|
29
29
|
score = Score.new(:composer => "Beethoven")
|
30
30
|
score.composer("Mozart")
|
31
|
-
score.composer.
|
31
|
+
expect(score.composer).to eq("Mozart")
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -37,14 +37,14 @@ describe Score do
|
|
37
37
|
context 'has program with more than one segment' do
|
38
38
|
it 'should return false' do
|
39
39
|
score = Score.new(program: [0..2,0..2])
|
40
|
-
score.collated
|
40
|
+
expect(score.collated?).to be false
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
context 'has program with 0 segments' do
|
45
45
|
it 'should return false' do
|
46
46
|
score = Score.new(program: [])
|
47
|
-
score.collated
|
47
|
+
expect(score.collated?).to be false
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -55,7 +55,7 @@ describe Score do
|
|
55
55
|
score = Score.new(program: [0..2],
|
56
56
|
parts: { "dummy" => Part.new(Dynamics::MP, notes: [Note.whole]*2)}
|
57
57
|
)
|
58
|
-
score.collated
|
58
|
+
expect(score.collated?).to be true
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -64,9 +64,9 @@ describe Score do
|
|
64
64
|
score = Score.new(program: [0..1],
|
65
65
|
parts: { "dummy" => Part.new(Dynamics::MP, notes: [Note.whole]*2) }
|
66
66
|
)
|
67
|
-
score.collated
|
67
|
+
expect(score.collated?).to be false
|
68
68
|
score.program = [0..3]
|
69
|
-
score.collated
|
69
|
+
expect(score.collated?).to be false
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -74,7 +74,7 @@ describe Score do
|
|
74
74
|
context 'program segment does not start at 0' do
|
75
75
|
it 'should return false' do
|
76
76
|
score = Score.new(program: [1..2])
|
77
|
-
score.collated
|
77
|
+
expect(score.collated?).to be false
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -83,25 +83,25 @@ describe Score do
|
|
83
83
|
describe '#valid?' do
|
84
84
|
context 'non-Range objects' do
|
85
85
|
it 'should return false' do
|
86
|
-
Score.new(program: [1,2,3]).
|
86
|
+
expect(Score.new(program: [1,2,3])).to_not be_valid
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
context 'increasing, positive segments' do
|
91
91
|
it 'should return true' do
|
92
|
-
Score.new(program: [0..2,1..2,0..4]).
|
92
|
+
expect(Score.new(program: [0..2,1..2,0..4])).to be_valid
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
96
|
context 'decreasing, positive segments' do
|
97
97
|
it 'should return false' do
|
98
|
-
Score.new(program: [2..0,2..1,04..0]).
|
98
|
+
expect(Score.new(program: [2..0,2..1,04..0])).to be_invalid
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
102
|
context 'increasing, negative segments' do
|
103
103
|
it 'should return false' do
|
104
|
-
Score.new(program: [-1..2,-2..0,-2..2]).
|
104
|
+
expect(Score.new(program: [-1..2,-2..0,-2..2])).to be_invalid
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
@@ -126,15 +126,15 @@ describe Score::Tempo do
|
|
126
126
|
describe '#initialize' do
|
127
127
|
it 'should use empty containers for parameters not given' do
|
128
128
|
s = Score::Tempo.new(120)
|
129
|
-
s.parts.
|
130
|
-
s.program.
|
131
|
-
s.tempo_changes.
|
132
|
-
s.meter_changes.
|
129
|
+
expect(s.parts).to be_empty
|
130
|
+
expect(s.program).to be_empty
|
131
|
+
expect(s.tempo_changes).to be_empty
|
132
|
+
expect(s.meter_changes).to be_empty
|
133
133
|
end
|
134
134
|
|
135
135
|
it 'should assign given parameters' do
|
136
136
|
s = Score::Tempo.new(120)
|
137
|
-
s.start_tempo.
|
137
|
+
expect(s.start_tempo).to eq 120
|
138
138
|
|
139
139
|
m = FOUR_FOUR
|
140
140
|
parts = { "piano (LH)" => Samples::SAMPLE_PART }
|
@@ -149,34 +149,36 @@ describe Score::Tempo do
|
|
149
149
|
meter_changes: mcs,
|
150
150
|
tempo_changes: tcs
|
151
151
|
)
|
152
|
-
s.start_meter.
|
153
|
-
s.parts.
|
154
|
-
s.program.
|
155
|
-
s.meter_changes.
|
156
|
-
s.tempo_changes.
|
152
|
+
expect(s.start_meter).to eq m
|
153
|
+
expect(s.parts).to eq parts
|
154
|
+
expect(s.program).to eq program
|
155
|
+
expect(s.meter_changes).to eq mcs
|
156
|
+
expect(s.tempo_changes).to eq tcs
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
160
160
|
describe '#duration' do
|
161
161
|
context 'with no parts' do
|
162
162
|
it 'should return 0' do
|
163
|
-
Score::Tempo.new(120).duration.
|
163
|
+
expect(Score::Tempo.new(120).duration).to eq(0)
|
164
164
|
end
|
165
165
|
end
|
166
166
|
context 'with one part' do
|
167
167
|
it 'should return the duration of the part, in notes' do
|
168
|
-
Score::Tempo.new(120, parts: {
|
168
|
+
s = Score::Tempo.new(120, parts: {
|
169
169
|
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes)
|
170
|
-
})
|
170
|
+
})
|
171
|
+
expect(s.duration).to eq(1.75)
|
171
172
|
end
|
172
173
|
end
|
173
174
|
|
174
175
|
context 'with two parts' do
|
175
176
|
it 'should return the duration of the longest part, in notes' do
|
176
|
-
Score::Tempo.new(120, parts: {
|
177
|
+
s = Score::Tempo.new(120, parts: {
|
177
178
|
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes),
|
178
179
|
"def" => Part.new(Dynamics::MF, notes: "/4 /4 /2 1".to_notes)
|
179
|
-
})
|
180
|
+
})
|
181
|
+
expect(s.duration).to eq(2)
|
180
182
|
end
|
181
183
|
end
|
182
184
|
end
|
@@ -194,7 +196,7 @@ describe Score::Tempo do
|
|
194
196
|
}.each do |context_str,args|
|
195
197
|
context context_str do
|
196
198
|
it 'should return true' do
|
197
|
-
Score::Tempo.new(*args).
|
199
|
+
expect(Score::Tempo.new(*args)).to be_valid
|
198
200
|
end
|
199
201
|
end
|
200
202
|
end
|
@@ -215,7 +217,7 @@ describe Score::Tempo do
|
|
215
217
|
}.each do |context_str,args|
|
216
218
|
context context_str do
|
217
219
|
it 'should return false' do
|
218
|
-
Score::Tempo.new(*args).
|
220
|
+
expect(Score::Tempo.new(*args)).to be_invalid
|
219
221
|
end
|
220
222
|
end
|
221
223
|
end
|
@@ -223,25 +225,25 @@ describe Score::Tempo do
|
|
223
225
|
|
224
226
|
describe '#pack' do
|
225
227
|
it 'should produce a Hash' do
|
226
|
-
@basic_score.pack.
|
228
|
+
expect(@basic_score.pack).to be_a Hash
|
227
229
|
end
|
228
230
|
|
229
231
|
it 'should pack program as an array of strings' do
|
230
232
|
program = @basic_score.pack[:program]
|
231
|
-
program.each {|entry| entry.
|
233
|
+
program.each {|entry| expect(entry).to be_a String}
|
232
234
|
end
|
233
235
|
|
234
236
|
it 'should pack sections as a Hash of strings' do
|
235
237
|
program = @basic_score.pack[:sections]
|
236
|
-
program.each {|name,entry| entry.
|
238
|
+
program.each {|name,entry| expect(entry).to be_a String}
|
237
239
|
end
|
238
240
|
end
|
239
241
|
|
240
242
|
describe 'unpack' do
|
241
243
|
it 'should produce an object equal the original' do
|
242
244
|
score2 = Score::Tempo.unpack @basic_score.pack
|
243
|
-
score2.
|
244
|
-
score2.
|
245
|
+
expect(score2).to be_a Score
|
246
|
+
expect(score2).to eq @basic_score
|
245
247
|
end
|
246
248
|
end
|
247
249
|
end
|
@@ -250,8 +252,8 @@ describe Score::Timed do
|
|
250
252
|
describe '#initialize' do
|
251
253
|
it 'should use empty containers for parameters not given' do
|
252
254
|
s = Score::Timed.new
|
253
|
-
s.parts.
|
254
|
-
s.program.
|
255
|
+
expect(s.parts).to be_empty
|
256
|
+
expect(s.program).to be_empty
|
255
257
|
end
|
256
258
|
|
257
259
|
it 'should assign given parameters' do
|
@@ -259,17 +261,18 @@ describe Score::Timed do
|
|
259
261
|
program = [0...0.75, 0...0.75]
|
260
262
|
|
261
263
|
s = Score::Timed.new(parts: parts, program: program)
|
262
|
-
s.parts.
|
263
|
-
s.program.
|
264
|
+
expect(s.parts).to eq parts
|
265
|
+
expect(s.program).to eq program
|
264
266
|
end
|
265
267
|
end
|
266
268
|
|
267
269
|
describe '#duration' do
|
268
270
|
it 'should return the duration of the longest part' do
|
269
|
-
Score::Timed.new(parts: {
|
271
|
+
s = Score::Timed.new(parts: {
|
270
272
|
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes),
|
271
273
|
"def" => Part.new(Dynamics::MF, notes: "/4 /4 /2 1".to_notes)
|
272
|
-
})
|
274
|
+
})
|
275
|
+
expect(s.duration).to eq(2)
|
273
276
|
end
|
274
277
|
end
|
275
278
|
|
@@ -280,7 +283,7 @@ describe Score::Timed do
|
|
280
283
|
}.each do |context_str,args|
|
281
284
|
context context_str do
|
282
285
|
it 'should return true' do
|
283
|
-
Score::Timed.new(*args).
|
286
|
+
expect(Score::Timed.new(*args)).to be_valid
|
284
287
|
end
|
285
288
|
end
|
286
289
|
end
|
@@ -291,7 +294,7 @@ describe Score::Timed do
|
|
291
294
|
}.each do |context_str,args|
|
292
295
|
context context_str do
|
293
296
|
it 'should return false' do
|
294
|
-
Score::Timed.new(*args).
|
297
|
+
expect(Score::Timed.new(*args)).to be_invalid
|
295
298
|
end
|
296
299
|
end
|
297
300
|
end
|
@@ -303,7 +306,7 @@ describe Score::Timed do
|
|
303
306
|
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes),
|
304
307
|
"def" => Part.new(Dynamics::MF, notes: "/4 /4 /2 1".to_notes)
|
305
308
|
})
|
306
|
-
score.pack.
|
309
|
+
expect(score.pack).to be_a Hash
|
307
310
|
end
|
308
311
|
end
|
309
312
|
|
@@ -314,8 +317,8 @@ describe Score::Timed do
|
|
314
317
|
"def" => Part.new(Dynamics::MF, notes: "/4 /4 /2 1".to_notes)
|
315
318
|
})
|
316
319
|
score2 = Score::Timed.unpack score.pack
|
317
|
-
score2.
|
318
|
-
score2.
|
320
|
+
expect(score2).to be_a score.class
|
321
|
+
expect(score2).to eq score
|
319
322
|
end
|
320
323
|
end
|
321
324
|
end
|
@@ -2,15 +2,15 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
2
|
|
3
3
|
describe Parsing::ArticulationParser do
|
4
4
|
parser = Parsing::ArticulationParser.new
|
5
|
-
|
5
|
+
|
6
6
|
ARTICULATION_SYMBOLS.each do |art,str|
|
7
7
|
res = parser.parse(str)
|
8
8
|
it "should parse '#{str}'" do
|
9
|
-
res.
|
9
|
+
expect(res).to_not be nil
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it 'should return a node to responds to :to_articulation correctly' do
|
13
|
-
res.to_articulation.
|
13
|
+
expect(res.to_articulation).to eq art
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|