extraire une portion de musique

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

extractMusic.ly (3.4 KB)

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

···

Le 2 juin 2008 13:28, Gilles THIBAULT <****@****> a écrit :

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.

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....

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).

Je vais essayé de le mettre sur le LSR, .... mais avec le minimum de commentaires (j'ai toujours du mal en anglais)

Valentin

... 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....

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

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

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

···

2008/6/3 Gilles THIBAULT <****@****>:

Il y a effectivement des pbs avec le LSR.

Le sens implicite de ma question était : peut-on se servir de ton code
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 :slight_smile:

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 ...

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
     }
   >>
}

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

···

Le 2 juin 08 à 13:28, Gilles THIBAULT a écrit :

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

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.

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
variables pour séparer les mots.

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 ...).

Voici ton code à peine retouché (j'ai juste transformé la variable
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

C'est parce que je l'ai approuvé :slight_smile:

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

···

Le 5 juin 2008 10:44, Gilles THIBAULT <****@****> a écrit :

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 !!!