musicality 0.11.1 → 0.12.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 +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
|