music-transcription 0.3.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.
- data/.document +3 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.rdoc +4 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +28 -0
- data/Rakefile +54 -0
- data/bin/transcribe +176 -0
- data/lib/music-transcription.rb +20 -0
- data/lib/music-transcription/arrangement.rb +31 -0
- data/lib/music-transcription/instrument_config.rb +38 -0
- data/lib/music-transcription/interval.rb +66 -0
- data/lib/music-transcription/link.rb +115 -0
- data/lib/music-transcription/note.rb +156 -0
- data/lib/music-transcription/part.rb +128 -0
- data/lib/music-transcription/pitch.rb +297 -0
- data/lib/music-transcription/pitch_constants.rb +204 -0
- data/lib/music-transcription/profile.rb +105 -0
- data/lib/music-transcription/program.rb +136 -0
- data/lib/music-transcription/score.rb +122 -0
- data/lib/music-transcription/tempo.rb +44 -0
- data/lib/music-transcription/transition.rb +71 -0
- data/lib/music-transcription/value_change.rb +85 -0
- data/lib/music-transcription/version.rb +7 -0
- data/music-transcription.gemspec +36 -0
- data/samples/arrangements/glissando_test.yml +71 -0
- data/samples/arrangements/hip.yml +952 -0
- data/samples/arrangements/instrument_test.yml +119 -0
- data/samples/arrangements/legato_test.yml +237 -0
- data/samples/arrangements/make_glissando_test.rb +27 -0
- data/samples/arrangements/make_hip.rb +75 -0
- data/samples/arrangements/make_instrument_test.rb +34 -0
- data/samples/arrangements/make_legato_test.rb +37 -0
- data/samples/arrangements/make_missed_connection.rb +72 -0
- data/samples/arrangements/make_portamento_test.rb +27 -0
- data/samples/arrangements/make_slur_test.rb +37 -0
- data/samples/arrangements/make_song1.rb +84 -0
- data/samples/arrangements/make_song2.rb +69 -0
- data/samples/arrangements/missed_connection.yml +481 -0
- data/samples/arrangements/portamento_test.yml +71 -0
- data/samples/arrangements/slur_test.yml +237 -0
- data/samples/arrangements/song1.yml +640 -0
- data/samples/arrangements/song2.yml +429 -0
- data/spec/instrument_config_spec.rb +47 -0
- data/spec/interval_spec.rb +38 -0
- data/spec/link_spec.rb +22 -0
- data/spec/musicality_spec.rb +7 -0
- data/spec/note_spec.rb +65 -0
- data/spec/part_spec.rb +87 -0
- data/spec/pitch_spec.rb +139 -0
- data/spec/profile_spec.rb +24 -0
- data/spec/program_spec.rb +55 -0
- data/spec/score_spec.rb +55 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/transition_spec.rb +13 -0
- data/spec/value_change_spec.rb +19 -0
- metadata +239 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Interval do
|
4
|
+
before :all do
|
5
|
+
@pitch = C4
|
6
|
+
end
|
7
|
+
|
8
|
+
context '.new' do
|
9
|
+
it "should assign :pitch parameter given during construction" do
|
10
|
+
interval = Interval.new :pitch => @pitch
|
11
|
+
interval.pitch.should eq(@pitch)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should assign :link parameter if given during construction" do
|
15
|
+
link = Link.new(:relationship => Link::RELATIONSHIP_TIE, :target_pitch => @pitch)
|
16
|
+
interval = Interval.new :pitch => @pitch, :link => link
|
17
|
+
interval.link.should eq(link)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context '#pitch=' do
|
22
|
+
it "should assign pitch" do
|
23
|
+
interval = Interval.new :pitch => @pitch
|
24
|
+
interval.pitch = Gb4
|
25
|
+
interval.pitch.should eq Gb4
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context '#link=' do
|
30
|
+
it "should assign link" do
|
31
|
+
link = Link.new(:relationship => Link::RELATIONSHIP_SLUR, :target_pitch => G2)
|
32
|
+
interval = Interval.new :pitch => @pitch
|
33
|
+
interval.link = link
|
34
|
+
interval.link.should eq(link)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/spec/link_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Link do
|
4
|
+
context '.new' do
|
5
|
+
its(:relationship) { should eq(Link::RELATIONSHIP_NONE) }
|
6
|
+
its(:target_pitch) { should eq(Pitch.new) }
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should assign the given relationship' do
|
10
|
+
Link::RELATIONSHIPS.each do |relationship|
|
11
|
+
link = Link.new(:relationship => relationship)
|
12
|
+
link.relationship.should eq(relationship)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should assign the given target pitch' do
|
17
|
+
[A0, B0].each do |pitch|
|
18
|
+
link = Link.new(:target_pitch => pitch)
|
19
|
+
link.target_pitch.should eq(pitch)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/spec/note_spec.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Note do
|
4
|
+
before :all do
|
5
|
+
@pitch = C4
|
6
|
+
end
|
7
|
+
|
8
|
+
context '.new' do
|
9
|
+
it 'should assign :duration that is given during construction' do
|
10
|
+
note = Note.new :duration => 2
|
11
|
+
note.duration.should eq(2)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should assign :sustain, :attack, and :separation parameters if given during construction" do
|
15
|
+
note = Note.new :duration => 2, :sustain => 0.1, :attack => 0.2, :separation => 0.3
|
16
|
+
note.sustain.should eq(0.1)
|
17
|
+
note.attack.should eq(0.2)
|
18
|
+
note.separation.should eq(0.3)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should have no intervals if not given' do
|
22
|
+
Note.new(:duration => 2).intervals.should be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should assign intervals when given' do
|
26
|
+
intervals = [
|
27
|
+
Interval.new(:pitch => C2),
|
28
|
+
Interval.new(:pitch => D2),
|
29
|
+
]
|
30
|
+
Note.new(:duration => 2, :intervals => intervals).intervals.should eq(intervals)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context '#duration=' do
|
35
|
+
it 'should assign duration' do
|
36
|
+
note = Note.new :pitch => @pitch, :duration => 2
|
37
|
+
note.duration = 3
|
38
|
+
note.duration.should eq 3
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context '#sustain=' do
|
43
|
+
it "should assign sustain" do
|
44
|
+
note = Note.new :pitch => @pitch, :duration => 2
|
45
|
+
note.sustain = 0.123
|
46
|
+
note.sustain.should eq 0.123
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context '#attack=' do
|
51
|
+
it "should assign attack" do
|
52
|
+
note = Note.new :pitch => @pitch, :duration => 2
|
53
|
+
note.attack = 0.123
|
54
|
+
note.attack.should eq 0.123
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context '#separation=' do
|
59
|
+
it "should assign separation" do
|
60
|
+
note = Note.new :pitch => @pitch, :duration => 2
|
61
|
+
note.separation = 0.123
|
62
|
+
note.separation.should eq 0.123
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/spec/part_spec.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Part do
|
4
|
+
context '.new' do
|
5
|
+
its(:offset) { should eq(0) }
|
6
|
+
its(:notes) { should be_empty }
|
7
|
+
|
8
|
+
it "should assign loudness_profile profile given during construction" do
|
9
|
+
loudness_profile = Profile.new(
|
10
|
+
:start_value => 0.5,
|
11
|
+
:value_changes => {
|
12
|
+
1.0 => linear_change(1.0, 2.0)
|
13
|
+
}
|
14
|
+
)
|
15
|
+
part = Part.new :loudness_profile => loudness_profile
|
16
|
+
part.loudness_profile.should eq(loudness_profile)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should assign notes given during construction" do
|
20
|
+
notes = [
|
21
|
+
Note.new(
|
22
|
+
:duration => 0.25,
|
23
|
+
:intervals => [
|
24
|
+
Interval.new(:pitch => C1),
|
25
|
+
Interval.new(:pitch => D1),
|
26
|
+
]
|
27
|
+
)
|
28
|
+
]
|
29
|
+
|
30
|
+
part = Part.new :notes => notes
|
31
|
+
part.notes.should eq(notes)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe PartFile do
|
37
|
+
describe '.new' do
|
38
|
+
before :all do
|
39
|
+
@part_hash = {
|
40
|
+
:notes => [
|
41
|
+
Note.new(
|
42
|
+
:duration => 0.25,
|
43
|
+
:intervals => [
|
44
|
+
Interval.new(:pitch => C1),
|
45
|
+
Interval.new(:pitch => D1) ]
|
46
|
+
),
|
47
|
+
Note.new(
|
48
|
+
:duration => 0.125,
|
49
|
+
:intervals => [
|
50
|
+
Interval.new(:pitch => E2) ]
|
51
|
+
),
|
52
|
+
],
|
53
|
+
:loudness_profile => Profile.new(
|
54
|
+
:start_value => 0.6
|
55
|
+
)
|
56
|
+
}
|
57
|
+
|
58
|
+
@path = 'temp.yml'
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'hash of part stored in YAML file' do
|
62
|
+
it 'should load part from file' do
|
63
|
+
File.open(@path, 'w') do |file|
|
64
|
+
file.write @part_hash.to_yaml
|
65
|
+
end
|
66
|
+
part = Part.new @part_hash
|
67
|
+
part_from_file = PartFile.new(:file_path => @path)
|
68
|
+
part_from_file.should eq part
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'part stored in YAML file' do
|
73
|
+
it 'should load part from file' do
|
74
|
+
part = Part.new @part_hash
|
75
|
+
File.open(@path, 'w') do |file|
|
76
|
+
file.write part.to_yaml
|
77
|
+
end
|
78
|
+
part_from_file = PartFile.new(:file_path => @path)
|
79
|
+
part_from_file.should eq part
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
after :all do
|
84
|
+
File.delete @path
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/spec/pitch_spec.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Pitch do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@cases =
|
7
|
+
[
|
8
|
+
{ :octave => 1, :semitone => 0, :cent => 0, :ratio => 2.0, :total_cent => 1200 },
|
9
|
+
{ :octave => 2, :semitone => 0, :cent => 0, :ratio => 4.0, :total_cent => 2400 },
|
10
|
+
{ :octave => 1, :semitone => 6, :cent => 0, :ratio => 2.8284, :total_cent => 1800 },
|
11
|
+
{ :octave => 2, :semitone => 6, :cent => 0, :ratio => 5.6569, :total_cent => 3000 },
|
12
|
+
{ :octave => 1, :semitone => 6, :cent => 20, :ratio => 2.8613, :total_cent => 1820 },
|
13
|
+
{ :octave => 2, :semitone => 6, :cent => 20, :ratio => 5.7226, :total_cent => 3020 },
|
14
|
+
{ :octave => 3, :semitone => 7, :cent => 77, :ratio => 12.5316, :total_cent => 4377 },
|
15
|
+
{ :octave => -1, :semitone => 0, :cent => 0, :ratio => 0.5, :total_cent => -1200 },
|
16
|
+
{ :octave => -2, :semitone => 0, :cent => 0, :ratio => 0.25, :total_cent => -2400 },
|
17
|
+
{ :octave => -2, :semitone => 7, :cent => 55, :ratio => 0.3867, :total_cent => -1645 },
|
18
|
+
{ :octave => -1, :semitone => 9, :cent => 23, :ratio => 0.8521, :total_cent => -277 },
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be constructible with no parameters (no error raised)" do
|
23
|
+
lambda { Pitch.new }.should_not raise_error
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be hash-makeable" do
|
27
|
+
obj = Pitch.new :octave => 4, :semitone => 3
|
28
|
+
obj.octave.should eq(4)
|
29
|
+
obj.semitone.should eq(3)
|
30
|
+
obj.cent.should eq(0)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should use default octave, semitone, and cent in none is given" do
|
34
|
+
p = Pitch.new
|
35
|
+
p.ratio.should be_within(0.01).of(1.0)
|
36
|
+
p.total_cent.should eq(0)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should use the octave, semitone, and cent given during construction" do
|
40
|
+
@cases.each do |case_data|
|
41
|
+
p = Pitch.new :octave => case_data[:octave], :semitone => case_data[:semitone], :cent => case_data[:cent]
|
42
|
+
p.ratio.should be_within(0.01).of case_data[:ratio]
|
43
|
+
p.total_cent.should be case_data[:total_cent]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should allow setting by ratio" do
|
48
|
+
@cases.each do |case_data|
|
49
|
+
p = Pitch.new
|
50
|
+
p.ratio = case_data[:ratio]
|
51
|
+
|
52
|
+
p.octave.should eq case_data[:octave]
|
53
|
+
p.semitone.should eq case_data[:semitone]
|
54
|
+
p.cent.should eq case_data[:cent]
|
55
|
+
p.total_cent.should eq case_data[:total_cent]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should setting by total_cent" do
|
60
|
+
@cases.each do |case_data|
|
61
|
+
p = Pitch.new
|
62
|
+
p.total_cent = case_data[:total_cent]
|
63
|
+
|
64
|
+
p.octave.should eq case_data[:octave]
|
65
|
+
p.semitone.should eq case_data[:semitone]
|
66
|
+
p.cent.should eq case_data[:cent]
|
67
|
+
p.total_cent.should eq case_data[:total_cent]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be comparable to other pitches" do
|
72
|
+
p1 = Pitch.new :semitone => 1
|
73
|
+
p2 = Pitch.new :semitone => 2
|
74
|
+
p3 = Pitch.new :semitone => 3
|
75
|
+
|
76
|
+
p1.should eq(Pitch.new :semitone => 1)
|
77
|
+
p2.should eq(Pitch.new :semitone => 2)
|
78
|
+
p3.should eq(Pitch.new :semitone => 3)
|
79
|
+
|
80
|
+
p1.should be < p2
|
81
|
+
p1.should be < p3
|
82
|
+
p2.should be < p3
|
83
|
+
p3.should be > p2
|
84
|
+
p3.should be > p1
|
85
|
+
p2.should be > p1
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should be addable and subtractable with other pitches" do
|
89
|
+
p1 = Pitch.new :semitone => 1
|
90
|
+
p2 = Pitch.new :semitone => 2
|
91
|
+
p3 = Pitch.new :semitone => 3
|
92
|
+
|
93
|
+
(p1 + p2).should eq(Pitch.new :semitone => 3)
|
94
|
+
(p1 + p3).should eq(Pitch.new :semitone => 4)
|
95
|
+
(p2 + p3).should eq(Pitch.new :semitone => 5)
|
96
|
+
|
97
|
+
(p1 - p2).should eq(Pitch.new :semitone => -1)
|
98
|
+
(p1 - p3).should eq(Pitch.new :semitone => -2)
|
99
|
+
(p2 - p3).should eq(Pitch.new :semitone => -1)
|
100
|
+
(p3 - p2).should eq(Pitch.new :semitone => 1)
|
101
|
+
(p3 - p1).should eq(Pitch.new :semitone => 2)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should have freq of 440 for A4" do
|
105
|
+
a4 = Pitch.new :octave => 4, :semitone => 9
|
106
|
+
a4.freq.should be_within(0.01).of(440.0)
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'String#to_pitch' do
|
110
|
+
it 'should create a Pitch object that matches the musical note' do
|
111
|
+
{
|
112
|
+
"Ab2" => Pitch.new(:octave => 2, :semitone => 8),
|
113
|
+
"C0" => Pitch.new(:octave => 0, :semitone => 0),
|
114
|
+
"db4" => Pitch.new(:octave => 4, :semitone => 1),
|
115
|
+
"F#12" => Pitch.new(:octave => 12, :semitone => 6),
|
116
|
+
"E#7" => Pitch.new(:octave => 7, :semitone => 5),
|
117
|
+
"G9" => Pitch.new(:octave => 9, :semitone => 7),
|
118
|
+
"Bb10" => Pitch.new(:octave => 10, :semitone => 10),
|
119
|
+
}.each do |str, expected_pitch|
|
120
|
+
str.to_pitch.should eq(expected_pitch)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context '.make_from_freq' do
|
126
|
+
it 'should make a pitch whose freq is approximately the given freq' do
|
127
|
+
one_cent = Pitch.new(:cent => 1)
|
128
|
+
[1.0, 25.0, 200.0, 3500.0].each do |given_freq|
|
129
|
+
pitch = Pitch.make_from_freq given_freq
|
130
|
+
freq = pitch.freq
|
131
|
+
if freq > given_freq
|
132
|
+
(freq / given_freq).should be < one_cent.ratio
|
133
|
+
elsif freq < given_freq
|
134
|
+
(given_freq / freq).should be < one_cent.ratio
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Profile do
|
4
|
+
|
5
|
+
context '.new' do
|
6
|
+
it "should assign start value given during construction" do
|
7
|
+
p = Profile.new(:start_value => 0.2)
|
8
|
+
p.start_value.should eq(0.2)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should assign settings given during construction" do
|
12
|
+
p = Profile.new(
|
13
|
+
:start_value => 0.2,
|
14
|
+
:value_changes => {
|
15
|
+
1.0 => ValueChange.new(:value => 0.5),
|
16
|
+
1.5 => ValueChange.new(:value => 1.0)
|
17
|
+
}
|
18
|
+
)
|
19
|
+
p.value_changes[1.0].value.should eq(0.5)
|
20
|
+
p.value_changes[1.5].value.should eq(1.0)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Program do
|
4
|
+
|
5
|
+
it "should assign the segments given during initialization" do
|
6
|
+
segments = [ 0.0...5.0, 0.0...4.0, 5.0...10.0 ]
|
7
|
+
program = Program.new :segments => segments
|
8
|
+
program.segments.should eq(segments.clone)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#include?" do
|
12
|
+
it "should return true for any offset which would be encountered" do
|
13
|
+
segments = [ 0.0...5.0, 0.0...4.0, 5.0...10.0 ]
|
14
|
+
program = Program.new :segments => segments
|
15
|
+
|
16
|
+
[0.0, 4.0, 5.0, 9.999].each do |offset|
|
17
|
+
program.include?(offset).should be_true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return false for any offset which would not be encountered" do
|
22
|
+
segments = [ 0.0...5.0, 0.0...4.0, 5.0...10.0 ]
|
23
|
+
program = Program.new :segments => segments
|
24
|
+
|
25
|
+
[-0.000001, 10.000001].each do |offset|
|
26
|
+
program.include?(offset).should be_false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#note_elapsed_at" do
|
32
|
+
before :each do
|
33
|
+
segments = [ 0.0...5.0, 0.0...4.0, 5.0..10.0 ]
|
34
|
+
@program = Program.new :segments => segments
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return 0.0 at program start" do
|
38
|
+
@program.note_elapsed_at(@program.start).should eq(0.0)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return program length at program stop" do
|
42
|
+
@program.note_elapsed_at(@program.stop).should eq(@program.length)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return correct note elapsed for any included offset" do
|
46
|
+
@program.note_elapsed_at(2.5).should eq(2.5)
|
47
|
+
@program.note_elapsed_at(5.5).should eq(9.5)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise error if offset is not included" do
|
51
|
+
lambda { @program.note_elapsed_at(-0.000001) }.should raise_error
|
52
|
+
lambda { @program.note_elapsed_at(10.000001) }.should raise_error
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/spec/score_spec.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Score do
|
4
|
+
before :each do
|
5
|
+
@parts = { "piano (LH)" => Samples::SAMPLE_PART }
|
6
|
+
@program = Program.new :segments => [0...0.75, 0...0.75]
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '.new' do
|
10
|
+
context "no args given" do
|
11
|
+
let(:score) { Score.new }
|
12
|
+
subject { score }
|
13
|
+
its(:program) { should eq(Program.new) }
|
14
|
+
its(:parts) { should be_empty }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'args given' do
|
18
|
+
it "should assign parts given during construction" do
|
19
|
+
score = Score.new :program => @program, :parts => @parts
|
20
|
+
score.parts.should eq(@parts)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should assign program given during construction" do
|
24
|
+
score = Score.new :program => @program
|
25
|
+
score.program.should eq(@program)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe TempoScore do
|
32
|
+
before :each do
|
33
|
+
@parts = { "piano (LH)" => Samples::SAMPLE_PART }
|
34
|
+
@program = Program.new :segments => [0...0.75, 0...0.75]
|
35
|
+
@tempo_profile = Profile.new(
|
36
|
+
:start_value => tempo(120),
|
37
|
+
:value_changes => {
|
38
|
+
0.5 => linear_change(tempo(60), 0.25)
|
39
|
+
}
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '.new' do
|
44
|
+
it "should assign tempo profile given during construction" do
|
45
|
+
score = TempoScore.new :tempo_profile => @tempo_profile
|
46
|
+
score.tempo_profile.should eq(@tempo_profile)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should assign part and program given during construction" do
|
50
|
+
score = TempoScore.new :tempo_profile => @tempo_profile, :parts => @parts, :program => @program
|
51
|
+
score.parts.should eq(@parts)
|
52
|
+
score.program.should eq(@program)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|