Subject: extraire une portion de musique

From: "Gilles THIBAULT" <[email-masked]>
Date: Mon, 2 Jun 2008 13:28:28 +0200

Cela fait longtemps que je voulais une fonction pour extraire d'une manière
simple, une portion de musique déjà entrée mais sans modifier celle-ci.

C'est ce que propose la fonction extractMusic (dans le fichier
extractMusic.ly ci-joint) :

Elle prend 3 arguments :
    - la musique à partir de laquelle se fait l'extraction
    - Combien de temps avant le début de l'extraction
    - Combien de temps dure l'extraction

Par exemple

\extractMusic \music s1*2 s1*4

copie \music de la mesure 3 pendant 4 mesures. (à  4/4  bien-sûr)

Si ça peut être util à d'autre que moi, tant mieux.

Euh, éventuellement je serai content si vous me dites s'il y a des bugs ...

Gilles

---

From: "Valentin Villenave" <[email-masked]>
Date: Tue, 3 Jun 2008 11:51:00 +0200

> simple, une portion de musique déjà entrée mais sans modifier celle-ci.

Tout ça m'a l'air très intéressant ; concrètement ça permet quelles
possibilités dans une partition "en vrai" ? Un genre de \addQuote
amélioré ?

Sinon, ça pourrait valoir le coup de l'envoyer sur le LSR (si ça ne
marche pas, envoie-le moi et je le mettrai dans input/new).

Valentin

---

From: "Gilles THIBAULT" <[email-masked]>
Date: Tue, 3 Jun 2008 15:18:29 +0200

> concrètement ça permet quelles
>possibilités dans une partition "en vrai" ?
>Un genre de \addQuote amélioré ?

Le \addQuote a 3 défauts immédiats
    - non transposable ( \transpose c d \quoteDuring  #"clarinet" { s2. } 
par exemple n'a aucun effet)
    - Il filtre les événements : les articulations et les nuances ne sont 
pas pris en compte par défaut  ( voir \set Staff.quotedEventTypes )
    - On ne peut pas spécifier à partir d' où on veut extraire la musique. 
(Il n'y qu'un paramètre de durée)
En fait, il n'a pas été fait pour ça.

Il y a aussi la méthode d'extraire manuellement la portion désirée.
par exemple, si on a
music = {c d e f g f e d c}
On peut (et c'est assez facile avec JEdit et LilyPondTools) découper cette 
musique en plusieurs morceaux
musicA = {c d e }
musicB = { f  g f}
musicC = {e d c }
Outre le fait que parfois en mode \relative ça nous fiche un peu le bazard 
dans les octaves, ce procédé devient très lourd quand par exemple on fait 
plusieurs arrangements d'une musique donnée.
J'ai dû plusieurs fois adapter le canon de Pachelbel pour des mariages (ok, 
c'est pas trop original mais c'est les mariés qui demandaient...),et ceci 
pour des instruments à chaque fois différents ... et aussi de différents 
niveaux (ben oui il, y a des triples-croches), et je me retrouve maintenant 
avec le canon de la forme
canon = { \canonA \canonB \canonC \canonD \canonE \canonF etc ... } et avec 
à l'intérieur de chaque partie encore des sous-parties voir des sous-sous 
parties de la forme
canonX = {  \canonXA \canonXB} ou canonYB = {  \canonYBA \canonYBB }
Inutile de vous dire que c'est complètement illisible !!!

Il y aurait enfin une methode en utilisant
     \set Score.skipTypesetting = ##t et \set Score.skipTypesetting = ##f
mais elle s'applique à tout le score entier ( oui, j'ai essayé de mettre 
\set Staff.skipTypesetting = ##t mais sans succès)
... d'où la fonction que j'ai essayée de faire mais je ne suis pas sûr que 
sur que sur le plan de la programmation il n'y est pas des lourdeurs....

>marche pas, envoie-le moi et je le mettrai dans input/new).
Je vais essayé de le mettre sur le LSR, .... mais avec le minimum de 
commentaires (j'ai toujours du mal en anglais)

Valentin

---

From: "Gilles THIBAULT" <[email-masked]>
Date: Tue, 3 Jun 2008 15:56:28 +0200

> sur que sur le plan de la programmation il n'y est pas des lourdeurs....
Euh sur le plan de l'orthographe, c'est sûr il y en a, des lourdeurs !!!

Valentin, j'ai entré le snippet dans le LSR sous le doux nom de
"Extracting a portion of music without modifying it"
le id = 474
Mais je n'ai pas pu voir ce que ça donnait : aucun snippet ne s'affiche.
Il y a effectivement des pbs avec le LSR.

Gilles

---

From: "Valentin Villenave" <[email-masked]>
Date: Tue, 3 Jun 2008 17:55:15 +0200

> Il y a effectivement des pbs avec le LSR.

Oui, en gros dès que deux personnes s'en servent en même temps le
serveur saute :-)

http://lsr.dsi.unimi.it/LSR/Item?id=474

ça rend super bien !

Le sens implicite de ma question était : peut-on se servir de ton code
pour améliorer la fonction \addQuote existante ?

Valentin

---

From: "Gilles THIBAULT" <[email-masked]>
Date: Tue, 3 Jun 2008 21:46:03 +0200

>pour améliorer la fonction \addQuote existante ?
Dans le fichier music-functions-init.ly, les fonctions \addQuote et
\quoteDuring ne font qu'appeller des fonctions définis en C
(add-quotable et   make-music 'QuoteMusic ...). On ne peut pas, me semble
t-il, agir avec du scheme sur ces fonctions.
La réponse à ta question serait donc non, mais bon, là ça dépasse un peu mes
compétences.

Gilles

NB
J'ai eu la chance de pouvoir voir le snippet une fois. Je devais être le 
seul connecté au serveur.
J'ai réessayé 2 minutes plus tard, ... plus rien  :-)

---

From: Nicolas Sceaux <[email-masked]>
Date: Wed, 4 Jun 2008 21:23:24 +0200

> Euh, éventuellement je serai content si vous me dites s'il y a des  

J'ai souvent eu envie d'une fonction de ce genre, sans me donner la
peine de l'écrire, mais je pense que c'est très utile, dès lors
qu'on écrit conducteur et matériel d'orchestre.

Une première remarque générale : le code est très mal présenté, ce
qui le rend pénible à lire. Les règles d'indentation des idiomes de
lisp sont très simples, si tu utilises un éditeur valable il saura
le faire tout seul. Mis à part l'indentation, il existe quelques
règles d'usage à respecter, par exemple on ne laisse pas de parenthèse
seule sur une ligne, on utilise des tiret "-" dans les noms de
variables pour séparer les mots.

Voici ton code à peine retouché (j'ai juste transformé la variable
globale en variable "spéciale" au sens Common Lisp du terme)

%%%%%%%%%%% functions %%%%%%%%%%%%%%%%%
#(use-modules (srfi srfi-39))

#(define *current-moment*
    (make-parameter (ly:make-moment 0 1 0 1)))

