Musical scales in F#

Before I start, please be aware that I am a complete novice as far as music theory is concerned, and I’m just covering some details so that the F# script below will make sense to a wider audience. Please let me know if I get any terminology wrong.

I was recently brushing up on some very basic music theory, specifically musical scales. Basically, you have twelve notes:

  1. A A# B C C# D D# E F F# G G#

The sequence of notes loops, so G# is followed by A again, except the A is an octave higher than the previous A. Most scales that I’m aware of start at one of the notes (the root note) and then skip various notes before arriving back at the root note an octave higher. We say that moving from one note to its neighbour is moving “half a step”. So going half a step up from A gives you A#. You can skip any number of half steps. Skipping a whole step up (two half-steps) from A gives you a B.

A major scale is constructed by choosing a root note, then moving the following sequence of steps. I’ll use F for a full step, H for half:

  1. F F H F F F H

So, starting at A, we get:

  1. A B C# D E F# G# A

That’s the A major scale. Different scales have different intervals. Natural minor goes:

  1. F H F F H F F

So, starting at A with the natural minor scale gives:

  1. A B C D E F G A

Simple enough eh?

I thought that generating scales would be a task well suited to F#, and I was right. The script below can be used to generate some major and natural minor scales. Initially I declare the notes, using ‘ to denote sharps. I then provide a function which can be used to move up a number of half-steps from a starting note.

The interesting bit is then the getScale function. This takes a root note, and a list of Note -> Note functions representing the intervals in the scales. It then uses the List.scan function to generate all the notes covered by the intervals. List.scan is similar to List.fold (or Linq’s Aggregate function), the difference being that each intermediate result of the fold is returned together with the final result in a sequence. Sadly, there doesn’t appear to be an equivalent of scan in Linq, but it’s not too hard to write yourself. Anyway…

After the getScale function, we declare a couple of scales by their intervals – the major and natural minor. Then we use those scales with the getScale function and some root notes.

  1. type note = A | A' | B | C | C' | D | D' | E | F | F' | G | G'
  3. let up halfSteps n =
  4.     let chromatic = [ A; A'; B; C; C'; D; D'; E; F; F'; G; G' ]
  5.     let i = (chromatic |> List.findIndex ((=) n)) + halfSteps
  6.     chromatic.[i % chromatic.Length]
  8. let half = up 1
  10. let full = up 2
  12. let getScale root = List.scan (fun n f -> f n) root
  14. let major = [ full; full; half; full; full; full; half ]
  16. let naturalMinor = [ full; half; full; full; half; full; full ]
  18. [ getScale C major
  19.   getScale A naturalMinor
  20.   getScale C' naturalMinor
  21. ] |> List.iter (printfn "%A")

That script prints the following, the C major scale, the A minor scale, and the C# minor scale:

  1. [C; D; E; F; G; A; B; C]
  2. [A; B; C; D; E; F; G; A]
  3. [C'; D'; E; F'; G'; A; B; C']

I think that script is pretty nifty.

Share and Enjoy:
  • Print
  • Digg
  • StumbleUpon
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • LinkedIn
  • Technorati