Subject: Du nouveau au sujet de ly2xml?

From: Bernard Meylan <[email-masked]>
Date: Sun, 16 May 2021 06:03:27 -0700 (MST)

Bonjour à toutes/tous!

Dans le but d'aider un collègue, j'aimerais savoir s'il y a eu des
avancées/nouveautés du côté de l'export du code lily en xml/musicxml. On
peut le faire avec Frescobaldi mais seulement si la partition est simple,
pas trop longue et ne comportant pas trop de chausse-trappes… Or, la
partition de ce collègue est complexe (4 chœurs plus basse chiffrée), longue
(plus de 200 mesures) et comporte de nombreux changements de métrique.
L'éditeur qui accepterait d'éditer ce gros cailloux ne bosse que sous
Sibelius… 
Donc, je cherche à lui donner un coup de main et voir si, à la place de tout
ressaisir, il n'y aurait pas moyen de translater cette pièce. 

-----
Cordialement

Bernard
--
Sent from: http://lilypond-french-users.1298960.n2.nabble.com/

---

From: Jacques Menu <[email-masked]>
Date: Sun, 16 May 2021 16:31:14 +0200

Salut Bernard,

En MusicXML, une partition est essentiellement une suite de <part />, chacune formée d’une suite de <measure />. Les différentes portées et voix sont simplément précisées pour chaque note si nécessaire (i.e. leur numéro n’est pas 1).

Si tu répartis toutes les voix, même longues, écrites en Lily sur un fichier dédié chacune, est-ce que ça se passe bien? Si oui, il n’y aurait plus qu’à fusionner les différents fichiers MusicXML exportés de Frescobaldi, ce qui est un problème qu’on pourrait attaquer.

Peux-tu faire un essai?

JM

> Le 16 mai 2021 à 15:03, Bernard Meylan <[email-masked]> a écrit :
> 
> Bonjour à toutes/tous!
>

---

From: Jean Abou Samra <[email-masked]>
Date: Sun, 16 May 2021 17:03:47 +0200

>> ressaisir, il n'y aurait pas moyen de translater cette pièce.

Bonjour,

Mon premier réflexe serait d'enlever la basse chiffrée,
car je doute que Frescobaldi sache la convertir. Si cela
ne fonctionne pas, faire comme propose Jacques : voix par
voix, et fusionner à la fin, en transcrivant manuellement
ce qui n'a pas pu être converti.

Je n'ai pas vu d'améliorations apportées à python-ly au
niveau de l'export en MusicXML récemment. L'auteur principal,
Wilbert Berendsen, s'est plutôt concentré sur une réécriture
de l'analyse syntaxique qui permettrait d'éditer des fichiers
de taille plus importante.

