The Circle of Fifths, Part One
coderedux.com
coderedux.com
NOTES = ['c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g', 'g#', 'a', 'a#', 'b']
# 2 is a whole step, 1 is a half step
MAJOR_STEPS = [2,2,1,2,2,2,1]
# returns the scale in the given key with the given steps
def scale(key, steps)
note = NOTES.index(key)
step = 0
notes = []
while step < steps.length
notes << NOTES[note % NOTES.length]
note += steps[step]
step += 1
end
notes
end
scale('d', MAJOR_STEPS) #=> ["d", "e", "f#", "g", "a", "b", "c#"]
I think this shows how a scale is just a list of steps applied to the notes from a certain key :)He starts with a basic sine wave and builds up abstractions until he has a Bach canon.
links aside, he uses (and is a project contributor) http://overtone.github.com/
ps: they also provide a nice emacs setup https://github.com/overtone/emacs-live
I agree. That is 1 million times better. Sometimes I wonder why I don't think of these things. I'll probably fix the code and use something like that... except in Python, obv.
Thank you;
It is something I practice a lot, maybe because it's in Ruby's culture, or just because I enjoy making code look pretty.
When I look at your two for loops that twice make a range, and have a bunch of magic numbers, all kinds of alarm bells go off. It should be one loop if possible, if there are magic numbers they should be in a constant at the top of the file.
Actually, the way you construct the seedList is interesting. A Haskell programmer might have done the same thing, because keeping indexes is ugly in Haskell, and doing operations on infinite lists (which you emulate by appending a copy) are pretty. Perhaps you are just a functional programmer, using a non-functional language :D
It would look better if it was in Scheme or Clojure, but that stuff's too scary for most readers. At least that's the story I'll maintain here.
Of all the bits and pieces I've looked at over the years explaining the circle of fifths this is the one that stands out for me as the easiest to remember. Being able to re-derive from basic principles is so much better than memorization.
Thank you again!
def notes_name(numbers):
notes = "C C# D D# E F F# G G# A A# B".split()
return [notes[(number % 12)] for number in numbers]
def transposition(notes, start):
index = start - notes[0]
return [(n + index) % 12 for n in notes]
def gen_scales():
c_scale = [0, 2, 4, 5, 7, 9, 11]
return [notes_name(transposition(c_scale, note)) for note in range(0, 12)]
for scale in gen_scales():
print " ".join(scale)
EDIT: make the code prettier notes_name([n*7 for n in range(0, 12)]) notes = concat $ repeat ["c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "b"]
majorSteps = [1,1,0,1,1,1,0]
scale key steps =
key : skip notesFromKey majorSteps
where
(_:notesFromKey) = dropWhile ((/=) key) notes
skip list skips =
fst $ foldl next ([], list) skips
where
next (m, xs) s = (m ++ [xs !! s], drop (s + 1) xs)
edit: cleaned it up a lot. This is Haskell by the way. The loop is replaced by a 'fold' in the skip function that reduces the list by skipping through it taking the skip distances from the skips argument. notes = cycle ["c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "b"]
majorSteps = [2, 2, 1, 2, 2, 2] :: [Int]
scale note = map (dropWhile (/= note) notes !!) . scanl (+) 0
I think it's less clear, but if you want to avoid the rescan via (!!), then scale note = map head . scanl (flip drop) (dropWhile (/= note) notes)
Both result in λ> scale "d" majorSteps
["d","e","f#","g","a","b","c#"]We generally treat Gb and F# as the same note, but if you actually count perfect Pythagorean fifths (frequency ratios of 3:2) in both directions from C, Gb and F# don't actually perfectly meet in the middle!
http://www.phy.mtu.edu/~suits/notefreqs.html
The ratios between subsequent notes differ, but not by much.
Edit: a quickie spreadsheet gives me 0.009502 for the largest difference between two tones.
See also:
The deviation should preferably be less than, say, 1Hz, because you hear the difference in frequency as the beat frequency.
G# A# B# C# D# E# F##
And it is a very important point, because each scale on the circle of fifth has one more sharp than the previous one when turning in one direction, and one more flat in the other one.
Another point is that there is actually a comma between F# and Gb, and between F## and G, because the chromatic semi-tone is one comma shorter than the diatonic semi-tone -- Though of course the distinction isn't done on a tempered instrument such as a piano or a guitar.
It is all actually quite simple, but not /that/ simple :)
Basically, take the home chord of a tune and apply one of the following:
If "major" then switch to the relative minor, or vice versa.
Go Round the circle of fifths or the circLe of fourths either direction, but stay on whichever side of "major/minor."
Go up or down the scale, staying on whichever side of "major/minor."
So for example, a tune set with E minor, G major, A major should work. (Again, not exactly it, but don't want to explain modes.)
I'll try and walk through it.
> If "major" then switch to the relative minor, or vice versa.
OK, home chord is Em, so we'll use G major.
> Go Round the circle of fifths or the circLe of fourths either direction, but stay on whichever side of "major/minor."
OK, that's C or D given G as the starting point.
> Go up or down the scale, staying on whichever side of "major/minor."
So playing the G, C, or D scale over an E minor progression. G makes sense, same scale as Em; C or D... don't even parse for me. I don't think of chords and scales as separate, changing the scale changes the underlying chords I'd play under them, thus changing the key to something other than Em.
> So for example, a tune set with E minor, G major, A major should work.
What? Nothing you just said would lead me to think A major would work over an Em progression. G major, sure, obvious, it's the relative major of Em and just another name for G major scale, but A... why A, you haven't explained that above, your example doesn't match what the instructions seem to say.
I did this at a competition once when given some insane scales (like 3 flats in the clef) without having ever practiced the scale itself and got it right.
I also started here to demonstrate how logical it all is.
Thank you so much;