Subject: Re: scheme : type d' arguments pour \transpose

From: Nicolas Sceaux <[email-masked]>
Date: Sat, 1 Dec 2007 11:55:28 +0100

Le 1 déc. 07 à 00:20, Gilles THIBAULT a écrit :
>
> C'est bien ce que j'avais essayé, mais voilà un extrait de ce que ça  
> donne pour
>       A = \relative { c'2 e g }
>       \displayMusic \transpose c g, \A
> =>
> [...]
>
> Comme on peut le voir, il n'y a aucune trace de g' dans la  
> représentation donnée par \displayMusic. Le listing ci-dessus  
> correspond à la liste déjà développée et transposée = {g'2 b'  
> d''}:   (le  (ly:make-pitch 0 4 0) correspond à g'2). Le  *  
> 'TransposedMusic* sert simplement à indiquer que la musique a été  
> transposée mais aucune trace de combien elle l'a été ...
> Je ne vois pas bien comment je pourrais me servir des renseignements  
> fournis ici.

En effet. Donc dans ce cas, il faut regarder ce que fait le parser  
quand il
rencontre le mot clé \transpose dans le fichier source lily/parser.yy,  
et
essayer de faire pareil.

TRANSPOSE pitch_also_in_chords pitch_also_in_chords music {
	Pitch from = *unsmob_pitch ($2);
	Pitch to = *unsmob_pitch ($3);
	SCM pitch = pitch_interval (from, to).smobbed_copy ();
	$$ = MAKE_SYNTAX ("transpose-music", @$, pitch, $4);

Le jeu de piste n'est pas terminé. Ici ça dit que l'on fabrique un objet
avec "transpose-music", qui est défini dans le fichier source
scm/ly-syntax-constructors.scm :

(define-ly-syntax-simple (transpose-music pitch music)
   (make-music 'TransposedMusic
   	      'element (ly:music-transpose music pitch)))

Donc on va essayer de faire comme le parser, à partir d'une note de  
départ,
une note de destination, et la musique à transposer, de générer la  
transposition
en utilisant ly:music-transpose.

L'équivalent en Scheme de la fonction pitch_interval qu'on voit dans  
parser.yy
est ly:pitch-diff (avec des arguments inversés). On va devoir écrire  
quelque chose
comme :

   (ly:music-transpose music (ly:pitch-diff to from))

où to est le "pitch" de la note passée en argument, et from le pitch  
de la note c.

Pour récupérer cette propriété pitch, il faut repérer où elle se loge  
dans
l'expression musicale représentant une note :

   \displayMusic g,
==>
   (make-music 'EventChord
     'elements (list (make-music 'NoteEvent
                       'duration (ly:make-duration 2 0 1 1)
                       'pitch    (ly:make-pitch -2 4 0))))

Donc, à partir d'une note, on obtient sa propriété pitch en faisant :

   (ly:music-property (car (ly:music-property note 'elements)) 'pitch)

Le pitch de la note "c" est également obtenu en invoquant  
\displayMusic :

   (ly:make-pitch -1 0 0)

On a maintenant tous les éléments permettant de construire à la main une
transposition.

   mytranspose =
   #(define-music-function (parser location to-note music)
                           (ly:music? ly:music?)
      (let ((from (ly:make-pitch -1 0 0))
            (to (ly:music-property (car (ly:music-property to-note  
'elements))
                                   'pitch)))
        (ly:music-transpose music (ly:pitch-diff to from))))

   \displayMusic \mytranspose g, a'
   \displayMusic \transpose c g, a'
==>
   (make-music 'EventChord
     'elements (list (make-music 'NoteEvent
                      'duration (ly:make-duration 2 0 1 1)
                      'pitch (ly:make-pitch 0 2 0))))
   (make-music 'TransposedMusic
    'element (make-music 'EventChord
               'elements (list (make-music 'NoteEvent
                                 'duration (ly:make-duration 2 0 1 1)
                                 'pitch (ly:make-pitch 0 2 0)))))

Pour avoir un résultat identique au \transpose original il ne reste  
qu'à enrober
le résultat de notre fonction dans (make-music 'TransposedMusic etc:

   mytranspose =
   #(define-music-function (parser location to-note music)
                           (ly:music? ly:music?)
      (let ((from (ly:make-pitch -1 0 0))
            (to (ly:music-property (car (ly:music-property to-note  
'elements))
                                   'pitch)))
        (make-music 'TransposedMusic
          'element (ly:music-transpose music (ly:pitch-diff to from)))))

Adapter cette fonction pour faire la fonction accord que tu souhaites  
devrait
être assez facile.

nicolas

---

From: Gilles THIBAULT <[email-masked]>
Date: Sat, 01 Dec 2007 15:28:19 +0100

Ouf, merci beaucoup pour cette réponse conséquente.
Je suis en fait, en train de faire un cahier de gammes pour mes élèves
clarinettistes d'où ma tentative de faire une fonction qui utilise un
canevas fixe et qui est transposé à souhait dans tous les tons.
Au delà de l'aide ponctuelle apportée ici, on peut aussi recueillir beaucoup 
de
renseignements sur la méthodologie à adopter pour écrire des
fonctions schemes. En particulier, j'avais bien tenté de trouver dans les
fichiers *.scm et *.ly du repertoire usr\share\lilypond\current,
l'implémentation de \transpose, mais sans succès.
Jamais je n'avais eu l'idée de rechercher dans les fichiers sources !
Bref, je vais étudier tout ça et je transmettrai ici le résultat. (je pense
que d'autres profs pourront éventuellement être interessés pour adapter ce
cahier pour leur propre instrument).

Un cahier de gammes, c'est les élèves qui vont être contents :-)

Gilles

-----------------------------------------------
Nicolas Sceaux a écrit
<
En effet. Donc dans ce cas, il faut regarder ce que fait le parser
quand il
rencontre le mot clé \transpose dans le fichier source lily/parser.yy,
et
essayer de faire pareil.

   \displayMusic g,
==>
   (make-music 'EventChord

   (ly:make-pitch -1 0 0)

   mytranspose =

   mytranspose =

nicolas

---

From: "christophe_cgy.godefroy" <[email-masked]>
Date: Sun, 02 Dec 2007 10:34:07 +0100

Salut à tous,

je suis sur le même travail  avec mes flûtistes. Mais je ne comprend
rien à a ce que vous avez écrit. est-ce que qqn peut faire une
explication de texte ?
Ou ce trouve le schéma de base, ou ce trouve le schéma transposé.
J'espère que l'un d'entre vous aura  le temps de faire un peut de formation.
Merci
Christophe

Gilles THIBAULT a écrit :
> <div class="moz-text-flowed" style="font-family: -moz-fixed">
> Au delà de l'aide ponctuelle apportée ici, on peut aussi recueillir
> beaucoup de
> Pitch from =unsmob_pitch ($2);
> Pitch to =unsmob_pitch ($3);
> SCM pitch =itch_interval (from, to).smobbed_copy ();
> $$ =AKE_SYNTAX ("transpose-music", @$, pitch, $4);
>
> =
>   mytranspose    #(define-music-function (parser location to-note music)
>                           (ly:music? ly:music?)
> =
>   mytranspose    #(define-music-function (parser location to-note music)
>                           (ly:music? ly:music?)
> </div>

-- 
Christophe GODEFROY