[Top][All Lists]
[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