Expanding on what Alex has already point out, you can do something like this:

;; PitchClass is one of
(define C 0)
(define C# 1)
(define D 2)
(define D# 3)
(define E 4)
(define F 5)
(define F# 6)
(define G 7)
(define G# 8)
(define A 9)
(define A# 10)
(define B 11)

;; Interval is Natural
;; number of semitones between two notes
;; assume: ascending intervals
(define FIFTH 7)  ;number of semitones
(define FOURTH 5) ;ditto

;; Direction is "up" or "down"
;; the direction of rotation around a circle of fifths
;; "up" means clockwise (ascending fifths), "down" counterclockwise
;; (descending fifths)

;; PitchClass PitchClass -> Nat
;; produce number of semitones between pc1 and pc2
;; where pc1 is lower than pc2
(define (interval pc1 pc2)
  (modulo (- pc2 pc1) 12))

;; PitchClass Interval -> PitchClass
;; produce the pitch class at the given ascending interval from pc
(define (next pc interval)
  (modulo (+ pc interval) 12))

;; Some 'next' concrete functions, for convenience
(define perfect-fifth (curryr next FIFTH))
(define perfect-fourth (curryr next FOURTH))

;; PitchClass PitchClass Direction -> PitchClass (listof PitchClass) Nat
;; ...
(define (fifths-from-to from to by)
  (define-values (next count)
    (if (string=? by "up")
        (values perfect-fifth add1)
        (values perfect-fourth sub1)))
  (for/fold ([init from]
             [circle-up-to null]
             [fifths# 0])
            ([i (in-naturals)]
             #:break (equal? init to))
    (values (next init)
            (append circle-up-to (list init))
            (count fifths#))))

The last function produces as last value the distance in ascending/descending 
fifths as you has hardcoded in the table. There might be better for forms to 
implement the same or you can use another style. Or you can produce something 
simpler like the positive count of fifths/forths, and convert it with another 
function to obtain the representation (positive/negative numbers) you want. As 
a bonus the function produces the actual ascending/descending fifths between 
the initial one (from) up to the final one (to) fifth, not included, it is the 
second value of the result. Anyway, you could pass the result to another 
function to do whatever you like with those values.

The rationale is just that each pitch-class is represented, as usual in music, 
by the way, by an integer from 0 to 11. This makes easier to work on 
intervallics by simple arithmetic. Based on it producing sequences of 
pitch-classes at the same intervallic like the circle of fifths is just a 
matter of generating it recursively. In addition, as a fourth is just the 
inversion of a fifth, you can traverse/generate the circle of descending fifths 
using fourths. 

You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to