Subject: [Fisarmonica] - comment utiliser \musicMap ?

From: Daniel Cartron <[email-masked]>
Date: Wed, 05 Jun 2013 10:44:37 +0200

Ce coup-ci on arrive aux choses sérieuses, maintenant que toutes mes autres 
fonctions sont au point, il faut que je les applique à la musique.

Les notes sont notées comme cet exemple :

(make-music
  'NoteEvent
  'articulations
  (list (make-music
          'StringNumberEvent
          'string-number
          1)
        (make-music
          'FingeringEvent
          'digit
          1)
        (make-music
          'StrokeFingerEvent
          'digit
          6))
  'duration
  (ly:make-duration 2 0 1)
  'pitch
  (ly:make-pitch -1 6 0))

Je veux utiliser le pitch, la valeur de StringNumberEvent et de 
StrokeFingerEvent (mais surtout pas FingeringEvent) pour générer un markup que 
j'ajoute à la note.

J'ai fouillé les snippets, mais pas trouvé qq chose que je pourrais adapter. 
Qui pourrait me donner une ou des pistes ?

Une fois que celle-ci sera au point on ne sera plus loin de la ligne d'arrivée 
:-)

Merci d'avance.

-- 
Cordialement, Daniel Cartron
« Le chien est l'animal le plus vigilant; pourtant il dort toute la journée. »
Georg Christoph Lichtenberg

---

From: Daniel Cartron <[email-masked]>
Date: Wed, 05 Jun 2013 12:29:17 +0200

Le mercredi 5 juin 2013 10:44:37 Daniel Cartron a écrit :
> J'ai fouillé les snippets, mais pas trouvé qq chose que je pourrais
> adapter.  Qui pourrait me donner une ou des pistes ?

C'est pas dans les snippets, mais ça a l'air de ressembler à ce que je cherche 
à faire :
http://www.lilypond.org/doc/v2.16/Documentation/extending/adding-articulation-to-notes-_0028example_0029

-- 
Cordialement, Daniel Cartron
« Les maîtres d'école sont des jardiniers en intelligences humaines. »
Victor Hugo - Faits et croyances

---

From: [email-masked]
Date: Wed, 5 Jun 2013 19:54:41 +0200 (CEST)

----- Mail original -----

Je veux utiliser le pitch, la valeur de StringNumberEvent et de 
StrokeFingerEvent
----------------------------

