Skip to content

Instantly share code, notes, and snippets.

@aalin
Created April 14, 2010 20:23
Show Gist options
  • Select an option

  • Save aalin/366294 to your computer and use it in GitHub Desktop.

Select an option

Save aalin/366294 to your computer and use it in GitHub Desktop.
Figure out chord intervals
# Program output:
#
# Chord: [0, 4, 7]
# [:major, [[0, :unison], [4, :third], [7, :fifth]]]
# [:minor, [[0, :unison], [3, :third], [8, :sixth]]]
# [:major, [[0, :unison], [5, :fourth], [9, :sixth]]]
# Chord: [0, 4, 7, 11]
# [:major, [[0, :unison], [4, :third], [7, :fifth], [11, :seventh]]]
# [:minor, [[0, :unison], [3, :third], [7, :fifth], [8, :sixth]]]
# [:major, [[0, :unison], [4, :third], [5, :fourth], [9, :sixth]]]
# [:minor, [[0, :unison], [1, :second], [5, :fourth], [8, :sixth]]]
# Chord: [1, 4, 8]
# [:minor, [[0, :unison], [3, :third], [7, :fifth]]]
# [:major, [[0, :unison], [4, :third], [9, :sixth]]]
# [:minor, [[0, :unison], [5, :fourth], [8, :sixth]]]
# Chord: [1, 6, 9]
# [:minor, [[0, :unison], [5, :fourth], [8, :sixth]]]
# [:minor, [[0, :unison], [3, :third], [7, :fifth]]]
# [:major, [[0, :unison], [4, :third], [9, :sixth]]]
#
require 'rotations'
INTERVAL_NAMES = {
:perfect => {
0 => :unison,
5 => :fourth,
7 => :fifth
},
:major => {
2 => :second,
4 => :third,
9 => :sixth,
11 => :seventh
},
:minor => {
1 => :second,
3 => :third,
8 => :sixth,
10 => :seventh
},
:augmented => {
1 => :unison,
3 => :second,
5 => :third,
6 => :fourth,
8 => :fifth,
10 => :sixth,
12 => :seventh
},
:diminished => {
-1 => :unison,
0 => :second,
2 => :third,
4 => :fourth,
6 => :fifth,
7 => :sixth,
9 => :seventh,
11 => :octave
}
}
def interval_names(intervals)
[
[ :major, INTERVAL_NAMES[:perfect].merge(INTERVAL_NAMES[:major]) ],
[ :minor, INTERVAL_NAMES[:perfect].merge(INTERVAL_NAMES[:minor]) ],
[ :augmented, INTERVAL_NAMES[:augmented] ],
[ :diminished, INTERVAL_NAMES[:diminished] ],
].each do |mode, interval_names|
x = intervals.map { |i| interval_names[i] }
return [mode, intervals.zip(x)] if x.all?
end
false
end
def figure_out_chord(chord)
puts "Chord: #{ chord.inspect }"
chord.rotations.each do |rotation|
root = rotation.first
intervals = rotation.map { |i| (12 + i - root) % 12 }
if names = interval_names(intervals)
puts " #{ names.inspect }"
end
end
end
figure_out_chord([0, 4, 7]) # C major
figure_out_chord([0, 4, 7, 11]) # C major seventh
figure_out_chord([1, 4, 8]) # C# minor
figure_out_chord([1, 6, 9]) # Some minor chord, starting on 6
class Array
def rotate!
push(shift)
end
def rotate
dup.rotate!
end
# >> [1, 2, 3].rotations
# => [[1, 2, 3], [2, 3, 1], [3, 1, 2]]
def rotations
size.times.map do |i|
i.times.inject(self) { |a,_| a.rotate }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment