Created
July 9, 2010 02:43
-
-
Save mhfs/468966 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Note; end | |
class C < Note; end | |
class Cs < C; end | |
class D < Note; end | |
class Db < D; end | |
class Ds < D; end | |
class E < Note; end | |
class Eb < E; end | |
class F < Note; end | |
class Fs < F; end | |
class G < Note; end | |
class Gb < G; end | |
class Gs < G; end | |
class A < Note; end | |
class Ab < A; end | |
class As < A; end | |
class B < Note; end | |
class Bb < B; end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module DiatonicScale | |
NOTES = [C, Cs, D, Ds, E, F, Fs, G, Gs, A, As, B] | |
DISTANCES = [2, 2, 1, 2, 2, 2] | |
INDEXES = { | |
C => 0, | |
Cs => 1, Db => 1, | |
D => 2, | |
Ds => 3, Eb => 3, | |
E => 4, | |
F => 5, | |
Fs => 6, Gb => 6, | |
G => 7, | |
Gs => 8, Ab => 8, | |
A => 9, | |
As => 10, Bb => 10, | |
B => 11 | |
} | |
ADJUSTMENTS = { | |
Cs => Db, | |
Ds => Eb, | |
Fs => Gb, | |
Gs => Ab, | |
As => Bb | |
} | |
def + (distance) | |
NOTES[(INDEXES[self] + distance) % NOTES.size] | |
end | |
def diatonic_scale | |
DISTANCES.inject([self]) { |result, distance| result << adjust(result.last, result.last + distance) } | |
end | |
def adjust(prev, result) | |
result.superclass != prev ? result : ADJUSTMENTS[result] | |
end | |
end | |
Note.extend DiatonicScale |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'test/unit' | |
class DiatonicScalesTest < Test::Unit::TestCase | |
def test_C | |
assert_equal [C, D, E, F, G, A, B], C.diatonic_scale | |
end | |
def test_D | |
assert_equal [D, E, Fs, G, A, B, Cs], D.diatonic_scale | |
end | |
def test_E | |
assert_equal [E, Fs, Gs, A, B, Cs, Ds], E.diatonic_scale | |
end | |
def test_F | |
assert_equal [F, G, A, Bb, C, D, E], F.diatonic_scale | |
end | |
def test_G | |
assert_equal [G, A, B, C, D, E, Fs], G.diatonic_scale | |
end | |
def test_A | |
assert_equal [A, B, Cs, D, E, Fs, Gs], A.diatonic_scale | |
end | |
def test_B | |
assert_equal [B, Cs, Ds, E, Fs, Gs, As], B.diatonic_scale | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment