Nabil Bouzaïene & Emmanuel Saint-James
[bouzaien,esj]@liafa.jussieu.fr
Laboratoire d’Informatique Algorithmique
Fondements et Applications
4 place Jussieu
75252 Paris cedex 5
L'édition électronique
de partitions musicales vise pour le
moment à imiter plus ou moins bien des documents imprimés. Pourtant, la
numérisation de leur support ouvre des domaines inaccessibles à la gravure
traditionnelle. La mise au point de polices de caractères représentatives de
l'esthétique musicale sous-jacente en fournit déjà un exemple: théoriquement
faisable avec les moyens traditionnels, elle n'a pu être réalisée qu'avec
l'abaissement des coûts autorisé par l'informatique [1].
Un autre domaine
nouveau, rendu aisé par l'essor spectaculaire du Word Wild Web, est l'édition
d'une partition par plusieurs intervenants simultanément. Un avantage
quantitatif évident est la rapidité de production permise par le travail
simultané, particulièrement manifeste dans les œuvres sollicitant un grand
effectif orchestral.
Un avantage qualitatif
est que chaque portée de la partition peut être saisie par un musicien
connaissant bien l'instrument, donc particulièrement compétent pour éviter les
fautes de copies et lever les ambiguïtés.
Mais surtout, cette
mise en réseau permet à un groupe de musiciens de préparer l'interprétation
d'une œuvre en annotant identiquement leurs partitions, sans avoir
nécessairement à se rencontrer physiquement: un trio à cordes multi-national
peut par exemple décider à travers le Web des diminuendo & crescendo, des
successions tiré/poussé de l'archet etc. avant de se retrouver effectivement
pour un concert, voire jamais pour un enregistrement multi-pistes en différé.
Le présent article
propose donc un tel outil d'édition. Il se présente comme une applet Java
fonctionnant sous un navigateur Web. À la base, c'est un éditeur de partitions
multi-polices (grâce à un
interprète Embedded
PostScript intégré, écrit en Java) pouvant être utilisé en solitaire, mais
gérant des requêtes d'édition partagée lorsque d'autres utilisateurs
surviennent pour travailler sur la même
partition.
La section suivante
montre comment résoudre les limitations des navigateurs en matière de police,
ce qui nécessitera une étude assez fine des différences entre Java et
PostScript. La section d'après détaille les problèmes d'accès concurrents à une
partition. On conclura sur les perspectives d'avenir.
Un navigateur WEB a un
nombre de polices de caractères limité (6 pour Netscape 3.0 par exemple). Pour
visualiser une simple chaîne de caractères dans une police non prédéfinie, il
faut en remplacer une sur la machine cliente.
De plus, pour qu'un
utilisateur puisse utiliser cette nouvelle police, il faudrait qu'il la
télécharge et l'installe au préalable, ce qui ferait perdre à l'applet sa
portabilité. Il faut donc que la police soit embarquée dans l'applet, pour
qu'au moment du téléchargement de celle-ci la police soit déjà prête. Cela
permettra en plus de changer de police en cours d'exécution sans être obligé de
passer par une phase de réinstallation.
En réalité, il n'est
pas possible d'utiliser une police de caractères qui se trouve sur la machine
hôte, il faut contourner le problème en lisant ses polices en tant que fichiers
texte.
L'ensemble des polices
de caractères est donc sur la machine qui héberge l'applet, sous un format
PostScript, et à partir de la machine cliente, l'applet accède à ces
fichiers en fonction de la demande de
l'utilisateur final.
Pour permettre des
agrandissements (zoom) de la fenêtre de travail, il faut résoudre le problème
des marches d'escalier qui apparaissent quand un simple affichage à grande
échelle est réalisé.
Pour
cela, il faut redessiner le caractère à la bonne échelle, donc avoir une
description de chaque caractère en terme de courbes et non en terme de points
(selon l’opposition classique Vectorielle/bitmap) [2].

