music-utils 0.5.2 → 1.0.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/.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
|