music-transcription 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +8 -8
- data/lib/music-transcription/link.rb +5 -9
- data/lib/music-transcription/meter.rb +5 -0
- data/lib/music-transcription/pitch.rb +2 -64
- data/lib/music-transcription/version.rb +1 -1
- data/music-transcription.gemspec +1 -0
- data/spec/change_spec.rb +16 -2
- data/spec/link_spec.rb +10 -3
- data/spec/meter_spec.rb +25 -0
- data/spec/note_spec.rb +16 -0
- data/spec/part_spec.rb +8 -1
- data/spec/pitch_spec.rb +5 -14
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e410c49d0b013842573762574ed5406d7676843b
|
4
|
+
data.tar.gz: 425be325e12b0908c57c1897ebad82443e685f81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fffac146f3b86db14687f3bd1b7e348d883351a3d368f2a192142f36951e5ae8225bd13c98c5f8fd2c2773766b162354528d82e035a350e1c0c01b6bddc75d0
|
7
|
+
data.tar.gz: 942d91f19af6e77d8ab61714bfe43e6c35d36e186dbd6adce002b131a6211e182c999e83a6472418d4e100156c7321569ecee6532f714e452ce4ec2f82fd544e
|
data/Rakefile
CHANGED
@@ -32,19 +32,19 @@ require 'yard'
|
|
32
32
|
YARD::Rake::YardocTask.new
|
33
33
|
task :doc => :yard
|
34
34
|
|
35
|
-
task :
|
35
|
+
task :make_examples do
|
36
36
|
current_dir = Dir.getwd
|
37
|
-
|
38
|
-
Dir.chdir
|
37
|
+
examples_dir = File.join(File.dirname(__FILE__), 'examples')
|
38
|
+
Dir.chdir examples_dir
|
39
39
|
|
40
|
-
|
40
|
+
examples = []
|
41
41
|
Dir.glob('**/make*.rb') do |file|
|
42
|
-
|
42
|
+
examples.push File.expand_path(file)
|
43
43
|
end
|
44
44
|
|
45
|
-
|
46
|
-
dirname = File.dirname(
|
47
|
-
filename = File.basename(
|
45
|
+
examples.each do |example|
|
46
|
+
dirname = File.dirname(example)
|
47
|
+
filename = File.basename(example)
|
48
48
|
|
49
49
|
Dir.chdir dirname
|
50
50
|
ruby filename
|
@@ -23,19 +23,15 @@ class Link
|
|
23
23
|
self.class.new @target_pitch.clone
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
:Legato
|
28
|
-
:Glissando
|
29
|
-
:Portamento
|
30
|
-
|
26
|
+
[ :Slur,
|
27
|
+
:Legato,
|
28
|
+
:Glissando,
|
29
|
+
:Portamento,
|
30
|
+
].each do |name|
|
31
31
|
klass = Class.new(Link) do
|
32
32
|
def initialize target_pitch
|
33
33
|
super(target_pitch)
|
34
34
|
end
|
35
|
-
|
36
|
-
def to_s
|
37
|
-
print_str + @target_pitch
|
38
|
-
end
|
39
35
|
end
|
40
36
|
Link.const_set(name.to_sym, klass)
|
41
37
|
end
|
@@ -102,7 +102,8 @@ class Pitch
|
|
102
102
|
|
103
103
|
# Compare pitch equality using total semitone
|
104
104
|
def ==(other)
|
105
|
-
self.
|
105
|
+
return (self.class == other.class &&
|
106
|
+
self.total_semitone == other.total_semitone)
|
106
107
|
end
|
107
108
|
|
108
109
|
def eql?(other)
|
@@ -148,26 +149,6 @@ class Pitch
|
|
148
149
|
@semitone = semitoneTotal
|
149
150
|
return self
|
150
151
|
end
|
151
|
-
|
152
|
-
# Produce a string representation of a pitch (e.g. "C2")
|
153
|
-
def to_s
|
154
|
-
semitone_str = case @semitone
|
155
|
-
when 0 then "C"
|
156
|
-
when 1 then "Db"
|
157
|
-
when 2 then "D"
|
158
|
-
when 3 then "Eb"
|
159
|
-
when 4 then "E"
|
160
|
-
when 5 then "F"
|
161
|
-
when 6 then "Gb"
|
162
|
-
when 7 then "G"
|
163
|
-
when 8 then "Ab"
|
164
|
-
when 9 then "A"
|
165
|
-
when 10 then "Bb"
|
166
|
-
when 11 then "B"
|
167
|
-
end
|
168
|
-
|
169
|
-
return semitone_str + @octave.to_s
|
170
|
-
end
|
171
152
|
|
172
153
|
def self.make_from_freq(freq)
|
173
154
|
pitch = Pitch.new()
|
@@ -186,46 +167,3 @@ end
|
|
186
167
|
|
187
168
|
end
|
188
169
|
end
|
189
|
-
|
190
|
-
class String
|
191
|
-
# Create a Pitch object from a string (e.g. "C2"). String can contain a letter (A-G),
|
192
|
-
# to indicate the semitone, followed by an optional sharp/flat (#/b) and then the
|
193
|
-
# octave number (non-negative integer).
|
194
|
-
def to_pitch
|
195
|
-
string = self
|
196
|
-
if string =~ /[AaBbCcDdEeFfGg][#b][\d]+/
|
197
|
-
semitone = letter_to_semitone string[0]
|
198
|
-
semitone = case string[1]
|
199
|
-
when "#" then semitone + 1
|
200
|
-
when "b" then semitone - 1
|
201
|
-
else raise ArgumentError, "unexpected symbol found"
|
202
|
-
end
|
203
|
-
octave = string[2..-1].to_i
|
204
|
-
return Music::Transcription::Pitch.new(:octave => octave, :semitone => semitone)
|
205
|
-
elsif string =~ /[AaBbCcDdEeFfGg][\d]+/
|
206
|
-
semitone = letter_to_semitone string[0]
|
207
|
-
octave = string[1..-1].to_i
|
208
|
-
return Music::Transcription::Pitch.new(:octave => octave, :semitone => semitone)
|
209
|
-
else
|
210
|
-
raise ArgumentError, "string #{string} cannot be converted to a pitch"
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
private
|
215
|
-
|
216
|
-
def letter_to_semitone letter
|
217
|
-
semitone = case letter
|
218
|
-
when /[Cc]/ then 0
|
219
|
-
when /[Dd]/ then 2
|
220
|
-
when /[Ee]/ then 4
|
221
|
-
when /[Ff]/ then 5
|
222
|
-
when /[Gg]/ then 7
|
223
|
-
when /[Aa]/ then 9
|
224
|
-
when /[Bb]/ then 11
|
225
|
-
else raise ArgumentError, "invalid letter \"#{letter}\" given"
|
226
|
-
end
|
227
|
-
|
228
|
-
return semitone
|
229
|
-
end
|
230
|
-
|
231
|
-
end
|
data/music-transcription.gemspec
CHANGED
data/spec/change_spec.rb
CHANGED
@@ -19,7 +19,14 @@ describe Change::Immediate do
|
|
19
19
|
it 'should return false if two immediate changes do not have the same value' do
|
20
20
|
Change::Immediate.new(5).should_not eq(Change::Immediate.new(4))
|
21
21
|
end
|
22
|
-
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#to_yaml' do
|
25
|
+
it 'should produce YAML that can be loaded' do
|
26
|
+
c = Change::Immediate.new(4)
|
27
|
+
YAML.load(c.to_yaml).should eq c
|
28
|
+
end
|
29
|
+
end
|
23
30
|
end
|
24
31
|
|
25
32
|
describe Change::Gradual do
|
@@ -45,5 +52,12 @@ describe Change::Gradual do
|
|
45
52
|
it 'should return false if two gradual changes do not have the same duration' do
|
46
53
|
Change::Gradual.new(5,2).should_not eq(Change::Gradual.new(5,1))
|
47
54
|
end
|
48
|
-
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#to_yaml' do
|
58
|
+
it 'should produce YAML that can be loaded' do
|
59
|
+
c = Change::Gradual.new(4,2)
|
60
|
+
YAML.load(c.to_yaml).should eq c
|
61
|
+
end
|
62
|
+
end
|
49
63
|
end
|
data/spec/link_spec.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
describe Link do
|
4
|
-
context '
|
4
|
+
context '#initialize' do
|
5
5
|
it 'should assign the given pitch to :target_pitch' do
|
6
6
|
Link.new(C2).target_pitch.should eq(C2)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
describe '
|
10
|
+
describe '#==' do
|
11
11
|
it 'should return true if two links have the same target pitch' do
|
12
12
|
Link.new(C2).should eq(Link.new(C2))
|
13
13
|
end
|
@@ -17,10 +17,17 @@ describe Link do
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
describe 'clone' do
|
20
|
+
describe '#clone' do
|
21
21
|
it 'should return a link with the same target pitch' do
|
22
22
|
l = Link.new(C4)
|
23
23
|
l.clone.should eq(l)
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
describe '#to_yaml' do
|
28
|
+
it 'should produce YAML that can be loaded' do
|
29
|
+
l = Link::Slur.new(C5)
|
30
|
+
YAML.load(l.to_yaml).should eq l
|
31
|
+
end
|
32
|
+
end
|
26
33
|
end
|
data/spec/meter_spec.rb
CHANGED
@@ -22,4 +22,29 @@ describe Meter do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
describe '#==' do
|
27
|
+
context 'meters with same beat duration and beats per measure' do
|
28
|
+
it 'should return true' do
|
29
|
+
m1 = Meter.new(4,"1/4".to_r)
|
30
|
+
m2 = Meter.new(4,"1/4".to_r)
|
31
|
+
m1.should eq m2
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'meters with same meausre duration but different beat duration' do
|
36
|
+
it 'should return false' do
|
37
|
+
m1 = Meter.new(4,"1/4".to_r)
|
38
|
+
m2 = Meter.new(2,"1/2".to_r)
|
39
|
+
m1.should_not eq m2
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#to_yaml' do
|
45
|
+
it 'should produce YAML that can be loaded' do
|
46
|
+
m = Meter.new(4,"1/4".to_r)
|
47
|
+
YAML.load(m.to_yaml).should eq m
|
48
|
+
end
|
49
|
+
end
|
25
50
|
end
|
data/spec/note_spec.rb
CHANGED
@@ -86,4 +86,20 @@ describe Note do
|
|
86
86
|
note.stretch!(1).should be note
|
87
87
|
end
|
88
88
|
end
|
89
|
+
|
90
|
+
describe '#to_yaml' do
|
91
|
+
it 'should produce YAML that can be loaded' do
|
92
|
+
n = Note.new(1,[C2])
|
93
|
+
YAML.load(n.to_yaml).should eq n
|
94
|
+
|
95
|
+
n = Note.new(1,[C2,E2])
|
96
|
+
YAML.load(n.to_yaml).should eq n
|
97
|
+
|
98
|
+
n = Note.new(1,[C2], accent: Accents::STACCATO)
|
99
|
+
YAML.load(n.to_yaml).should eq n
|
100
|
+
|
101
|
+
n = Note.new(1,[E2], links: {E2 => Link::Legato.new(F2)})
|
102
|
+
YAML.load(n.to_yaml).should eq n
|
103
|
+
end
|
104
|
+
end
|
89
105
|
end
|
data/spec/part_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
describe Part do
|
4
|
-
|
4
|
+
describe '#initialize' do
|
5
5
|
it 'should use empty containers for parameters not given' do
|
6
6
|
p = Part.new(Dynamics::MP)
|
7
7
|
p.notes.should be_empty
|
@@ -19,4 +19,11 @@ describe Part do
|
|
19
19
|
p.dynamic_changes.should eq dcs
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
describe '#to_yaml' do
|
24
|
+
it 'should produce YAML that can be loaded' do
|
25
|
+
p = Samples::SAMPLE_PART
|
26
|
+
YAML.load(p.to_yaml).should eq p
|
27
|
+
end
|
28
|
+
end
|
22
29
|
end
|
data/spec/pitch_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe Pitch do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should be constructible with no parameters (no error raised)" do
|
21
|
-
|
21
|
+
lambda { Pitch.new }.should_not raise_error
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should be hash-makeable" do
|
@@ -101,19 +101,10 @@ describe Pitch do
|
|
101
101
|
a4.freq.should be_within(0.01).of(440.0)
|
102
102
|
end
|
103
103
|
|
104
|
-
describe '
|
105
|
-
it 'should
|
106
|
-
|
107
|
-
|
108
|
-
"C0" => Pitch.new(octave: 0, semitone: 0),
|
109
|
-
"db4" => Pitch.new(octave: 4, semitone: 1),
|
110
|
-
"F#12" => Pitch.new(octave: 12, semitone: 6),
|
111
|
-
"E#7" => Pitch.new(octave: 7, semitone: 5),
|
112
|
-
"G9" => Pitch.new(octave: 9, semitone: 7),
|
113
|
-
"Bb10" => Pitch.new(octave: 10, semitone: 10),
|
114
|
-
}.each do |str, expected_pitch|
|
115
|
-
str.to_pitch.should eq(expected_pitch)
|
116
|
-
end
|
104
|
+
describe '#to_yaml' do
|
105
|
+
it 'should produce YAML that can be loaded' do
|
106
|
+
p = Pitch.new(octave: 1, semitone: 2)
|
107
|
+
YAML.load(p.to_yaml).should eq p
|
117
108
|
end
|
118
109
|
end
|
119
110
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: music-transcription
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Tunnell
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - '>='
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry-stack_explorer
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
description: "The goal of music-transcription is the abstract representation of standard
|
112
126
|
\nmusical features such as pitch, note, loudness, tempo, etc. Establishing\na common
|
113
127
|
representation enables composition and performance.\n"
|