lilypond-user-fr
[Top][All Lists]
Advanced

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

Re: scheme : type d' arguments pour \transpose


From: Gilles THIBAULT
Subject: Re: scheme : type d' arguments pour \transpose
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.

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







reply via email to

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