\version "2.15.3" #(define (extract-pitch-sequence music) "Recurse through @var{music}, extracting pitches. Returns a list of pitch objects, e.g @code{'((ly:make-pitch 0 2 0) (ly:make-pitch 0 4 0) ... )} Typically used to construct a scale for input to transposer-factory (see). " (let ((elements (ly:music-property music 'elements)) (element (ly:music-property music 'element)) (pitch (ly:music-property music 'pitch))) (cond ((ly:pitch? pitch) pitch) ((pair? elements) (map (lambda (x) (extract-pitch-sequence x)) elements)) ((ly:music? element) (extract-pitch-sequence element))))) #(define (enharmonic pitch0 pitch1 enharmonic-class) "Whether two pitches are enharmonic." (equal? (enharmonic-class pitch0) (enharmonic-class pitch1))) %TODO: implement this with a dictionary. #(define (enharmonic-from scale pitch enharmonic-class enharmonic-octaves) "The first enharmonic equivalent of pitch from scale." (if (pair? scale) (let ((pitch1 (caar scale))) (if (enharmonic pitch pitch1 enharmonic-class) ; adjust octave of pitch1 (ly:pitch-transpose pitch1 (ly:make-pitch (enharmonic-octaves (ly:pitch-diff pitch pitch1)) 0 0)) (enharmonic-from (cdr scale) pitch enharmonic-class enharmonic-octaves))) pitch)) #(define (enharmonize-pitch pitch scale enharmonic-class enharmonic-octaves) (let ((p (ly:music-property pitch 'pitch))) (if (ly:pitch? p) (ly:music-set-property! pitch 'pitch (enharmonic-from scale p enharmonic-class enharmonic-octaves))) pitch)) #(define (enharmonize scale music enharmonic-class enharmonic-octaves) "Replaces pitches in music by their enharmonic counterpart in scale." (let ((s (extract-pitch-sequence scale))) (music-map (lambda (x) (enharmonize-pitch x s enharmonic-class enharmonic-octaves)) music))) enharmonizeMusic = #(define-music-function (parser location scale music enharmonic-class enharmonic-octaves) (ly:music? ly:music? procedure? procedure?) (_i "Replace pitches in @var{music} by their enharmonic counterpart in @var{scale}.") (enharmonize scale music enharmonic-class enharmonic-octaves)) #(define (frac x) (- x (floor x))) #(define (alg-alteration pitch) "Second coefficient of an algebraic pitch representation modulo octave," " the first one being (ly:pitch-notename pitch)" (+ (ly:pitch-alteration pitch) (if (> (ly:pitch-notename pitch) 2) -1/2 0))) #(define (et12-value pitch) "Auxiliary." (* 1/6 (+ (ly:pitch-notename pitch) (alg-alteration pitch)))) #(define (et12-class pitch) "pitch modulo octave in ET12, represented as a fraction of the octave" (frac (et12-value pitch))) #(define (et12-octaves pitch) "If pitch is equivalent to an integer number of octaves in ET12," " returns that value. Otherwise, return value is unspecified." (+ (ly:pitch-octave pitch) (et12-value pitch))) #(define (et31-value pitch) "Auxiliary." (+ (* 5/31 (ly:pitch-notename pitch)) (* 4/31 (alg-alteration pitch)))) #(define (et31-class pitch) "pitch modulo octave in ET31, represented as a fraction of the octave" (frac (et31-value pitch))) #(define (et31-octaves pitch) "If pitch is equivalent to an integer number of octaves in ET31," " returns that value. Otherwise, return value is unspecified." (+ (ly:pitch-octave pitch) (et31-value pitch))) esMinor = { es f ges as bes ces des } mus = { dis' feses' c'' aisis' } mu = { bisis' feses' } { \key es \minor \mus \enharmonizeMusic \esMinor \mus #et12-class #et12-octaves \enharmonizeMusic \esMinor \transpose es es' \mus #et12-class #et12-octaves \enharmonizeMusic \esMinor \transpose es' es \mus #et12-class #et12-octaves % example for 31-step equal temperament \mu \enharmonizeMusic { deses cis des cisis eses dis es disis } \mu #et31-class #et31-octaves }