Fig 1 : Les marches d’escaliers
Le logiciel de
création de polices de caractères, "Fontographer" permet d'exporter
les polices en EPS, en fait, il est possible d'avoir un fichier contenant une
liste de fonctions PostScript dessinant tous les caractères à une certaine
échelle[1],
voici par exemple la fonction du caractère '0' (de la police Sonata):
%%[Char
name=], Char number, x offset, y offset, x width, y width, unicode value
%%Note:zero=48
13.4445 719 45 0 48
13.4445
719 m
s
13.6244
719.218 m
13.6244
719.219 l
13.7523
719.218 13.8043 719.083 13.8043 719 c
13.8043
718.918 13.7523 718.783 13.6244 718.783 c
13.4965
718.783 13.4445 718.918 13.4445 719 c
13.4445
719.083 13.4965 719.219 13.6244 719.218 c
s
13.6244
719.188 m
13.5584
719.188 13.5484 719.049 13.5484 719 c
13.5484
718.952 13.5544 718.815 13.6244 718.815 c
13.6944
718.815 13.7004 718.952 13.7004 719 c
13.7004
719.049 13.6904 719.188 13.6244 719.188 c
s
13.8043
719 m
s
Les lettres m, c, l et
s sont respectivement les fonction moveto, lineto, curveto et stroke du
PostScript.
Un caractère est constitué
d'un ensemble de parcours disjoints (comme l'exemple ci-dessus), le caractère
de notre exemple est en fait défini à l'aide de deux parcours :

Fig 2 : Le zéro est formé par deux parcours disjoints
Le programme réalisé,
part du fichier EPS contenant la description des contours des caractères puis
en extrait les valeurs numériques et les différentes fonctions (moveto,
curveto, etc...). Chaque caractère est donc représenté sous la forme d'un
tableau, contenant l'ensemble des fonctions et des valeurs numériques
nécessaires à son dessin.
Les fonctions
"MoveTo" et "LineTo" existent dans les classes de l'AWT de
Java, par contre le fonction CurveTo n'existait pas encore (elle vient de faire
son apparition dans la grosse API
Java2D). il a donc fallu programmer un petit algorithme qui décompose la courbe
de Bezier en segments de petite
longueur.
Le problème à résoudre
est donc de remplir les surfaces délimités par ces parcours, puisqu'il faut
savoir à chaque fois si le parcours est à colorer ou pas, et si oui comment
colorer juste l'espace entre les deux parcours.
En PostScript le
problème ne se pose pas pour deux raisons : d'un côté les différents
algorithmes de remplissage se basent sur la notion de parcours, alors que
l'algorithme de remplissage de Java, utilise la notion de forme.
De l'autre, le
remplissage des parcours en PostScript se comporte d'une façon différente s'il
traite un caractère appartenant à un police, ou s'il traite une forme quelconque
[3].
La solution apportée
est la suivante : au moment du dessin final à une échelle donnée, le caractère
est transformé en un ensemble de polygones correspondant chacun à un parcours
différent. À ce niveau, et puisque les parcours sont complètement disjoints, un
calcul de la "profondeur" du parcours est réalisé de la façon
suivante :
·
Un polygone qui
n'est contenu dans aucun autre à la profondeur 0
·
Un polygone contenu
dans un autre à la profondeur 1
·
Un polygone contenu
dans deux autres à la profondeur 2
·
Etc…

Ensuite, tous les polygones de profondeurs
paires sont remplis en noir, et tous les polygones de profondeurs impaires en
couleur de fond. Enfin il faut dessiner les polygones dans l'ordre de
profondeur croissante. Cet algorithme donne les mêmes résultats que
l’algorithme pair-impair de PostScript Pour des parcours convexes complètement
disjoints [3].
Fig 3 : Les parcours en pointillés sont coloriés en couleur de fond
Fig 4 :une édition distribuée sous Netscape

