lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Diatonic/modal transposition function (John Mandereau)


From: Nick Payne
Subject: RE: Diatonic/modal transposition function (John Mandereau)
Date: Tue, 30 Dec 2008 12:01:37 +1100

When I run your example (2.12 Windows) it produces the expected output but I 
also get in the log:

Parsing...D:/Documents/Lilypond/examples/transpose.ly:18:5: In procedure - in 
expression (- (ly:pitch-alteration normalized-pitch) (ly:assoc-get notename 
scale ...)):
D:/Documents/Lilypond/examples/transpose.ly:18:5: Wrong type: (unquote SHARP)

Nick

> -----Original Message-----
> Behalf Of John Mandereau
> Sent: Tuesday, 30 December 2008 07:55
> To: Stefan Thomas
> Cc: lilypond-user
> Subject: Re: Diatonic/modal transposition function (John Mandereau)
> 
> 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 <address@hidden>
> 
> 
> 
> _______________________________________________
> lilypond-user mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/lilypond-user
> No virus found in this incoming message.
> Checked by AVG - http://www.avg.com
> Version: 8.0.176 / Virus Database: 270.10.1/1868 - Release Date:
> 29/12/2008 10:48





reply via email to

[Prev in Thread] Current Thread [Next in Thread]