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: John Mandereau
Subject: Re: Diatonic/modal transposition function (John Mandereau)
Date: Tue, 30 Dec 2008 01:20:00 +0100

Le lundi 29 décembre 2008 à 12:33 +0100, Tao Cumplido a écrit :
> As far as I understand it it works independent from a key signature so
> it doesn't matter if the key is in C or not.
>
> The function says taht you transpose a pattern in a given key for X
> steps, so in your example you transpose a pattern in a-minor one step
> up, and from C one step is D.

Correct.


> Would it be possible to make \diatonicTranspose recognize the key 
> automatically?

Yes, if you know how to retrieve a context property -- I've started
looking at this, this is less trivial than setting context properties
with \set.  It would not be named \diatonicTranspose, though, as this
function must keep a general enough purpose; would \keyDiatonicTranspose
be a sensible name?


> It would save a lot of typing.
> e.g.:
> 
> motive = { c'8 d'8 }
> 
> \new Staff
> {
>    \key c \major
>    \motive
>    \diatonicTranspose #1 \motive
>    \diatonicTranspose #2 \motive
> }


> Maybe the same for modeTranspose, that I only have to specify the mode
> I transpose into.
> This would be especially useful for minor keys because a motive is
> often transposed into minor melodic/harmonic.

Certainly.  The problem is, it's not possible to retrieve the current
key signature as a context property at parsing stage, because contexts
(and thus context properties) are built in the next stage "music
interpretation".  A dirty solution is defining a custom \key command
(e.g. defining \myKey that calls \key and stores the tonic and scale in
global variables), then reusing global variables in a
\keyDiaonicTranspose command; the downside of this is, it would be too
dirty for inclusion in LilyPond.  A clean solution is delaying
evaluation of the diatonic applyContext; here's a sample based on
functions I sent in
http://lists.gnu.org/archive/html/lilypond-user/2008-12/msg00849.html


%%% Begin snippet %%%

#(define (lookup-context-property c symbol)
  (if (ly:context? c)
   (let ((v (ly:context-property c symbol)))
    (if (and v (not (null? v)))
     v
     (lookup-context-property (ly:context-parent c) symbol)))
   #f))


keyDiatonicTranspose =
#(define-music-function
  (parser location pitch-note1 pitch-note2 music)
  (ly:music? ly:music? ly:music?)
  "Transpose music diatonicly by from pitch-note1 to pitch-note2
in scale on tonic-note."
  (make-music 'ApplyContext
   'origin location
   'procedure (
     lambda (c)
     (let ((k (lookup-context-property c 'keySignature)))
      (ly:interpret-music-expression
       (make-music
        'ContextSpeccedMusic
        'property-operations
        '()
        'context-id
        (ly:context-id c)
        'context-type
        (ly:context-name c)
        'element
        (mode-transpose
         pitch-note1 pitch-note2 #{ c #} k #{ c #} k music))
       (ly:context-find c 'Global))))))

minorPattern = {
  c'2 ~  c'8 d'16 ees' f' g' aes' bes' c''4 g' ees' c' 
}

{
  \key c \minor
  \repeat unfold 2 c'1
  \keyDiatonicTranspose c d \minorPattern
}

%%% End snippet %%%

Note the strange spacing I get in the attached PNG; it even segfaults if
I add c'1 after "\keyDiatonicTranspose c d \minorPattern".  I'll reduce
try to reduce the problem down and submit a bug report.


> I guess the best solution would be to have both options available,
> e.g. just to specify the key if necessary and automatic recognition of
> the current key if no key is specified.

It is hardly possible to have optional arguments in music functions,
because AFAIK the parser grabs next input tokens according to the music
function prototype.  Having music functions with variable argument count
would make the parser horribly complex and would create ambiguous cases.



> Another thing I was thinking about is maybe using interval numbers
> instead of steps for the integer, so that #2 tranposes a second up and
> #-4 a fourth down etc.

This would make the arithmetic more complicated (as it already does to
people that learn western music theory :-P), a better solution is to use
interval names as I suggested to Stefan, or even better replace this
integer argument start pitch and final pitch as I proposed.


> It's definitely an awesome function and it makes constructing a piece
> with motives possible.

Yeah, as my flatmate says this function is relevant to composition and
not pure music typesetting, but by design LilyPond already offers input
facilities with this kind of side-effect (or at least it has this
power).

Best,
John

Attachment: abbr-diatonic-transpo.png
Description: PNG image


reply via email to

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