Le lundi 29 décembre 2008 à 10:16 +0100, Stefan Thomas a écrit : > Dear John, > I understood now. You have a note 0 in c major and in a minor, which > is a c.
The most meaningful I think is that c major and a minor define the same major scale in LilyPond, only the tonic (c or a, respectively) differ. > In my opinion it would be better to understand for a musician, > if You could use the intervall-names. You're right, and it could simply be done by defining secondUp = #1 thirdUp = #2 ... seventhUp = #7 secondDown = #1 ... seventhDown = #-7 and using these variables with a backslash in \diatonicTranspose and \modeTranspose. However, your remarks also made me think about simplifying the syntax for saving the typist the effort of computing the degree delta himself. With the revised snippet below, the functions now take a start pitch and a final pitch instead of a degree delta; that is, think about the syntax of these functions of being the same as (chromatic) \transpose, except you insert additional arguments to specify one (for \diatonicTranspose or two (for \modeTranspose) modes. See at the end of the code below for examples; is this syntax more user-friendly? #(define (true-quotient n d) "Return the true quotient in integer division of n by d, i.e. return the integer q so that there is a unique integer r that satisfies n = qd + r and 0 <= r < |d|" (if (>= n 0) (quotient n d) (- (quotient n d) 1))) #(define (ly-pitch->modal-pitch ly-pitch scale tonic-c-diff) "Convert ly-pitch to a list (octave degree depresentation) which represents the modal pitch in scale, with tonic-c-diff as the pitch diff from tonic to middle C. scale should be a notename->alteration alist of length 7 which represents the alteration of each note with C as first pitch of the scale." (let* ((normalized-pitch (ly:pitch-transpose ly-pitch tonic-c-diff)) (notename (ly:pitch-notename normalized-pitch))) (list (ly:pitch-octave normalized-pitch) ;; octave notename ;; degree ;; alteration (- (ly:pitch-alteration normalized-pitch) (ly:assoc-get notename scale 0))))) #(define (degree-transpose modal-pitch modal-pitch-delta scale-length) "Transpose modal-pitch (octave degree alteration) by modal-pitch-delta assuming scale-length." (let* ((octave (car modal-pitch)) (degree (cadr modal-pitch)) (alteration (caddr modal-pitch)) (octave-delta (car modal-pitch-delta)) (degree-delta (cadr modal-pitch-delta)) (alteration-delta (caddr modal-pitch-delta)) (relative-new-degree (+ degree degree-delta))) (list (+ octave octave-delta (true-quotient relative-new-degree scale-length)) (modulo relative-new-degree scale-length) (+ alteration alteration-delta)))) #(define (modal-pitch->ly-pitch modal-pitch scale c-tonic-diff) "Convert modal-pitch -- a list (octave degree alteration) -- to a standard pitch using scale and pitch diff from middle C to tonic. scale should be a notename->alteration alist of length 7 which represents the alteration of each note with C as first pitch of the scale." (let* ((octave (car modal-pitch)) (degree (min 6 (cadr modal-pitch))) (alteration (caddr modal-pitch)) (abs-alteration (+ alteration (ly:assoc-get degree scale 0)))) (ly:pitch-transpose (ly:make-pitch octave degree abs-alteration) c-tonic-diff))) #(define (lookup-music-property event type) "Return the first music property of the given type found in event, or #f is no such property is found. event should be music or a list of music." (if (null? event) #f (if (list? event) (or (lookup-music-property (car event) type) (lookup-music-property (cdr event) type)) (let ((p (ly:music-property event 'pitch))) (if (not (null? p)) p (let* ((e (ly:music-property event 'element)) (es (ly:music-property event 'elements)) (p2 (if (null? e) '() (lookup-music-property e type)))) (if (not (null? p2)) p2 (lookup-music-property es type)))))))) #(define (mode-transpose pitch-note1 pitch-note2 tonic-note1 scale1 tonic-note2 scale2 music) (let* ((tonic-diff1 (ly:pitch-diff (ly:make-pitch 0 0 0) (lookup-music-property tonic-note1 'pitch))) (tonic-diff2 (ly:pitch-diff (lookup-music-property tonic-note2 'pitch) (ly:make-pitch 0 0 0))) (modal-pitch-delta (map - (ly-pitch->modal-pitch (lookup-music-property pitch-note2 'pitch) scale2 (ly:pitch-negate tonic-diff2)) (ly-pitch->modal-pitch (lookup-music-property pitch-note1 'pitch) scale1 tonic-diff1)))) (music-map (lambda (event) (let ((p (ly:music-property event 'pitch))) (if (ly:pitch? p) (ly:music-set-property! event 'pitch (modal-pitch->ly-pitch (degree-transpose (ly-pitch->modal-pitch p scale1 tonic-diff1) modal-pitch-delta 7) scale2 tonic-diff2))) event)) music))) modeTranspose = #(define-music-function (parser location pitch-note1 pitch-note2 tonic-note1 scale1 tonic-note2 scale2 music) (ly:music? ly:music? ly:music? list? ly:music? list? ly:music?) "Transpose music diatonicly by the interval between pitch-note1 and pitch-note2, interpreting pitches in scale1 on tonic-note1 and producing pitches in scale2 on tonic-note2." (mode-transpose pitch-note1 pitch-note2 tonic-note1 scale1 tonic-note2 scale2 music)) diatonicTranspose = #(define-music-function (parser location pitch-note1 pitch-note2 tonic-note scale music) (ly:music? ly:music? ly:music? list? ly:music?) "Transpose music diatonicly by from pitch-note1 to pitch-note2 in scale on tonic-note." (mode-transpose pitch-note1 pitch-note2 tonic-note scale tonic-note scale music)) pattern = \relative c' { c2~ c8 d16 e f g a b c4 g e c } \new Staff { \pattern \diatonicTranspose c d c \major \pattern % I -> II \diatonicTranspose c e c \major \pattern % I -> III } % mixing lydian and mixolydian modes milydian = #`( (0 . 0) (1 . 0) (2 . 0) (3 . ,SHARP) (4 . 0) (5 . 0) (6 . ,FLAT)) melodie = \relative c' { \times 2/3 { cis8 d e } f2 } \new Staff { \time 3/4 \melodie \modeTranspose cis d g \milydian d \lydian \melodie \modeTranspose cis dis' g \milydian e \lydian \melodie } -- John Mandereau <john.mander...@gmail.com> _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user