music-utils 0.5.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -1
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -2
- data/README.md +18 -13
- data/Rakefile +2 -24
- data/lib/music-utils/interval/interval.rb +109 -0
- data/lib/music-utils/scales/scales.rb +13 -0
- data/lib/music-utils/version.rb +3 -0
- data/lib/music-utils.rb +26 -0
- data/music-utils.gemspec +23 -14
- data/spec/{interval_spec.rb → interval/interval_spec.rb} +7 -6
- data/spec/music-utils_spec.rb +45 -0
- metadata +34 -12
- data/Gemfile.lock +0 -21
- data/lib/interval.rb +0 -117
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 1.0.0 (May 6, 2011)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- Added MusicUtils module
|
6
|
+
- New shortcuts for clasify intervals on MusicUtils module
|
7
|
+
|
8
|
+
|
9
|
+
## 0.5.2 (April 29, 2011)
|
10
|
+
|
11
|
+
Features:
|
12
|
+
|
13
|
+
- Extracted some common logic into helper methods
|
14
|
+
|
15
|
+
|
1
16
|
## 0.5.1 (April 27, 2011)
|
2
17
|
|
3
18
|
Features:
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,30 +1,35 @@
|
|
1
1
|
music-utils
|
2
2
|
=========
|
3
3
|
|
4
|
-
Utils for music. At the moment only
|
4
|
+
Utils for music. At the moment only to classify interval.
|
5
5
|
|
6
6
|
Examples
|
7
7
|
--------
|
8
8
|
Simple intervals:
|
9
9
|
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
10
|
+
* MusicUtils.number('do', 'mi') #=> 3 (3th)
|
11
|
+
* MusicUtils.semitones('do', 'mi') #=> 4 (semi-tones)
|
12
|
+
* MusicUtils.quality('do', 'mi') #=> M (major)
|
13
|
+
* MusicUtils.quality('do#', 'mi') #=> m (minor)
|
14
14
|
|
15
15
|
Compound intervals:
|
16
16
|
|
17
|
-
*
|
18
|
-
*
|
19
|
-
*
|
20
|
-
*
|
17
|
+
* MusicUtils.number('do', 'mi', 1) #=> 10 (10th)
|
18
|
+
* MusicUtils.semitones('do', 'mi', 1) #=> 16 (semi-tones)
|
19
|
+
* MusicUtils.quality('do', 'mi', 1) #=> M (major)
|
20
|
+
* MusicUtils.quality('dob', 'mi#', 1) #=> AA (augmented plus)
|
21
21
|
|
22
22
|
Short Notation:
|
23
23
|
|
24
|
-
*
|
25
|
-
*
|
26
|
-
*
|
27
|
-
*
|
24
|
+
* MusicUtils.short('do', 're') #=> M2
|
25
|
+
* MusicUtils.short('do', 're', 1) #=> M9
|
26
|
+
* MusicUtils.short('do#', 'mi') #=> m3
|
27
|
+
* MusicUtils.short('do#', 'mi', 1) #=> m10
|
28
|
+
|
29
|
+
Installation
|
30
|
+
-----------
|
31
|
+
|
32
|
+
gem install music-utils
|
28
33
|
|
29
34
|
To Do
|
30
35
|
-----
|
data/Rakefile
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler/setup'
|
3
|
-
|
4
1
|
require 'rake'
|
5
2
|
require 'rspec/core/rake_task'
|
6
3
|
|
@@ -16,27 +13,8 @@ RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
16
13
|
end
|
17
14
|
|
18
15
|
# Gems tasks
|
19
|
-
|
20
|
-
|
21
|
-
@gemspec = eval(File.read(Dir["*.gemspec"].first))
|
22
|
-
end
|
23
|
-
|
24
|
-
desc "Validate the gemspec"
|
25
|
-
task :gemspec => :load_gemspec do
|
26
|
-
@gemspec.validate
|
27
|
-
end
|
28
|
-
|
29
|
-
desc "Build gem locally"
|
30
|
-
task :build => :gemspec do
|
31
|
-
system "gem build #{@gemspec.name}.gemspec"
|
32
|
-
FileUtils.mkdir_p "pkg"
|
33
|
-
FileUtils.mv "#{@gemspec.name}-#{@gemspec.version}.gem", "pkg"
|
34
|
-
end
|
35
|
-
|
36
|
-
desc "Install gem locally"
|
37
|
-
task :install => :build do
|
38
|
-
system "gem install pkg/#{@gemspec.name}-#{@gemspec.version}"
|
39
|
-
end
|
16
|
+
require "bundler"
|
17
|
+
Bundler::GemHelper.install_tasks
|
40
18
|
|
41
19
|
desc "Clean automatically generated files"
|
42
20
|
task :clean do
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'music-utils/scales/scales'
|
2
|
+
|
3
|
+
# This class represents a music interval
|
4
|
+
module MusicUtils
|
5
|
+
|
6
|
+
class Interval
|
7
|
+
include Scales
|
8
|
+
|
9
|
+
def initialize(note1, note2, step)
|
10
|
+
@note1 = note1
|
11
|
+
@note2 = note2
|
12
|
+
@step = step
|
13
|
+
end
|
14
|
+
|
15
|
+
# It classifies the diatonic interval
|
16
|
+
def number
|
17
|
+
# initialize counter and index of scale
|
18
|
+
i = note1_index
|
19
|
+
count = 1
|
20
|
+
|
21
|
+
count, i = no_unison(count, i)
|
22
|
+
|
23
|
+
# Counting notes
|
24
|
+
until_find_note2(i) { count += 1 }
|
25
|
+
|
26
|
+
count = count + (8 * @step) - 1 if @step > 0
|
27
|
+
count
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the number of semitones
|
31
|
+
def semitones
|
32
|
+
# initialize counter and index of scale
|
33
|
+
i = note1_index
|
34
|
+
count = 0
|
35
|
+
|
36
|
+
count, i = no_unison(count, i)
|
37
|
+
|
38
|
+
# counting semi-tones
|
39
|
+
until_find_note2(i) do |i|
|
40
|
+
# from 'mi' to 'fa' and 'si' to 'do' there 1 semi-tone
|
41
|
+
if DIATONIC_SCALE[i] == 'fa' or DIATONIC_SCALE[i] == 'do'
|
42
|
+
count += 1
|
43
|
+
else
|
44
|
+
count += 2
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
count = count + (12 * @step) if @step > 0
|
49
|
+
|
50
|
+
# counting notes alterations
|
51
|
+
alter = @note1[2..3]
|
52
|
+
|
53
|
+
alter.each_char do |c|
|
54
|
+
count += 1 if c == 'b'
|
55
|
+
count -= 1 if c == '#'
|
56
|
+
end
|
57
|
+
|
58
|
+
alter = @note2[2..3]
|
59
|
+
|
60
|
+
alter.each_char do |c|
|
61
|
+
count -= 1 if c == 'b'
|
62
|
+
count += 1 if c == '#'
|
63
|
+
end
|
64
|
+
|
65
|
+
count
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the quality of the interval
|
69
|
+
def quality
|
70
|
+
s = ( @step > 0 and semitones - (12 * @step) ) || semitones
|
71
|
+
n = ( @step > 0 and number - (7 * @step) ) || number
|
72
|
+
QUALITIES[n][s]
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the class interval in the short notation
|
76
|
+
def short
|
77
|
+
quality + number.to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# Common loop to search note 2
|
83
|
+
def until_find_note2(i)
|
84
|
+
# search note2
|
85
|
+
while DIATONIC_SCALE[i] != @note2[0..1]
|
86
|
+
i += 1
|
87
|
+
if i > DIATONIC_SCALE.length
|
88
|
+
i = 0; next
|
89
|
+
end
|
90
|
+
yield i
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Jumps to the next note if note 1 and note 2 are the same
|
95
|
+
def no_unison(count, i)
|
96
|
+
if @note1[0..1] == @note2[0..1]
|
97
|
+
count += 1; i += 1
|
98
|
+
end
|
99
|
+
[count, i]
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns index of note 1
|
103
|
+
def note1_index
|
104
|
+
DIATONIC_SCALE.index(@note1[0..1])
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Scales module
|
2
|
+
module Scales
|
3
|
+
DIATONIC_SCALE = ['do', 're', 'mi', 'fa', 'sol', 'la', 'si']
|
4
|
+
QUALITIES = {
|
5
|
+
2 => {0 => 'd', 1 => 'm', 2 => 'M', 3 => 'A', 4 => 'AA'},
|
6
|
+
3 => {1 => 'dd', 2 => 'd', 3 => 'm', 4 => 'M', 5 => 'A', 6 => 'AA'},
|
7
|
+
4 => {3 => 'dd', 4 => 'd', 5 => 'P', 6 => 'A', 7 => 'AA'},
|
8
|
+
5 => {5 => 'dd', 6 => 'd', 7 => 'P', 8 => 'A', 9 => 'AA'},
|
9
|
+
6 => {6 => 'dd', 7 => 'd', 8 => 'm', 9 => 'M', 10 => 'A', 11 => 'AA'},
|
10
|
+
7 => {8 => 'dd', 9 => 'd', 10 => 'm', 11 => 'M', 12 => 'A', 13 => 'AA'},
|
11
|
+
8 => {10 => 'dd', 11 => 'd', 12 => 'P', 13 => 'A', 14 => 'AA'}
|
12
|
+
}
|
13
|
+
end
|
data/lib/music-utils.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'music-utils/interval/interval'
|
2
|
+
|
3
|
+
# Music utils
|
4
|
+
module MusicUtils
|
5
|
+
|
6
|
+
# Returns the number of the interval
|
7
|
+
def MusicUtils.number(note1, note2, step = 0)
|
8
|
+
Interval.new(note1, note2, step).number
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns semitones of interval
|
12
|
+
def MusicUtils.semitones(note1, note2, step = 0)
|
13
|
+
Interval.new(note1, note2, step).semitones
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the quality of interval
|
17
|
+
def MusicUtils.quality(note1, note2, step = 0)
|
18
|
+
Interval.new(note1, note2, step).quality
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns short notation
|
22
|
+
def MusicUtils.short(note1, note2, step = 0)
|
23
|
+
Interval.new(note1, note2, step).short
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/music-utils.gemspec
CHANGED
@@ -1,22 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "music-utils/version"
|
1
4
|
|
2
5
|
Gem::Specification.new do |s|
|
3
6
|
# Basic Info
|
4
|
-
s.name =
|
5
|
-
s.version =
|
6
|
-
s.summary = 'music-utils'
|
7
|
-
s.description = 'Utils for music. At the moment only one class to classify intervals.'
|
7
|
+
s.name = "music-utils"
|
8
|
+
s.version = MusicUtils::VERSION
|
8
9
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = [
|
10
|
-
s.email = [
|
11
|
-
s.homepage =
|
12
|
-
s.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
s.authors = ["Jorge Luis Pérez"]
|
11
|
+
s.email = ["jorgeluis700@gmail.com"]
|
12
|
+
s.homepage = "http://github.com/jorgeluis700/music-utils"
|
13
|
+
s.summary = %q{Utils for music}
|
14
|
+
s.description = %q{Utils for music. At the moment only to classify intervals.}
|
15
|
+
s.license = %q{MIT}
|
16
|
+
|
17
|
+
# Files
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
17
22
|
|
18
|
-
#
|
19
|
-
s.add_development_dependency('rspec')
|
23
|
+
# Ruby Gems Version
|
20
24
|
s.required_rubygems_version = ">= 1.3.6"
|
21
25
|
|
26
|
+
# Dependencies
|
27
|
+
s.add_development_dependency "rake", ">= 0.8"
|
28
|
+
s.add_development_dependency "bundler"
|
29
|
+
s.add_development_dependency "rspec"
|
30
|
+
|
22
31
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
require 'interval'
|
1
|
+
require 'music-utils/interval/interval'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe MusicUtils::Interval do
|
4
|
+
include MusicUtils
|
4
5
|
|
5
6
|
context "Number of intervals" do
|
6
7
|
it "the number of simple interval do-mi should be a 3rd" do
|
@@ -22,22 +23,22 @@ describe Interval do
|
|
22
23
|
context "Number of semitones of intervals" do
|
23
24
|
it "simple interval do-mi should be 4 semitones" do
|
24
25
|
i = Interval.new('do', 'mi', 0)
|
25
|
-
i.
|
26
|
+
i.semitones.should == 4
|
26
27
|
end
|
27
28
|
|
28
29
|
it "simple interval dob-mi# should be 6 semitones" do
|
29
30
|
i = Interval.new('dob', 'mi#', 0)
|
30
|
-
i.
|
31
|
+
i.semitones.should == 6
|
31
32
|
end
|
32
33
|
|
33
34
|
it "simple interval do-do should be 12 semitones" do
|
34
35
|
i = Interval.new('do', 'do', 0)
|
35
|
-
i.
|
36
|
+
i.semitones.should == 12
|
36
37
|
end
|
37
38
|
|
38
39
|
it "compound interval do-mi should be 16 semitones" do
|
39
40
|
i = Interval.new('do', 'mi', 1)
|
40
|
-
i.
|
41
|
+
i.semitones.should == 16
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'music-utils'
|
2
|
+
|
3
|
+
describe MusicUtils do
|
4
|
+
|
5
|
+
context "Intervals" do
|
6
|
+
|
7
|
+
context "By number" do
|
8
|
+
it "the number of simple interval do-mi should be a 3rd" do
|
9
|
+
MusicUtils.number('do', 'mi').should == 3
|
10
|
+
end
|
11
|
+
it "the number of do-mi compound interval should be a 10th" do
|
12
|
+
MusicUtils.number('do', 'mi', 1).should == 10
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "By semitones" do
|
17
|
+
it "simple interval do-mi should be 4 semitones" do
|
18
|
+
MusicUtils.semitones('do', 'mi').should == 4
|
19
|
+
end
|
20
|
+
it "compound interval do-mi should be 16 semitones" do
|
21
|
+
MusicUtils.semitones('do', 'mi', 1).should == 16
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "By quality" do
|
26
|
+
it "quality of interval do-mi should be M" do
|
27
|
+
MusicUtils.quality('do', 'mi').should == 'M'
|
28
|
+
end
|
29
|
+
it "quality of compound interval do-mi should be M" do
|
30
|
+
MusicUtils.quality('do', 'mi', 1).should == 'M'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "By short notation" do
|
35
|
+
it "the short notation of do#-mi interval should be m3" do
|
36
|
+
MusicUtils.short('do#', 'mi').should == 'm3'
|
37
|
+
end
|
38
|
+
it "the short notation of do#-mi compound interval should be m10" do
|
39
|
+
MusicUtils.short('do#', 'mi', 1).should == 'm10'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: music-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,33 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-05-06 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &20979048 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.8'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *20979048
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: bundler
|
27
|
+
requirement: &20978820 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *20978820
|
14
36
|
- !ruby/object:Gem::Dependency
|
15
37
|
name: rspec
|
16
|
-
requirement: &
|
38
|
+
requirement: &20978544 !ruby/object:Gem::Requirement
|
17
39
|
none: false
|
18
40
|
requirements:
|
19
41
|
- - ! '>='
|
@@ -21,8 +43,8 @@ dependencies:
|
|
21
43
|
version: '0'
|
22
44
|
type: :development
|
23
45
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
description: Utils for music. At the moment only
|
46
|
+
version_requirements: *20978544
|
47
|
+
description: Utils for music. At the moment only to classify intervals.
|
26
48
|
email:
|
27
49
|
- jorgeluis700@gmail.com
|
28
50
|
executables: []
|
@@ -32,13 +54,16 @@ files:
|
|
32
54
|
- .gitignore
|
33
55
|
- CHANGELOG.md
|
34
56
|
- Gemfile
|
35
|
-
- Gemfile.lock
|
36
57
|
- LICENSE
|
37
58
|
- README.md
|
38
59
|
- Rakefile
|
39
|
-
- lib/
|
60
|
+
- lib/music-utils.rb
|
61
|
+
- lib/music-utils/interval/interval.rb
|
62
|
+
- lib/music-utils/scales/scales.rb
|
63
|
+
- lib/music-utils/version.rb
|
40
64
|
- music-utils.gemspec
|
41
|
-
- spec/interval_spec.rb
|
65
|
+
- spec/interval/interval_spec.rb
|
66
|
+
- spec/music-utils_spec.rb
|
42
67
|
homepage: http://github.com/jorgeluis700/music-utils
|
43
68
|
licenses:
|
44
69
|
- MIT
|
@@ -52,9 +77,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
52
77
|
- - ! '>='
|
53
78
|
- !ruby/object:Gem::Version
|
54
79
|
version: '0'
|
55
|
-
segments:
|
56
|
-
- 0
|
57
|
-
hash: 934369633
|
58
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
81
|
none: false
|
60
82
|
requirements:
|
@@ -66,5 +88,5 @@ rubyforge_project:
|
|
66
88
|
rubygems_version: 1.7.2
|
67
89
|
signing_key:
|
68
90
|
specification_version: 3
|
69
|
-
summary: music
|
91
|
+
summary: Utils for music
|
70
92
|
test_files: []
|
data/Gemfile.lock
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
diff-lcs (1.1.2)
|
5
|
-
rake (0.8.7)
|
6
|
-
rspec (2.5.0)
|
7
|
-
rspec-core (~> 2.5.0)
|
8
|
-
rspec-expectations (~> 2.5.0)
|
9
|
-
rspec-mocks (~> 2.5.0)
|
10
|
-
rspec-core (2.5.1)
|
11
|
-
rspec-expectations (2.5.0)
|
12
|
-
diff-lcs (~> 1.1.2)
|
13
|
-
rspec-mocks (2.5.0)
|
14
|
-
|
15
|
-
PLATFORMS
|
16
|
-
ruby
|
17
|
-
x86-mingw32
|
18
|
-
|
19
|
-
DEPENDENCIES
|
20
|
-
rake (~> 0.8)
|
21
|
-
rspec (~> 2.5)
|
data/lib/interval.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
# Scales module
|
2
|
-
module Scales
|
3
|
-
DIATONIC_SCALE = ['do', 're', 'mi', 'fa', 'sol', 'la', 'si']
|
4
|
-
QUALITIES = {
|
5
|
-
2 => {0 => 'd', 1 => 'm', 2 => 'M', 3 => 'A', 4 => 'AA'},
|
6
|
-
3 => {1 => 'dd', 2 => 'd', 3 => 'm', 4 => 'M', 5 => 'A', 6 => 'AA'},
|
7
|
-
4 => {3 => 'dd', 4 => 'd', 5 => 'P', 6 => 'A', 7 => 'AA'},
|
8
|
-
5 => {5 => 'dd', 6 => 'd', 7 => 'P', 8 => 'A', 9 => 'AA'},
|
9
|
-
6 => {6 => 'dd', 7 => 'd', 8 => 'm', 9 => 'M', 10 => 'A', 11 => 'AA'},
|
10
|
-
7 => {8 => 'dd', 9 => 'd', 10 => 'm', 11 => 'M', 12 => 'A', 13 => 'AA'},
|
11
|
-
8 => {10 => 'dd', 11 => 'd', 12 => 'P', 13 => 'A', 14 => 'AA'}
|
12
|
-
}
|
13
|
-
end
|
14
|
-
|
15
|
-
# This class represents a music interval
|
16
|
-
class Interval
|
17
|
-
include Scales
|
18
|
-
|
19
|
-
def initialize(note1, note2, step)
|
20
|
-
@note1 = note1
|
21
|
-
@note2 = note2
|
22
|
-
@step = step
|
23
|
-
end
|
24
|
-
|
25
|
-
# It classifies the diatonic interval
|
26
|
-
def number
|
27
|
-
# initialize counter and index of scale
|
28
|
-
i = note1_index
|
29
|
-
count = 1
|
30
|
-
|
31
|
-
count, i = no_unison(count, i)
|
32
|
-
|
33
|
-
# Counting notes
|
34
|
-
until_find_note2(i) { count += 1 }
|
35
|
-
|
36
|
-
count = count + (8 * @step) - 1 if @step > 0
|
37
|
-
count
|
38
|
-
end
|
39
|
-
|
40
|
-
# Returns the number of semitones
|
41
|
-
def semitone
|
42
|
-
# initialize counter and index of scale
|
43
|
-
i = note1_index
|
44
|
-
count = 0
|
45
|
-
|
46
|
-
count, i = no_unison(count, i)
|
47
|
-
|
48
|
-
# counting semi-tones
|
49
|
-
until_find_note2(i) do |i|
|
50
|
-
# from 'mi' to 'fa' and 'si' to 'do' there 1 semi-tone
|
51
|
-
if DIATONIC_SCALE[i] == 'fa' or DIATONIC_SCALE[i] == 'do'
|
52
|
-
count += 1
|
53
|
-
else
|
54
|
-
count += 2
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
count = count + (12 * @step) if @step > 0
|
59
|
-
|
60
|
-
# counting notes alterations
|
61
|
-
alter = @note1[2..3]
|
62
|
-
|
63
|
-
alter.each_char do |c|
|
64
|
-
count += 1 if c == 'b'
|
65
|
-
count -= 1 if c == '#'
|
66
|
-
end
|
67
|
-
|
68
|
-
alter = @note2[2..3]
|
69
|
-
|
70
|
-
alter.each_char do |c|
|
71
|
-
count -= 1 if c == 'b'
|
72
|
-
count += 1 if c == '#'
|
73
|
-
end
|
74
|
-
|
75
|
-
count
|
76
|
-
end
|
77
|
-
|
78
|
-
# Returns the quality of the interval
|
79
|
-
def quality
|
80
|
-
s = ( @step > 0 and semitone - (12 * @step) ) || semitone
|
81
|
-
n = ( @step > 0 and number - (7 * @step) ) || number
|
82
|
-
QUALITIES[n][s]
|
83
|
-
end
|
84
|
-
|
85
|
-
# Returns the class interval in the short notation
|
86
|
-
def short
|
87
|
-
quality + number.to_s
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
# Common loop to search note 2
|
93
|
-
def until_find_note2(i)
|
94
|
-
# search note2
|
95
|
-
while DIATONIC_SCALE[i] != @note2[0..1]
|
96
|
-
i += 1
|
97
|
-
if i > DIATONIC_SCALE.length
|
98
|
-
i = 0; next
|
99
|
-
end
|
100
|
-
yield i
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# Jumps to the next note if note 1 and note 2 are the same
|
105
|
-
def no_unison(count, i)
|
106
|
-
if @note1[0..1] == @note2[0..1]
|
107
|
-
count += 1; i += 1
|
108
|
-
end
|
109
|
-
[count, i]
|
110
|
-
end
|
111
|
-
|
112
|
-
# Returns index of note 1
|
113
|
-
def note1_index
|
114
|
-
DIATONIC_SCALE.index(@note1[0..1])
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|