make-scale.lsp

A neat little function to create a scale in the form of a list of pitch symbols, e.g. ‘(c4 d4 e4 f4 g4 a4 b4 c5).

Possibilities include:

  • major
  • natural minor
  • harmonic minor
  • melodic minor upwards
  • melodic minor downwards
  • ionian
  • dorian
  • mixolydian
  • phrygian
  • lydian
  • aeolian
  • locrian
  • ahava-raba
  • whole-tone
  • chromatic
  • custom (roll your own!)

You can also chose the enharmonics of the black notes.

NB: Chromatic notes only, no micro-tones!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; File:    make-scale.lsp
;;;
;;; Author:  Daniel James Ross (mr.danielross@gmail.com)
;;;
;;; Date:    23 May 2016
;;;
;;; Update:  Fri Sep 23 10:54:44 BST 2016
;;;
;;; Purpose: Create a list of pitches contained in a specific scale,
;;;          e.g. major, natural minor, harmonic minor, ionian, etc.
;;;          Custom scales also possible.
;;;
;;; Output:  A list of pitch symbols e.g. '(c4 d4 e4 f4 g4 a4 b4 c5)
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun make-scale (scale-type        ; see possibilities below
           root            ; lowest note of scale
           &key
             (num-octaves 2)
             ;; list of semitones or tones
             ;; e.g. '(1 2 1 1 1)
             custom-scale 
             enharm)        ; sharps or flats
  ;; Generate a scale
  (unless (typep scale-type 'atom)
    (error "~a is not a valid scale type" scale-type))
  (let ((scale-pattern
     ;; scale types
     (cond ((equalp scale-type 'major) 
        '(2 2 1 2 2 2 1))
           ((equalp scale-type 'nat-minor)
        '(2 1 2 2 1 2 2))
           ((equalp scale-type 'harm-minor)
        '(2 1 2 2 2 1 2))
           ((equalp scale-type 'mel-minor-up)
        '(2 1 2 2 2 2 1))
           ((equalp scale-type 'mel-minor-down)
        '(2 1 2 2 2 1 2))
           ((equalp scale-type 'ionian)
        '(2 2 1 2 2 2 1))
           ((equalp scale-type 'dorian)
        '(2 1 2 2 2 1 2))
           ((equalp scale-type 'mixolydian)
        '(2 2 1 2 2 1 2))
           ((equalp scale-type 'phrygian)
        '(1 2 2 2 1 2 2))
           ((equalp scale-type 'lydian)
        '(2 2 2 1 2 2 1))
           ((equalp scale-type 'aeolian)
        '(2 1 2 2 1 2 2))
           ((equalp scale-type 'locrian)
        '(1 2 2 1 2 2 2))
           ((equalp scale-type 'ahava-raba)
        '(1 2 1 2 1 2 2))
           ((equalp scale-type 'whole-tone)
        '(2 2 2 2 2))
           ((equalp scale-type 'chromatic)
        '(1 1 1 1 1 1 1 1 1 1))
           ((equalp scale-type 'custom)
        custom-scale))))
    (unless enharm
      (if (or (is-flat root)
          (octave-freqs (note-to-freq 'f4)
                (note-to-freq root)))
      (setf enharm 'flats)
      (setf enharm 'sharps)))
    (unless scale-pattern
      (error "~a is not recognised.~%Misspelling or no custom data?"
         scale-type))
    (flatten
     (loop repeat num-octaves collect
      (list root
        (loop for interval in scale-pattern
           with note = root
           do (setf note
                (midi-to-note
                 (+ (note-to-midi note)
                interval)))
           collect (if (or (and (equalp enharm 'sharps)
                    (is-flat note))
                   (and (equalp enharm 'flats)
                    (is-sharp note)))
                   (data (enharmonic
                      (make-pitch note)))
                   note)))
    do (setf root (midi-to-note (+ 12 (note-to-midi root))))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; EOF make-scale.lsp
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s