lilypond-user
[Top][All Lists]
Advanced

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

Re: Transform notes in a variable?


From: Jean Abou Samra
Subject: Re: Transform notes in a variable?
Date: Mon, 2 Aug 2021 11:25:44 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0



Le 02/08/2021 à 02:27, Craig Comstock a écrit :
Related to my other question of note names I am wondering if it is possible to maybe write a mapping function of some sort for pitches?

I know there is transpose like shown here: https://lilypond.org/doc/v2.22/Documentation/web/text-input <https://lilypond.org/doc/v2.22/Documentation/web/text-input>

\transpose f c' \hornNotes

What I need, I think, is a way to write a “riff” let’s say and then transform it differently for different parts/instruments each of which would have a static mapping from the notes in the riff to the notes in the different parts.

\version "2.20.0"
riff = { c' r d' r }
<<
  \new Staff \riff
% \new Staff \transformOne \riff
  \new Staff { e' r g'' r }
% \new Staff \transformTwo \riff
  \new Staff { g'' r a'' r }
>>

Where transformOne would map c’ to say e’ and d’ to g’’. TransormTwo would map c’ to g’’ and d’ to a’’.

I put what I would like to write in comments and what it would look like after.

Writing the mapping function in scheme is fine I suppose. Or maybe some data structure like a map given to a single scheme function?



Like this perhaps? The mapping is defined in chords,
internally converted to an alist. It just seemed easier
to input { <c' d'> } than #`((#{ c' #} . #{ d' #})).

\version "2.22.1"

#(define (chord-as-pitch-pair chord)
   (let ((elements (ly:music-property chord 'elements)))
     (if (eqv? 2 (length elements))
         (cons (ly:music-property (first elements)
                                  'pitch)
               (ly:music-property (second elements)
                                  'pitch))
         (begin
           (ly:music-warning chord "expected two notes")
           (cons #f #f)))))

transformPitches =
#(define-music-function (mapping music) (ly:music? ly:music?)
   (let* ((copy (ly:music-deep-copy music))
          (chords (extract-typed-music mapping 'event-chord))
          (alist (map chord-as-pitch-pair chords)))
     (for-some-music
       (lambda (m)
         (let ((pitch (ly:music-property m 'pitch #f)))
           (if pitch
               (let ((new-pitch (assoc-ref alist pitch)))
                 (set! (ly:music-property m 'pitch)
                       (or new-pitch pitch))))
           #f))
       copy)
     copy))


mappingOne = { <c' e'> <d' g''> }
mappingTwo = { <c' g''> <d' a''> }

music = { c' d' e' }

\transformPitches \mappingOne \music
\transformPitches \mappingTwo \music



Since you seem interested by the Scheme level,
here are resources to learn how to program LilyPond:

https://lilypond.org/doc/v2.23/Documentation/extending/index.html
https://extending-lilypond.readthedocs.io/en/latest/

Best,
Jean




reply via email to

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