Pour permettre une
édition partagée dans de bonnes conditions et pour éviter tous les problèmes
que pourrait provoquer une déconnexion du réseau, il faut que chaque client ait
sa propre structure de données et qu'il informe les autres des modifications
qu'il opère dessus.
Par ailleurs, pour que
justement les clients puissent visualiser la même page à des échelles
différentes et avec des polices différentes, il faut qu'il y ait deux systèmes
de coordonnées : des coordonnées absolues, communes à tous les clients, et des
coordonnées propres au contexte d'affichage de chaque client. Les clients
dialoguent donc, en utilisant les coordonnées absolues, que chacun reconvertit
en fonction de son contexte d'affichage.
Un serveur tourne en
permanence sur la machine mère. Au démarrage l'applet "client" essaie
de s'y connecter, si elle y arrive elle l'informera de toutes les opérations
d'édition qu’elle opère sur la page courante. Le serveur transmet alors
l'information à tous les autres clients connectés au même moment.
Le résultat est qu'un
client donné n'est informé que des opérations qui ont lieu à partir du moment
de sa connexion.
Cette méthode présente
néanmoins un problème illustré par l'exemple ci-dessous :
Soient deux Clients A
et B travaillant sur la même partition :
Le client A envoie le
message : "suppression de la zone 50 50 100 100" qui veut dire qu'il
efface tous les composants qui sont situés dans cette région de la page. Au
"même" moment le client B, rajoute une note justement dans cette zone
avant de recevoir le message d'effacement du client A. Dans ce cas il peut
exister un conflit dont voici un bilan chronologique:
- Le client A efface
la dite zone sur sa page en informe le serveur et la voit effectivement
s'effacer.
- Le client B rajoute
une note, en informe le serveur, et la voit apparaître sur sa page.
- Pendant ce temps le
message de A arrive au serveur, il en informe B qui efface donc la note de sa
page.
- Et enfin le message
de B arrive au serveur qui en informe A qui rajoute donc la fameuse note.
Résultat : A et B
n'ont pas la même partition !
La deuxième solution
qui empêche ce comportement, consiste à faire en sorte que le serveur informe
tous les clients (y compris l'envoyeur) de tous les événements , et que chaque
client attende le retour du serveur pour effectivement procéder au changement ,
notre exemple devient :
- Le client A demande
l'effacement de la zone mais ne fait rien pour l'instant.
- Le client B demande
l'ajout d'une note et attend.
- Le message de A
arrive au serveur qui en informe A et B, qui effacent la zone sur les deux
pages.
- Le message de B
arrive au serveur qui en informe A et B, qui rajoutent tous les deux la note
sur la page.
Résultat: A et B ont
la même partition.
Cette solution est
satisfaisante dans le cas où il y a effectivement plusieurs clients qui
interviennent au même temps, mais fait perdre à l'application une fluidité
d'exécution même dans le cas où il y a un seul client.
Finalement, une
troisième solution repose sur deux modes d'exécution un "local" et
l'autre "en réseau". Quand un client demande une nouvelle connexion
au serveur, celui-ci teste s'il existe d'autres clients déjà connectés.
S'il n'y en a pas,
alors il informe le client qu'il est en mode "local". Celui-ci
n'avertit plus le serveur de ses changements mais reste, cependant, à son
écoute.
Par contre, si le
serveur trouve un seul autre client déjà connecté, alors il informe les deux
clients (l'ancien et le nouveau venu) qu'ils sont en mode "réseau",
et qu'il doivent informer le serveur de tous les changements.
De plus, il demande à
l'ancien de mettre à jour la page du nouveau, en lui transmettant l'état
(toutes les notes) de la page courante.
Enfin si le serveur
trouve plusieurs autres clients déjà connectés, il informe le nouveau client qu’il
est en mode "réseau" puis demande au plus ancien client de mettre à
jour le nouveau.
Voici un organigramme
qui résume l'action du serveur au moment d'une connexion :

Fig 5 : Activité du serveur au moment d’une nouvelle connexion
Pour permettre un
dialogue entre les différents intervenants sur une même partition, une fenêtre
textuelle est ajoutée. Il est donc possible de s'envoyer des messages textuels
comme dans une session de "chat", puis de se remettre dans la page de
travail pour agir sur la partition.
Le serveur différencie
les messages textuels des messages de travail grâce à un mot clef ajouté au
début des messages textuels.
Les problèmes de
sécurité bien connus sur le Web limitent la version actuelle de l'éditeur: une
applet java ne peut ouvrir un fichier sur la machine hôte, il n'est donc pas
possible de retravailler une partition saisie préalablement. Partant, la
sauvegarde est minimale: c'est un simple mémorisation des notes, sous le format
abc [4], évacuant volontairement toute indication graphique. Libre à
l'utilisateur ensuite d'imprimer le résultat par un éditeur type abc2ps, ou de
faire des copies d'écran pendant sa session.
L'adoption d'un format
plus riche, type NIFF, est à l'étude, ainsi que l'élaboration de droits d'accès
sur le serveur de l'éditeur afin de l'étendre à un atelier de composition de
partitions.
[1] Bouzaïene, Le Gall
& Saint-James, Une bibliothèque
informatique pour la notation musicale baroque, Lecture Notes in Computer
Science 1375, Springer 1998
[2] Jacques André &
Irène Vatton, Dynamic optical scaling and
variable-sized characters, Electronic Publishing vol 7(4), Décembre 1994
[3] Manuel de référence du langage PostScript, Deuxième édition,
Addison-Wesley 1992
[4] Chris Walshaw, The abc musical notation language,
http://www.gre.ac.uk/c.walshaw/abc/
[5] J.Gosling, B.Joy
& G.Steele,The Java language
specification, Addison-Wesley 1996
[1] Dans la sortie EPS de Fontographer, il y a une petite erreur, il utilise une fonction PostScript ‘n’ qu’il ne définit pas auparavant, il faut juste remplacer tous les ‘n’ par ‘newpath’ par exemple .