#(define (clean-music music)
    (music-filter
     (lambda (evt)
       ;; don't keep simultaneous and  sequential music with empty  
'elements
       (or (not (eq? 'EventChord (ly:music-property evt 'name)))
           (pair? (ly:music-property evt 'elements))
           (pair? (ly:music-property evt 'articulations))
           (ly:music? (ly:music-property evt 'element))))
     (music-filter
      (lambda (evt)
        ;; don't keep articulations or slurs with no notes assigned to
        (let ((elts (ly:music-property evt 'elements)))
          (not (and (eq? (ly:music-property evt 'name) 'EventChord)
                    (pair? elts)
                    (not (memq (ly:music-property (car elts) 'name)
                               (list 'NoteEvent 'RestEvent)))))))
      music)))

#(define (extract-music music from to)
    "description... `from' and `to' as moment"
    (let ((elts (ly:music-property music 'elements))
          (elt  (ly:music-property music 'element))
          (dur (ly:music-property music 'duration))
          (result music))
      (cond ((pair? elts)
             (if (not (eq? (ly:music-property music 'name)  
'SimultaneousMusic))
                 (set! (ly:music-property music 'elements) ;% for  
SequentialMusic
                       (filter (lambda (evt)
                                 (extract-music evt from to))
                               elts)) ; for SimultaneousMusic
                 (let ((max-moment (ly:make-moment 0 1 0 1))
                       (save-moment (*current-moment*))
                       (temp-moment (ly:make-moment 0 1 0 1))
                       (res-music (make-music 'Music)))
                   (set! (ly:music-property music 'elements)
                         (filter (lambda (evt)
                                   (set! res-music (extract-music evt  
from to))
                                  (set! temp-moment (ly:moment-sub  
(*current-moment*) save-moment))
                                  (if (ly:moment<? max-moment temp- 
moment)
                                      (set! max-moment temp-moment)) ; 
% keep the biggest length
                                  (*current-moment* save-moment) ; 
%restore the previous length
                                  res-music)
                                 elts))
                   (*current-moment* (ly:moment-add save-moment max- 
moment)))))
            ((ly:music? elt)
             (extract-music elt from to))
            ((ly:duration? dur)
             (*current-moment* (ly:moment-add (*current-moment*)  
(ly:duration-length dur)))
             (set! result (and (ly:moment<? from (*current-moment*))
                               (not (ly:moment<? to (*current- 
moment*)))))))
      result))

%%%%%%%%%%% the main function %%%%%%%%%%%%%%%%%
extractMusic =
#(define-music-function (parser location music from during)
                         (ly:music? ly:music? ly:music?)
    (let* ((from-length (ly:music-length from))
           (during-length (ly:music-length during))
           (to-length (ly:moment-add during-length from-length)))
      (parameterize ((*current-moment* (ly:make-moment 0 1 0 1)))
        (clean-music (extract-music music from-length to-length)))))

%%%%%%%%%%%%%%%%%%%%%%%%%%% tests %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\version "2.11.42" %% should work with 2.10

music = \relative {
   << { c4 d e f g1 } \\ { c,2 c b1 } >>
   g'4\< a b c\!
   << d1 \\ { b2\> b\! } >>
   d4( c) b-. a-.
   << { g1-> g4-. f-. e( d) } \\ { g4 f e d( e2) r } >>
   c1
}
  			
\score {
   <<
     \new Staff { \music }  %% original
     \new Staff {
       R1*2
       \extractMusic \music s1*2 s1*4
       %% extract the music begining at the 2 measures and during 4  
measures
       R1*2
     }
}

%%%%%%%%%%%%%%%%%%%%%%

---

From: "Gilles THIBAULT" <[email-masked]>
Date: Thu, 5 Jun 2008 10:44:37 +0200

Merci beaucoup Nicolas d'avoir examiné le code !!!

>le faire tout seul.
Arg !!! Je me rend compte de l'erreur que j'ai commise.
Avant d'envoyé le fichier, j'ai ouvert le bloc-note de Windows et copié le 
code que j'avais entré sous LilypondTools, au lieu de copier simplement le 
fichier source .
Je viens d'ouvrir le fichier que j'ai envoyé : il y a effectivement des 
sauts de lignes n'importe-où, et l'indentation est monstrueuse !!!
C'est un peu le même problème avec les gestionnaires de courriers. Si je 
copie dans JEdit, le code que tu as envoyé, Nicolas, ça ne compile pas 
directement, parce-que Outlook a rajouté des sauts de lignes partout.
Par exemple si on met en commentaires
%% Salut tout le monde
vous pouvez vous retrouver avec
%% Salut tout
le monde
 => erreur de compilation à la ligne 2
Mêmes les noms de variables sont parfois coupés au niveau du tiret "-" !
Très pénible ça.

>on utilise des tiret "-" dans les noms de
ok, c'est une habitude qui me sera facile à prendre.

>on ne laisse pas de parenthèse seule sur une ligne,
Ça me demandera là plus de rigueur car ça m'aide beaucoup de mettre une 
parenthèse fermante en dessous d'une parenthèse ouvrante (même si elle est 
seule ...).

>globale en variable "spéciale" au sens Common Lisp du terme)
Super !
Seul petit problème, il m'a été impossible de mettre à jour le LSR.
Le snippet est en lecture seule, même en se logant !!!
Grrrr...

Gilles

---

From: "Valentin Villenave" <[email-masked]>
Date: Thu, 5 Jun 2008 11:35:22 +0200

> Le snippet est en lecture seule, même en se logant !!!

C'est parce que je l'ai approuvé :-)

C'est corrigé. Même si j'ai dû faire sauter la liaison rajoutée
entretemps (je ne sais pas pourquoi, il me faisait un caca nerveux
là-dessus).

Valentin