À mon avis, un outil qui ne soit pas seulement une solution
de secours devrait être intégré à LilyPond via des traducteurs
(je parle de ceux que l'on ajoute avec \consists, pas de Jean-Charles).
Il y a eu plusieurs discussions en ce sens sur la liste de
développement, mais jamais rien de concret n'en est sorti
malheureusement, faute de personnes à la fois intéressées,
compétentes dans le domaine, et ayant la possibilité matérielle
d'y travailler.

Cordialement,
Jean

---

From: Marc <[email-masked]>
Date: Sun, 16 May 2021 17:37:04 +0200

2 pistes

Pour réduire le travail, faire un fichier midi et l'importer sous Sibelius.

Sinon essayer un import sous MuseScore  suivi d'un export xml de toutes 
façons, le chiffrage est perdu et il faudra vérifier la place des paroles.

Bon courage

Marc Lanoiselée

---

From: Jacques Menu <[email-masked]>
Date: Sun, 16 May 2021 17:39:13 +0200

Fusionner à la main serait sans doute fastidieux : je pensais à un xmlmerge, que je pourrais dériver de xml2xml. 
Ce dernier est pensé pour appliquer des modifications au contenu musical d’un texte MusicXML et de produire une nouvelle description MusicXML en fonction des options choisies :

jacquesmenu@macmini: ~/musicformats-git-dev/files/musicxml > xml2xml -a
What xml2xml does:

    This multi-pass translator basically performs 6 passes:
        Pass 1:  reads the contents of MusicXMLFile or stdin ('-')
                 and converts it to a MusicXML tree;
        Pass 2a: converts that MusicXML treeinto
                 a Music Score Representation (MSR) skeleton;
        Pass 2b: populates the MSR skeleton from the MusicXML tree
                 to get a full MSR;
        Pass 3:  converts the MSR into a second MSR, to apply options;
        Pass 4:  converts the second MSR into a second MusicXML tree;
        Pass 5:  converts the second MusicXML tree to MusicXML code
                 and writes it to standard output.

    Other passes are performed according to the options, such as
    printing views of the internal data or printing a summary of the score.

    The activity log and warning/error messages go to standard error.

C’est en fusionnant les descriptions internes MSR obtenues pour différents fichiers que je pourrais en créer une pour le tout, qu’il n’y aurait plus qu’à convertir en MusicXML avec les passes 4 et 5 figurant ci-dessus, qui sont disponibles.

Voici un exemple d’option de xml2xml :

jacquesmenu@macmini: ~/musicformats-git-dev/files/musicxml > xml2xml -apropos msr-rename-part
--- Help for atom "msr-rename-part" in subgroup "Parts"
    -mrp, -msr-rename-part PART_RENAME_SPEC
          Rename part ORIGINAL_NAME to NEW_NAME, for example after displaying
          the names in the score or a summary of the latter in a first run with options
          '-dmnames, -display-msr-names' or 'dmsum, -display-msr-summary'.
          PART_RENAME_SPEC can be:
          'ORIGINAL_NAME = NEW_NAME'
          or
          "ORIGINAL_NAME = NEW_NAME"
          The single or double quotes are used to allow spaces in the names
          and around the '=' sign, otherwise they can be dispensed with.
          Using double quotes allows for shell variables substitutions, as in:
          DESSUS="Cor anglais"
          xml2xml -msr-rename-part "P1 = ${DESSUS}" .
          There can be several occurrences of this option.

Un point délicat dans l’export par Frescobaldi est peut-être les voix implicites de LilyPond, comme dans :
 	<< c1 \\ { b2 a2 } >>

Jean, je te laisse préciser ce que tu m’as dit récemment quant à l'obtention, à partir de la description en Scheme de la musique dans Lily, des informations nécessaires pour la création de code MusicXML ou autre.

JM

---

From: gerardk <[email-masked]>
Date: Sun, 16 May 2021 09:40:32 -0700 (MST)

Est-ce que l'éditeur accepterait un fichier PDF pour l'imprimer ? Générer un
PDF à partir de Frescobaldi ne pose pas de problème et un éditeur devrait
pouvoir reprendre un PDF dans un logiciel de mise en page (genre InDesign)
pour compléter la partition si besoin.

---

From: Jean Abou Samra <[email-masked]>
Date: Sun, 16 May 2021 20:35:00 +0200

Le 16/05/2021 à 17:39, Jacques Menu a écrit :

> Jean, je te laisse préciser ce que tu m’as dit récemment quant à 
> l'obtention, à partir de la description en Scheme de la musique dans 
> Lily, des informations nécessaires pour la création de code MusicXML 
> ou autre.

En simplifiant un peu, on peut considérer que la compilation d'un 
fichier dans la sortie graphique (pas MIDI) se fait en trois phases 
principales :

1. Analyse syntaxique et traitement de l'entrée par des fonctions musicales.

2. Traduction par des graveurs en un ensemble d'objets graphiques.

3. Calcul des sauts de ligne, positionnement et dessin des objets.

Jusqu'ici, les tentatives (restées modestes) d'implémentation d'un 
export MusicXML sont restées cantonnées à la phase 1.

C'est une approche fort limitée. En effet, les objets musicaux sont très 
proches de la saisie de l'utilisateur, et ne contiennent aucune 
information ni sur la temporalité de la musique, ni sur le 
positionnement, par exemple la direction des hampes, ou bien la 
configuration des barres de ligature.

Il faudrait donc commencer dans la phase 2, en introduisant :

- un nouveau type de définitions de sortie, en complément de \layout { } 
et \midi { }, nommé par exemple \xml { },

- un nouveau genre de traducteurs, en plus des graveurs (engravers) et 
des interprètes (performers), appelé, disons, exportateur (exporter).

Les exportateurs devraient être liés aux graveurs, car ils s'intéressent 
au placement. Les graveurs sont construits selon un système où chaque 
étape temporelle comporte deux phases :

- l'écoute de la musique, et la création d'objets graphiques en réaction,

- l'observation des objets créés par d'autres graveurs.

Il faudrait que les exportateurs s'insèrent dans ce système, en créant, 
pour leur part, un type différent d'objets (nodes ?), servant 
spécifiquement à la sortie MusicXML. De plus, ils devront observer à la 
fois les grobs et les nodes.

Mais ce n'est pas tout. Le positionnement n'est pas connu lors de la 
traduction, qui doit seulement servir à mettre les nodes en place. Pour 
finir, j'imagine que les nodes pourront être munis de fonctions de 
rappel (callbacks) de la même manière que les grobs, pour accéder aux 
ligatures, sauts de page, etc., et remplir ainsi leur jeu de propriétés 
avant écriture du MusicXML.

Est-ce que c'est le type d'informations que tu attendais ? Je ne suis 
pas sûr d'avoir bien compris la question…

En tous cas, inutile de dire que cela représente un travail faisable, 
mais important.

Amicalement,
Jean

PS : En pièce jointe, un graveur simple qui montre comment on peut 
accéder à l'information musicale. Il rend compte rudimentairement du 
flux musical sur la console.

---

From: Jacques Menu <[email-masked]>
Date: Mon, 17 May 2021 00:00:21 +0200

Bonsoir Jean,

Désolé pour les lecteurs qui vont trouver ce message rébarbatif…

Comme je te l’avais dit, j’avais demandé, lors de ma présentation à Salzburg, s’il existait dans le flot de tâches exécutées par LilyPond un endroit où se raccrocher pour aborder ça. Personne ne semblait avoir de réponse à ce moment-là. Je suis heureux que tu nous en apportes, tu as bien compris ce que je demandais.

Quitte à faire du gros boulot, il serait effectivement de loin plus porteur de travailler à un export de Lily vers d’autres représentations des partitions que de créer un outil pour fusionner des fichiers MusicXML.

Comme je ne connais pas, tant s’en faut, le détail de ce que fait Lily, et que ça serait contre-productif que je m’y investisse, je pourrais colloborer avec quelqu’un qui aurait cette connaissance. Tu me sembles donc être le volontaire tout désigné!

L’approche consisterait à créer une description LPSR (LilyPond Score Representation) de la partition par un exporteur. Il faudrait voir ce qui devrait être écrit en Scheme et en C++ respectivement. 

C’est ce LPSR que xml2ly construit pour ensuite produire le code LilyPond à partir de ça, voir l’architecture à la page 2 de https://github.com/jacques-menu/musicformats/blob/dev/doc/musicformatsArchitecture/musicformatsArchitecture.pdf <https://github.com/jacques-menu/musicformats/blob/dev/doc/musicformatsArchitecture/musicformatsArchitecture.pdf> .

Pour illustrer comment la partition est décrite dans LPSR, je joins l’exemple d’une partition minimale, mais avec quand même différents aspects présents :

Il y a le source MusicXML et le log de sa conversion en LilyPond par la commande :

	xml2ly -auto-output-file-name  basic/MinimalScore.xml -display-lpsr

Les numéros de lignes sont ceux des éléments dans le fichier MusicXML.

On voit dans le log les deux composants de la description LPSR : le premier est la musique (composant MSR), et le second tout à la fin ce qu’il faut en plus pour structurer la partition comme on le fait en LilyPond :

  Book blocks
  
    BookBlock
    
      BookBlockElements
        ScoreBlock
        
          ParallelMusicBLock, 1 part group
            
            PartGroupBlock for partGroup "PartGroup_1 ('0', partGroupName "Implicit")", partGroupSymbolNone, 1 element
            
              PartBlock for part Part_POne (partID "P1"), 1 element
                partName                     = ""
                partAbbreviation             = ""
                partBlockInstrumentName      = ""
                partBlockShortInstrumentName = ""
                
                StaffBlock for staff "Part_POne_Staff_One" (staffRegular), 1 element
                  (StaffBlockInstrumentName       = "")
                  (StaffBlockShortInstrumentName  = "")
                  
                  UseVoiceCommand "Part_POne_Staff_One_Voice_One", 0 stanza
          
          Layout
            layoutGlobalStaffSize : 20
          
          MidiTempo
            midiTempoDuration  = 4
            midiTempoPerSecond = 90

Je suis en train de documenter progressivement comment tout cela est fait.

Donc pour résumer : si on peut créer cette description LPSR depuis LilyPond par un exporteur, on a directement la conversion en MusicXML, Guido et braille. MIDI n’est pas encore disponible, mais j’ai déjà avancé dans cette direction.
Les nodes que tu proposes correspondraient à des msrElement de mon côté.

Par exemple, pour créer dans le composant MSR de la description LPSR une note avec un pp, comme :

	a'8 \pp

on écrirait le code C++ ci-dessous, ou son équivalent en Scheme :

      // create the note
      S_msrNote
        note1 =
          msrNote::createRegularNote (
            __LINE__,
            measure1number,
            msrQuarterTonesPitchKind::kQTP_A_Natural,
            msrOctaveKind::kOctave4,
            rational (1, 8), // soundingWholeNotes
            rational (1, 8), // displayWholeNotes
            0);              // dotsNumber

      // append the dynamics to the note
      note1->
        appendDynamicsToNote (
          msrDynamics::create (
            __LINE__,
            msrDynamicsKind::kDynamicsPP,
            msrPlacementKind::kPlacementBelow));

N’hésite pas si tu as des questions!

JM

> En simplifiant un peu, on peut considérer que la compilation d'un fichier dans la sortie graphique (pas MIDI) se fait en trois phases principales :
> 
> Jusqu'ici, les tentatives (restées modestes) d'implémentation d'un export MusicXML sont restées cantonnées à la phase 1.
> 
> C'est une approche fort limitée. En effet, les objets musicaux sont très proches de la saisie de l'utilisateur, et ne contiennent aucune information ni sur la temporalité de la musique, ni sur le positionnement, par exemple la direction des hampes, ou bien la configuration des barres de ligature.
> 
> - un nouveau type de définitions de sortie, en complément de \layout { } et \midi { }, nommé par exemple \xml { },
> 
> - un nouveau genre de traducteurs, en plus des graveurs (engravers) et des interprètes (performers), appelé, disons, exportateur (exporter).
> 
> Les exportateurs devraient être liés aux graveurs, car ils s'intéressent au placement. Les graveurs sont construits selon un système où chaque étape temporelle comporte deux phases :
> 
> Il faudrait que les exportateurs s'insèrent dans ce système, en créant, pour leur part, un type différent d'objets (nodes ?), servant spécifiquement à la sortie MusicXML. De plus, ils devront observer à la fois les grobs et les nodes.
> 
> Mais ce n'est pas tout. Le positionnement n'est pas connu lors de la traduction, qui doit seulement servir à mettre les nodes en place. Pour finir, j'imagine que les nodes pourront être munis de fonctions de rappel (callbacks) de la même manière que les grobs, pour accéder aux ligatures, sauts de page, etc., et remplir ainsi leur jeu de propriétés avant écriture du MusicXML.
> 
> Est-ce que c'est le type d'informations que tu attendais ? Je ne suis pas sûr d'avoir bien compris la question…
> 
> En tous cas, inutile de dire que cela représente un travail faisable, mais important.
> 
> Amicalement,
> Jean
> 
> PS : En pièce jointe, un graveur simple qui montre comment on peut accéder à l'information musicale. Il rend compte rudimentairement du flux musical sur la console.
> 
> <log-parts.ly>

---

From: Bernard Meylan <[email-masked]>
Date: Sun, 16 May 2021 16:04:28 -0700 (MST)

Alors je ne pensais pas que cette demande allait générer un flot de messages,
très intéressants… mais qui pour moi, en ce qui concerne les plus pointus
(désolé Jean et Jacques) sont du domaine de la prise de tête sans aspirine…
Je n'ai absolument pas le tiers du quart de votre compétence en la matière…
mon domaine est celui de la gravure, et ce dont j'ai besoin, ce sont des
outils… Comment ils sont faits, je le sait si peu… trop peu, sans doute.
J'ai isolé la voix du soprano du premier chœur sur une centaine de mesure.
J'ai tenté un export avec Frescobaldi qui a raté, tout comme l'export de la
pièce entière, avec les commentaires qui voici:

Traceback (most recent call last):
File
"/usr/local/lib/python3.8/dist-packages/frescobaldi_app/file_export/__init__.py",
line 66, in exportMusicXML
xml = writer.musicxml()
File "/usr/lib/python3/dist-packages/ly/musicxml/lymus2musxml.py", line 155,
in musicxml
xml_objs.IterateXmlObjs(
File "/usr/lib/python3/dist-packages/ly/musicxml/xml_objs.py", line 78, in
__init__
self.iterate_part(p)
File "/usr/lib/python3/dist-packages/ly/musicxml/xml_objs.py", line 99, in
iterate_part
self.iterate_bar(bar)
File "/usr/lib/python3/dist-packages/ly/musicxml/xml_objs.py", line 106, in
iterate_bar
for obj in bar.obj_list:
AttributeError: 'list' object has no attribute 'obj_list'

Je joins le fichier .ly et le .xml généré par Frescobaldi sans les paroles…
c'est le seul export qui n'ait pas échoué.

Inutile de vous dire que pour moi, même l'hébreu est plus… visuel…
credo_s1.ly
<http://lilypond-french-users.1298960.n2.nabble.com/file/t249946/credo_s1.ly>  
credo_s1.xml
<http://lilypond-french-users.1298960.n2.nabble.com/file/t249946/credo_s1.xml>  

-----
Cordialement

Bernard

---

From: Jacques Menu <[email-masked]>
Date: Mon, 17 May 2021 07:23:57 +0200

Salut Bernard,

Pas de problème, j’ai juste saisi l’occasion de voir avec Jean comment on pourrait aborder l’export depuis LilyPond. 

Les approches basées sur des scripts Python (ou dans d’autres langages) sont condamnées à refaire tout le travail de construction d’une représentation interne des partitions, ce qui est difficile, alors que LilyPond le fait déjà, et très bien en plus. C’est pourquoi je ne crois pas que ça puisse aller très loin, et que la seule solution me semble être de se greffer sur LilyPond lui-même.

Pour ton cas concret, si Frescobaldi ne permet pas d’avancer plus dans la création de fichiers MusicXML, leur fusion ne peut pas s’appliquer, et je ne vois pas de solution de ce côté.

En revanche, en scannant la partition obtenue avec Lily, tu pourrait obtenir du MusicXML pour le tout, voire même un export direct vers Sibelius dans le cas de PhotoScore Ultimate. Tu pourrais ensuite corriger les pertes dûes au scan et finaliser dans Sibelius lui-même. Mais ça aussi prendrait du temps selon le nombre de pages. Il faudrait sans doute voir avec l’éditeur quelle part de ce travail il pourrait faire.

JM

> Le 17 mai 2021 à 01:04, Bernard Meylan <[email-masked]> a écrit :
>

---

From: Jean Abou Samra <[email-masked]>
Date: Mon, 17 May 2021 22:01:04 +0200

Le 17/05/2021 à 00:00, Jacques Menu a écrit :
> Comme je te l’avais dit, j’avais demandé, lors de ma présentation à 
> Salzburg, s’il existait dans le flot de tâches exécutées par LilyPond 
> un endroit où se raccrocher pour aborder ça. Personne ne semblait 
> avoir de réponse à ce moment-là. Je suis heureux que tu nous en 
> apportes, tu as bien compris ce que je demandais.
>
> Quitte à faire du gros boulot, il serait effectivement de loin plus 
> porteur de travailler à un export de Lily vers d’autres 
> représentations des partitions que de créer un outil pour fusionner 
> des fichiers MusicXML.
>
> Comme je ne connais pas, tant s’en faut, le détail de ce que fait 
> Lily, et que ça serait contre-productif que je m’y investisse, je 
> pourrais colloborer avec quelqu’un qui aurait cette connaissance. Tu 
> me sembles donc être le volontaire tout désigné!
>
> L’approche consisterait à créer une description LPSR (LilyPond Score 
> Representation) de la partition par un exporteur. Il faudrait voir ce 
> qui devrait être écrit en Scheme et en C++ respectivement.
>
> C’est ce LPSR que xml2ly construit pour ensuite produire le code 
> LilyPond à partir de ça, voir l’architecture à la page 2 de 
> https://github.com/jacques-menu/musicformats/blob/dev/doc/musicformatsArchitecture/musicformatsArchitecture.pdf 
> <https://github.com/jacques-menu/musicformats/blob/dev/doc/musicformatsArchitecture/musicformatsArchitecture.pdf> 
> .
>
> Pour illustrer comment la partition est décrite dans LPSR, je joins 
> l’exemple d’une partition minimale, mais avec quand même différents 
> aspects présents :
>
>
>
>
> On voit dans le log les deux composants de la description LPSR : le 
> premier est la musique (composant MSR), et le second tout à la fin ce 
> qu’il faut en plus pour structurer la partition comme on le fait en 
> LilyPond :
>
>   Book blocks
>     BookBlock
>       BookBlockElements
>         ScoreBlock
>             PartGroupBlock for partGroup "PartGroup_1 ('0', 
> partGroupName "Implicit")", partGroupSymbolNone, 1 element
> Donc pour résumer : si on peut créer cette description LPSR depuis 
> LilyPond par un exporteur, on a directement la conversion en MusicXML, 
> Guido et braille. MIDI n’est pas encore disponible, mais j’ai déjà 
> avancé dans cette direction.

Bonjour Jacques,

Je réponds en privé, sinon je crois que nous allons passer pour des 
extraterrestres ;-)

---

From: Marc <[email-masked]>
Date: Mon, 17 May 2021 22:22:58 +0200

> Je réponds en privé, sinon je crois que nous allons passer pour des 

Trop tard, c'est déjà fait..........

Marc L.