Tu récupères le pitch de ta note ( qui est par exemple dans une variable music) par :
(ly:music-property music 'pitch)  ; <- un pitch
Pour récupérer le 'string-number et le 'digit, tu peux utiliser un music-map à l'intérieur de la note :
tu peux savoir si un évenement evt est un 'StringNumberEvent ou un 'StrokeFingerEvent avec sa propriété name :
 (if (eq? (ly:music-property evt 'name) 'StringNumberEvent) ...) par exemple, et après tu peux enfin récupérer le 'string-number ou le 'digit
  (ly:music-property evt 'string-number)  ; <- un nombre

- Gilles

---

From: Daniel Cartron <[email-masked]>
Date: Wed, 05 Jun 2013 21:14:10 +0200

Le mercredi 5 juin 2013 19:54:41 [email-masked] a écrit :
> Tu récupères le pitch de ta note ( qui est par exemple dans une variable
> music) par : (ly:music-property music 'pitch)  ; <- un pitch
> Pour récupérer le 'string-number et le 'digit, tu peux utiliser un music-map
> à l'intérieur de la note : tu peux savoir si un évenement evt est un
> 'StringNumberEvent ou un 'StrokeFingerEvent avec sa propriété name : (if
> (eq? (ly:music-property evt 'name) 'StringNumberEvent) ...) par exemple, et
> après tu peux enfin récupérer le 'string-number ou le 'digit

Bonsoir Gilles, 

merci pour ces infos, je vais me pencher là-dessus demain matin.

-- 
Cordialement, Daniel Cartron
« Si vous fermez la porte à toutes les erreurs, la vérité restera dehors. »
Rabindranàth Tagore

---

From: Daniel Cartron <[email-masked]>
Date: Thu, 06 Jun 2013 07:08:58 +0200

> (ly:music-property music 'pitch)  ; <- un pitch

Ça va vraiment me renvoyer le pitch complet ? Sous quelle forme, '(x x x) ?

Si oui ça m'arrange, ça simplifiera mon code, mais il faudra que ré-écrive 
tout...

En attendant un simple (display (ly:music-property note-event 'pitch) ) me 
renvoie (), donc rien ne marche...

-- 
Cordialement, Daniel Cartron
« Il y a trois choses que chaque personne doit faire dans sa vie : planter un 
arbre, avoir un enfant et écrire un livre. »
José Marti

---

From: Daniel Cartron <[email-masked]>
Date: Thu, 06 Jun 2013 08:25:13 +0200

> (ly:music-property evt 'string-number)  ; <- un nombre

Je dois oublier qq chose qq part parce que ça ne marche pas, c'est soit vide 
soit unbound, et les lignes pitch-notename etc. que j'ai commentées me 
plantent tout.

Voici le petit bout de code que j'ai écrit pour voir si je récupère bien les 
infos de
(make-music
  'NoteEvent
  'articulations
  (list (make-music
          'StringNumberEvent
          'string-number
          2)
        (make-music
          'FingeringEvent
          'digit
          1)
        (make-music
          'StrokeFingerEvent
          'digit
          5))
  'duration
  (ly:make-duration 2 0 1)
  'pitch
  (ly:make-pitch -1 6 0))

\version "2.16.0"
\language "italiano"

Melody = \relative sol'  {
       \displayMusic si4\2-1\rightHandFinger #5
}

diatoTab = #(define-music-function (parser location note-event)
                                        (ly:music?)
""
(display (ly:music-property note-event 'pitch))
;(display (ly:pitch-notename note-event))
;(display (ly:pitch-octave note-event))
;(display (ly:pitch-alteration note-event))
(if (eq? (ly:music-property note-event 'name) 'StringNumberEvent)
  (display (ly:music-property note-event 'string-number)))
(if (eq? (ly:music-property note-event 'name) 'FingeringEvent)
  (display (ly:music-property note-event 'digit)))
(if (eq? (ly:music-property note-event 'name) 'StrokeFingerEvent)
  (define dir (ly:music-property note-event 'digit)))
note-event)

\score { \new Staff << \diatoTab \Melody >> }

-- 
Cordialement, Daniel Cartron
« Le marchand de sable ne fait pas fortune dans le désert. »
Proverbe bantou - Alexandre Vialatte

---

From: elmamyra <[email-masked]>
Date: Thu, 6 Jun 2013 04:54:31 -0700 (PDT)

Daniel Cartron-2 wrote
> soit unbound, et les lignes pitch-notename etc. que j'ai commentées me

Le fait d'utiliser "\displayMusic" n'envoie pas une liste de musique dans ta
fonction, mais affiche simplement la musique dans la console.
"note-event" contient en fait un "RelativeOctaveMusic". Il te faut donc
récupérer les "NoteEvent". Voici un petit exemple qui permet d'afficher le
pitch et le nom des articulations de chaque note:

\version "2.16.0"
\language "italiano"

#(define (display-info mus-elt)
   (let ((articulations (ly:music-property mus-elt 'articulations)))
     (newline)(display "__________________  ")(newline)
     (display-scheme-music mus-elt)
     (display (ly:music-property mus-elt 'pitch))
     (for-each (lambda (arti)
          (newline)(display (ly:music-property arti 'name))
       )
       articulations
     )
     mus-elt
   )
)

diatoTab = #(define-music-function (parser location mus) (ly:music?)
   (let* ( 
          (relativeMusic (ly:music-property mus 'element) )
          (music-list (ly:music-property relativeMusic 'elements))
         )
     (for-each (lambda (mus-elt)
           (if (eq? (ly:music-property mus-elt 'name) 'NoteEvent)
               (display-info mus-elt)
           )
       )
       music-list
     )
   mus
   )
)

Melody = \relative sol'  {
      si4\2-1\rightHandFinger #5 do\3-2 re\1-4
}

Ensuite je pense que ton but est de pouvoir modifier les notes et les
articulations, pour ce faire tu peux remplacer le for-each par map. Un petit
exemple qui descend le pitch d'un octave et met les  tous les doigtés à 1:

\version "2.16.0"
\language "italiano"

#(define (appli-change mus-elt)
   (if (eq? (ly:music-property mus-elt 'name) 'NoteEvent) 
       (let* (
              (pitch (ly:music-property mus-elt 'pitch))
              (pitch-oct (ly:pitch-octave pitch))
              (pitch-name (ly:pitch-notename pitch))
              (pitch-alt (ly:pitch-alteration pitch))
              (articulations (ly:music-property mus-elt 'articulations))
            )
         
          (ly:music-set-property! mus-elt 'pitch (ly:make-pitch (1-
pitch-oct) pitch-name pitch-alt))
          
          (for-each (lambda (arti)
                (if (eq? (ly:music-property arti 'name) 'StringNumberEvent)
                     (ly:music-set-property! arti 'string-number 1)
                     (ly:music-set-property! arti 'digit 1)
                )
             )
             articulations
          )
         mus-elt
       )
       mus-elt
   )
)

diatoTab = #(define-music-function (parser location mus) (ly:music?)
   (let* ( 
          (relativeMusic (ly:music-property mus 'element) )
          (music-list (ly:music-property relativeMusic 'elements))
         )
     (ly:music-set-property! relativeMusic 'element (map appli-change
music-list))
     
     mus
   )  
)

Melody = \relative sol'  {
      si4\2-1\rightHandFinger #5 do\3-2 re\1-4
}

--
View this message in context: http://lilypond-french-users.1298960.n2.nabble.com/Fisarmonica-comment-utiliser-musicMap-tp7579923p7579935.html
Sent from the LilyPond French Users mailing list archive at Nabble.com.

---

From: Daniel Cartron <[email-masked]>
Date: Thu, 06 Jun 2013 17:45:14 +0200

> fonction, mais affiche simplement la musique dans la console.

Oui je savais ça et je ne pensais pas qu'il était nécessaire de le préciser, 
je mettais juste le display pour montrer ce que je veux obtenir.

> pitch et le nom des articulations de chaque note:

Oui mais non... pour l'instant ce dont j'ai besoin est le contenu et non le 
nom des articulations. Je veux utiliser le chiffre contenu dans 
StringNumberEvent et dans StrokeFingerEvent (la valeur de 'digit pour pêtre 
précis) pour générer mon markup. Or je ne récupère au mieux que des listes 
vides, voire des unbound...

J'ai besoin du 5 de \rightHandFinger #5 et du 3 de \3.

Quant au pitch, j'en ai besoin sous la forme (x x x) et non #<Pitch d'' >, et 
c'est ça aussi qui me pose problème.

> exemple qui descend le pitch d'un octave et met les  tous les doigtés à 1:

Ok ça va probablement me servir pour la suite, j'ai encore une ou deux idées 
derrière la tête... Par exemple remplacer toutes les notes d'une mélodie par 
des \skip (s) et autres joyeusetés de ce genre.

Bon sur ce je vais étudier le code que tu m'as envoyé, notamment le for-each 
dont je me dis depuis un moment qu'il va pas tarder à devenir indispensable.

Merci

-- 
Cordialement, Daniel Cartron
« La religion est une fatiguante solution de paresse. »
E. M. Cioran

---

From: Gilles <[email-masked]>
Date: Fri, 07 Jun 2013 00:07:02 +0200

Le Thu, 06 Jun 2013 07:08:58 +0200, Daniel Cartron <[email-masked]> a  

> Ça va vraiment me renvoyer le pitch complet ? Sous quelle forme, '(x x  

Le pitch complet oui. Si tu  veux acceder aux différents composantes du  
pitch, tu as les fonctions que tu connais
ly:pitch-octave, ly:pitch-notename, ly:pitch-alteration. Si tu préfères  
les avoir sous la forme de liste, tu écris

(let ((p (ly:music-property music 'pitch))
   (list (ly:pitch-octave p) (ly:pitch-notename p) (ly:pitch-alteration p)))
.
Je n'ai aucune idée de comment les pitch sont mis en interne en mémoire,  
et pour une utilisation courante, on n'a pas à le savoir.
Ce que nous renvoie display et display-scheme-music n'est qu'une  
représentation du pitch, en texte, c'est de l'infos simplement (voir  
ci-dessous)

> renvoie (), donc rien ne marche...

manote = a1-3\5-\rightHandFinger #4

#(display "\n***** La note en entier *****\n")
#(display-scheme-music manote)

#(display "\n***** Le  pitch *****\n")
#(display (ly:music-property manote 'pitch))
#(newline)
#(display-scheme-music (ly:music-property manote 'pitch))

#(display "\n***** Les arti *****\n")
#(let ((arti (ly:music-property manote 'articulations)))
    (for-each
      (lambda(evt)
        (let ((name (ly:music-property evt 'name)))
         (cond ((eq? name 'FingeringEvent)
                  (format #t "  FingeringEvent : digit = ~a"
                    (ly:music-property evt 'digit)))
               ((eq? name 'StringNumberEvent)
                  (format #t "\n  StringNumberEvent : string-number = ~a"
                    (ly:music-property evt 'string-number)))
               ((eq? name 'StrokeFingerEvent)
                  (format #t "\n  StrokeFingerEvent : digit = ~a"
                    (ly:music-property evt 'digit)))
           )))
      arti))

\manote

-- 
Gilles

---

From: Daniel Cartron <[email-masked]>
Date: Fri, 07 Jun 2013 07:43:08 +0200

>    (list (ly:pitch-octave p) (ly:pitch-notename p) (ly:pitch-alteration 
p)))

Ce qui me manquait était l'enrobage de tout ça, le (let ((p (ly:music-
property music 'pitch)) en fait. Donc maintenant j'arrive à utiliser ces 
informations comme je veux.

Par contre dans ton code sur les articulations, j'ai vu qu'on peut 
effectivement récupérer les valeurs qui m'intéressent, et je n'ai gardé que:

#(let ((arti (ly:music-property manote 'articulations)))
    (for-each
      (lambda(evt)
        (let ((name (ly:music-property evt 'name)))
         (cond ((eq? name 'StringNumberEvent)
                  (display (ly:music-property evt 'string-number))
                  (newline)
                  )
               ((eq? name 'StrokeFingerEvent)
                  (display (ly:music-property evt 'digit)))
           )))
      arti))

mais si ça m'affiche bien les deux infos je n'arrive pas à injecter ces 
valeurs dans des variables pour les utiliser ailleurs... Si je met un define 
à la place des display ça coince, or je voudrais utiliser ces valeurs pour 
filtrer une liste avec :

#(define (btn-ref btn-lst dir row)
  (if 
    (or (equal? 1 (length btn-lst)) (equal? 0 dir) ) btn-lst
      (if (equal? 1 (length (filter (lambda (lst) (equal? (cadr lst) row) ) 
btn-lst ))) 
        (filter (lambda (lst) (equal? (cadr lst) row) ) btn-lst )
        (filter (lambda (lst) (equal? (car lst) dir) ) btn-lst ))))

row c'est la valeur de string-number (0 1 2 ou 3) et dir c'est digit (0 5 ou 
6), et btn-lst ressemble à ((5 1 2) (6 2 4)) de une à trois sous listes.

Je vois mal comment on pourrait mélanger les deux codes, c'est pourquoi 
j'essaye de passer par des variables, et de plus si dir n'est pas présente 
il faut utiliser la valeur précédente donc mémorisation nécessaire.

Merci pour toutes les lumières que vous me donnez.

-- 
Cordialement, Daniel Cartron
« La laideur a ceci de supérieur à la beauté, c'est qu'elle dure! »
Georg Christoph Lichtenberg

---

From: Daniel Cartron <[email-masked]>
Date: Fri, 07 Jun 2013 09:26:33 +0200

Le vendredi 7 juin 2013 07:43:08 Daniel Cartron a écrit :
> valeurs dans des variables pour les utiliser ailleurs... Si je met un
> define  à la place des display ça coince, or je voudrais utiliser ces
> valeurs pour filtrer une liste avec :

j'ai réussi à faire comme ça, qu'est-c que ça vaut comme code ?
Et surtout est-ce la bonne syntaxe pour que la valeur de dir soit conservée 
tout au long de l'analyse de la musique mais pas celle de row ? Je doute...

#(let ((arti (ly:music-property manote 'articulations)))
    (for-each
      (lambda(evt)
        (let ((name (ly:music-property evt 'name)))
         (cond ((eq? name 'StringNumberEvent)
                  (set! row (ly:music-property evt 'string-number)))
           )
         (cond ((eq? name 'StrokeFingerEvent)
                  (set! dir (ly:music-property evt 'digit)))
           )
         ))
      arti))

-- 
Cordialement, Daniel Cartron
« Il n'y a point de génie sans un grain de folie. »
Aristote - Poétique

---

From: Daniel Cartron <[email-masked]>
Date: Fri, 07 Jun 2013 10:33:08 +0200

> exemple qui descend le pitch d'un octave et met les  tous les doigtés à 1:

Tout ça est très intéressant et très pratique, je vais sans doute ne pas tant 
avoir besoin de trafiquer mes contexte que je ne le craignais et ça pourrait 
notamment éviter mon pb décrit dans Infinity or NaN encountered.

Mais il faudrait que je puisse supprimer les articulations existantes pour les 
remplacer par d'autres : plus de doigtés mais un markup par exemple. Créer un 
markup maintenant j'y arrive assez bien, mm à partir de fonctions complexes, 
mais supprimer des articulations, je vois pas bien...

-- 
Cordialement, Daniel Cartron
« Les voyages, ça sert surtout à embêter les autres une fois qu'on est revenu  
»
Sacha Guitry

---

From: Gilles <[email-masked]>
Date: Fri, 07 Jun 2013 11:56:49 +0200

> tout au long de l'analyse de la musique mais pas celle de row ? Je  

Là difficile de répondre, on a qu'une vue parcellaire de ton code.
>                   (set! dir (ly:music-property evt 'digit)))

Pourquoi tu as a mis 2 section cond ?
C'est pas ça, plutôt que tu veux ? :

-- 
Gilles

---

From: Daniel Cartron <[email-masked]>
Date: Fri, 07 Jun 2013 12:14:04 +0200

> C'est pas ça, plutôt que tu veux ? :

si bien sur mais tous les essais que j'ai fait renvoyaient une erreur, j'avais 
très probablement des parenthèses qui n'allaient pas parce que sinon c'était 
(de mémoire) la mm chose que toi.

Merci, ça me plait mieux moi aussi.

-- 
Cordialement, Daniel Cartron
« L'humanité a l'oreille ainsi faite qu'elle continue à dormir quand le bruit 
retentit et ne se réveille qu'avec l'écho. »
Arthur Schnitzler

---

From: Daniel Cartron <[email-masked]>
Date: Sat, 08 Jun 2013 10:33:11 +0200

Bonjour tout le monde,

J'ai enfin réussi à écrire ma fonction, et elle marche !

Sauf que j'ai encore un petit défaut... 

Le début de la fonction me fabrique une liste btn-lst du genre ((5 1 2)) 
mais ça peut aussi être ((5 1 2) (6 2 3)) voire ((5 1 2) (6 2 3) (5 3 4)).

À partir de ça je fabrique un markup que j'ajoute à la note. Le markup est 
fabriqué à partir des sous listes et ajouté à la note avec le code ci-
dessous.

Mon problème est que pour l'instant seule la première sous-liste est 
traitée, alors que j'aimerais les traiter toutes et ajouter de 1 à 3 markups 
à la note. J'ai essayé de déplacer les (cond...) (nécessités par le fait 
qu'il y a deux systèmes de tablature qui ne s'écrivent pas du tout pareil) 
dans la dernière partie pour faire un for-each mais erreurs à chaque fois. 

Donc je fais encore une fois appel à votre aide pour déméler tout ça. 

Je me doute qu'une fois que ce sera dans une boucle for-each, les caddar et 
autres changeront mais ce n'est pas ça qui me pose problème, c'est les 
imbrications... Dont notamment le (cons...) qui ajoute les markup aux 
articulations.

Voici la partie du code que j'aimerais modifier comme indiqué ci-dessus :

; builds the button number depending on the tablature system
  (cond
    ( (and (equal? (assoc-ref syst "name") "Cadb") (equal? (cadr btn-lst) 2) 
)
      (set! btn (string-append (caddr btn-lst) "'")) )
    ( (and (equal? (assoc-ref syst "name") "Cadb") (equal? (cadr btn-lst) 3) 
)
      (set! btn (string-append (caddr btn-lst) "''")) )
    ( else
      (set! btn (caddar btn-lst)) )
  )
; builds the markups depending on the tablature system
  ( cond
    ((equal?(cadr(assoc-ref syst (list (caar btn-lst) (cadar btn-lst)))) 
"mkso") 
     (set! mkup (markup #:line (#:with-color pshcolor (#:simple btn)))) )
    ((equal?(cadr(assoc-ref syst (list (caar btn-lst) (cadar btn-lst)))) 
"mksi") 
     (set! mkup (markup #:line (#:with-color pllcolor (#:simple btn)))) )
    ((equal?(cadr(assoc-ref syst (list (caar btn-lst) (cadar btn-lst)))) 
"mkui") 
     (set! mkup (markup #:line (#:with-color pllcolor (#:underline btn)))) )
    ((equal?(cadr(assoc-ref syst (list (caar btn-lst) (cadar btn-lst)))) 
"mkco") 
     (set! mkup (markup #:line (#:with-color pshcolor (#:column (#:line 
(#:simple btn) #:null))))) )
    ((equal?(cadr(assoc-ref syst (list (caar btn-lst) (cadar btn-lst)))) 
"mkci") 
     (set! mkup (markup #:line (#:with-color pllcolor (#:column (#:line 
(#:underline btn) #:null))))))
 )

  ; add the markup to the note
  (set! (ly:music-property evt 'articulations)
  
  (cons (make-music 'TextScriptEvent 
    'direction (car(assoc-ref syst (list (caar btn-lst) (cadar btn-lst))))
      'text mkup
      )
    (ly:music-property evt 'articulations) )
  )
  evt)

Merci d'avance.

-- 
Cordialement, Daniel Cartron
« Tout le monde savait que c'était impossible. Il est venu un imbécile qui 
ne le savait pas et qui l'a fait. »
Marcel Pagnol

---

From: Daniel Cartron <[email-masked]>
Date: Mon, 10 Jun 2013 10:11:17 +0200

> imbrications... Dont notamment le (cons...) qui ajoute les markup aux

En fait il suffisait que je mette l'intégralité du code que j'ai envoyé dans 
la boucle, et enlever le a final des caddar et cie.

Donc ça y est ça marche, mais sur une unique note, pas sur la totalité de la 
mélodie. j'ai cru comprendre que c'est \musicMap qui permet ça mais impossible 
de trouver une doc explicite ou des exemples sur le sujet. La seule chose que 
google me ramène c'est "Ajout d’articulation à des notes" or on n'y trouve pas 
ce terme, ou A.18 Fonctions musicales prédéfinies mais c'est on ne peut plus 
spartiate, ou alors mes propres questions sur cette liste...

Donc je repose ma question en précisant que ma fonction est plus complexe que 
ajouteAccent de la page "Ajout d’articulation à des notes" mais c'est le mm 
principe.

ajouteAccent = #(define-music-function (parser location note-event)
                                        (ly:music?)
  "Ajoute un accent (ArticulationEvent) aux articulations de `note-event',
  qui est censé être une expression NoteEvent."
  (set! (ly:music-property note-event 'articulations)
        (cons (make-music 'ArticulationEvent
                'articulation-type "accent")
              (ly:music-property note-event 'articulations)))
  note-event)

Ce que j'aimerais savoir c'est comment on peut utiliser cette fonction sur une 
mélodie compléte, à savoir pouvoir écrire \ajouteAccent \Melody et ça fait le 
boulot sur chacune des notes de Melody.

Merci d'avance.

-- 
Cordialement, Daniel Cartron
« Tu es responsable de ce que tu as apprivoisé. »
Antoine de Saint-Exupéry - Le petit prince