Thèse de doctorat

en

Intelligence Artificielle

[arrêté du 30 mars 1992]

 

Présentée par :

Vincent LESBROS

 

Sujet de la thèse :

 

Atelier Incrémentiel pour la

Musique Expérimentale

 

 

Directeur de thèse :

M.  Harald WERTZ

 

 

Université Paris 8

Département Informatique

Laboratoire d’Intelligence Artificielle

 

 

 

 

Soutenue le 24 Octobre 1995

devant le jury composé de :

M.M.     Patrick GREUSSAY   Président

              Daniel ARFIB              Rapporteur

              Claude CADOZ                      Rapporteur

              Giuseppe G. ENGLERT         

              Curtis ROADS

              Harald WERTZ


 

Remerciements

 

Je souhaite remercier ici tous ceux qui au cours de ce travail m'ont apporté leur précieuse aide.

 

Depuis mon arrivée à l'université, Giuseppe G. ENGLERT a guidé mes pas dans le monde de la musique expérimentale, en m'accueillant dans l'équipe du GAIV, m'initiant tant à la programmation qu'à la composition et me permettant de concrétiser, par de nombreux concerts, les rêves qui me hantaient. Notre travail d'équipe s'est transformé progressivement en étroite collaboration, voire en travail de concert sur des oeuvres communes. Je ne peux mesurer l'étendue de ma reconnaissance envers lui.

 

Harald WERTZ, Daniel GOOSSENS et Patrick GREUSSAY m'ont ouvert les yeux sur l'intelligence artificielle, et lancé sur les chemins de la recherche. Je les remercie pour les bagages qu'ils m'ont fourni, dans lesquels je puise les ressources me permettant d'affronter ces sentes escarpées, et ces parois rocheuses. Je leur dois la vue sur ce paysage magnifique.

 

Je remercie les membres du GAIV (Groupe Art & Informatique de Vincennes à St DENIS), son fondateur retraité Patrick GREUSSAY, Giuseppe G. ENGLERT, feu Gilbert DALMASSO, Marc BATTIER, Lirio MARTINEZ, Guillaume BILLAUX, Alawa BOUABDALLAH, Max HEDIGUER et Jean HOLLEVILLE. Que Marcel PROVOST soit remercié également pour sa bienveillance discrète et efficace envers cette équipe.

 

Je remercie Claude CADOZ et Daniel ARFIB de participer au jury et d'avoir accepté d'être les rapporteurs de cette thèse.

 

Je remercie Curtis ROADS, pour l'interêt qu'il a manifesté à l'égard de mes travaux ainsi que pour sa participation au jury.

 

Je remercie Daniel GOOSSENS, grâce à qui l'idée de phonogramme a pu prendre naissance, pour tous ses conseils, suggestions et remarques avisés.

 

Je remercie Marc BATTIER, Giuseppe ENGLERT et Pierre MARIETAN d'avoir contribué au développement de notre atelier au travers d'expériences, parfois émaillées d'erreurs...

 

Je remercie les enfants qui ont dessiné des phonogrammes, Corentin, Solène, et Fanny.

 

Que cette phrase soit une formule arborescente de remerciements pour Claude LENORMAND et Pierre AUDIBERT.

 

Mon goût pour la musique expérimentale a été renforcé grâce à Horacio VAGGIONE, Marc BATTIER, André RIOTTE, Joel CHADABE, Pierre MARIETAN.

 

Je remercie les membres du Laboratoire d'Intelligence Artificielle de Paris 8, Patrick GREUSSAY, Harald WERTZ, Françoise BALMAS, Damien PLOIX, Thierry DELAMARE, Sophie DELAMARE,  ALI CHERIF, Jean MEHAT, Renaud DUMEUR pour les nombreuses discussions qui ont contribué à l’achèvement de cette étude.

 

Je remercie Thierry DELAMARE, Marie Solange TOUZEAU et Maurice AMSELLEM grâce à qui le GAIV peut communiquer.

 

Ce message à pour objet tous mes remerciements et pour récepteurs Philippe KRIEF et François PACHET.

 

Je remercie mes patients relecteurs et parents.


 


Résumé

 

Notre travail, portant sur le domaine de la composition dans la musique expérimentale, a abouti à la création d'un atelier informatique propice au développement de trois grandes catégories d'applications : les éditeurs de représentations graphiques de pièces musicales et de sons pour la composition, la synthèse et l'analyse des sons, ainsi que le pilotage de synthétiseurs en temps réel; les applications pour la musique algorithmique en temps réel, et enfin les applications pour la musique algorithmique interprétée par des instrumentistes.

 

Nous présenterons d’abord notre système de représentation graphique des sons : les phonogrammes., ainsi que les principes et les techniques développées pour la représentation graphique de formes musicales et de sons, tels les trajectoires  de mobiles virtuels.

Nous montrerons également l'utilisation d’un système s’apparentant au modèle physique des couplages élastiques dans les modules graphiques, dans les procédés d'analyse et de synthèse du son, et même dans les algorithmes compositionnels. Ceci débouchera sur l'exposé de nos systèmes de synthèse et d'analyse induits par ces représentations graphiques.

 

Ensuite nous exposerons le module Métronome, cœur des applications de génération en temps réel. Ce noyau est utilisé par des étudiants en musicologie, pour développer des applications musicales expérimentales variées. Nous l'avons également utilisé pour la réalisation de systèmes générateurs de formes musicales réagissant à des stimuli musicaux externes : modes, harmonie, mélodie, rythmes. Le résultat principal de ce module est un séquenceur algorithmique interactif. Des algorithmes de génération mélodique seront présentés, en particulier l'algorithme de composition de la partie de contrebasse d'une pièce mixte : Méduse pour contrebasse et phonogramme.

 

Nous examinerons enfin le module de génération automatique de partitions, utilisé en particulier pour la composition d’une pièce pour orchestre et piano concertant.

 

Nous pensons que le processus de composition de musique par ordinateur nécessite une connaissance simultanée des domaines musical et informatique, et qu'aucun système ne fournira la possibilité ni à un musicien non informaticien d'exploiter toutes les possibilités que peuvent offrir les machines dans ce domaine, ni à un informaticien non musicien de faire de la musique. Aboutissant toutefois d'une part à des outils purement informatiques et d'autre part à des applications utilisables par des compositeurs, nous préférons une approche où les compositeurs-informaticiens peuvent s'exprimer dans des espaces multiples, sans leur imposer une conception préétablie.



 

Résumé                                    ........................................................................................................................................ 4

1.                                               Introduction............................................................................................................... 10

1.1.                                      Vocabulaire................................................................................................................. 10

1.2.                                      AIME, l’atelier incrémentiel..................................................................................... 11

1.3.                                      Une représentation graphique des sons pour la synthèse additive en temps réel             16

1.4.                                      Trajectoires élastiques de mobiles virtuels........................................................... 20

1.5.                                      Couplages élastiques................................................................................................ 21

1.5.1.                             L’aspect statique des réseaux de couplages......................................................... 21

1.5.2.                             L’aspect dynamique des réseaux de couplages................................................... 24

1.6.                                      La transformée élastique.......................................................................................... 24

1.7.                                      Un séquenceur algorithmique interactif................................................................. 27

1.8.                                      Un générateur de partitions pour piano et orchestre........................................... 29

1.9.                                      Conversions............................................................................................................... 36

2.                                               Représentation graphique des sons....................................................................... 40

2.1.                                      Principe des phonogrammes.................................................................................... 41

2.1.1.                             Échelle microtonale des phonogrammes................................................................ 41

2.2.                                      Représentation interne des phonogrammes.......................................................... 45

2.2.1.                             Dissection des images.............................................................................................. 45

2.2.2.                             Algorithme d’intégration d’un segment................................................................ 47

2.2.3.                             Vectorisation.............................................................................................................. 51

2.2.4.                             Conversion vectorielle/bitmap................................................................................ 54

2.2.4.1.                   Traitement numérique d'images............................................................................... 55

2.3.                                      Outils graphiques spécialisés.................................................................................. 56

2.3.1.                             Pinceau à harmoniques............................................................................................. 60

2.3.2.                             Pinceau à timbres....................................................................................................... 62

2.3.3.                             Tracé élastique de courbes et de droites............................................................... 67

2.3.4.                             Masques pour échelles microtonales..................................................................... 68

2.4.                                      Synthèse et analyse des sons dans Phonogramme............................................. 69

2.4.1.                             Les images de Phonogramme.................................................................................. 69

2.4.2.                             La synthèse sonore à partir des images................................................................. 70

2.4.2.1.                   Synthèse additive ou synthèse directe.................................................................. 70

2.4.2.1.1.          Traitement du signal................................................................................................. 76

2.4.2.1.2.          Visualisation du signal............................................................................................. 77

2.4.2.1.3.          Accès disque, flux et flux AIFF............................................................................... 77

2.4.2.2.                   Conversion des phonogrammes vers la norme MIDI.......................................... 78

2.4.2.2.1.          Exécution en temps réel des phonogrammes........................................................ 78

2.4.2.2.2.          Génération de fichiers MIDI.................................................................................... 81

2.4.3.                             L'analyse du son pour la synthèse d'images......................................................... 81

2.4.3.1.                   Transformée de Fourier Rapide............................................................................... 81

2.4.3.2.                   Transformée de Fourier discrète............................................................................. 86

2.5.                                      Organisation temporelle des phonogrammes........................................................ 88

2.5.1.                             Les marques............................................................................................................... 88

2.5.2.                             Les schémas............................................................................................................... 90

2.5.2.1.                   Structure et réflexes des schémas........................................................................... 90

2.5.2.1.1.          Structure des cellules et des flèches...................................................................... 90

2.5.2.1.2.          Propriétés des cellules et des flèches..................................................................... 91

2.5.2.1.3.          Surfaces sensibles et déclencheurs........................................................................ 94

2.5.2.2.                   La clepsydre ou le sablier......................................................................................... 96

2.6.                                      Convolutions............................................................................................................. 97

2.6.1.                             Génération de suites............................................................................................... 102

2.6.2.                             Les multiplications.................................................................................................. 104

2.6.3.                             Des nombres infinis à gauche vers une méthode de multiplication......................                106

2.6.3.1.                   Représentation graphique des tables de divisions et multiplications............. 116

2.6.3.1.1.          Division..................................................................................................................... 117

2.6.3.1.2.          Multiplication........................................................................................................... 117

2.6.3.1.3.          Constructions.......................................................................................................... 119

3.                                               Oscillateurs et trajectoires...................................................................................... 122

3.1.                                      Le bruissement des feuilles.................................................................................... 122

3.2.                                      Les trajectoires......................................................................................................... 123

3.3.                                      Mise en œuvre des trajectoires............................................................................. 128

3.4.                                      Conversion de phonogrammes vers des trajectoires......................................... 130

3.5.                                      Expériences avec les trajectoires........................................................................... 131

4.                                               Couplages élastiques.............................................................................................. 138

4.1.                                      Des interfaces graphiques..................................................................................... 138

4.2.                                      De la transformation, de l'analyse et de la création de sons............................. 146

4.2.1.                             Filtrage...................................................................................................................... 149

4.2.2.                             Synthèse................................................................................................................... 150

4.3.                                      Le carré de la distance............................................................................................ 154

4.4.                                      Simulation de ressorts............................................................................................ 154

4.5.                                      Imprécision du calcul dans la simulation............................................................. 161

4.6.                                      Résonateurs à couplages élastiques.................................................................... 162

4.6.1.                             Expérience avec les graphes de couplages élastiques...................................... 162

4.7.                                      Génération de trajectoires à partir de réseaux de couplages............................. 172

4.8.                                      Conversion des trajectoires en réseaux élastiques circulaires......................... 176

4.9.                                      Interface graphique pour les graphes de couplages élastiques.............................                177

5.                                               Transformée élastique............................................................................................ 179

5.1.                                      Analyse acoustique directe................................................................................... 179

5.2.                                      Procédé d'analyse.................................................................................................... 179

5.3.                                      Contrôle de la résonance........................................................................................ 182

5.4.                                      Optimisation............................................................................................................. 183

5.5.                                      Algorithme des résonateurs.................................................................................. 184

5.6.                                      Étalonnage des fréquences des résonateurs...................................................... 185

5.7.                                      Étalonnage des niveaux des résonateurs............................................................ 186

5.8.                                      Production de signal par bancs de résonateurs................................................. 191

5.9.                                      Stimulation des bancs de résonateurs par des flux MIDI................................. 192

5.10.                                    Filtrage d'un signal par bancs de résonateurs.................................................... 192

5.11.                                    Génération d’un réseau élastique à partir d’un signal....................................... 192

6.                                               Métronome : noyau d’applications pour la composition algorithmique en temps réel      195

6.1.                                      Infrastructure........................................................................................................... 195

6.1.1.                             Le système hôte....................................................................................................... 195

6.1.2.                             Un squelette d’application..................................................................................... 196

6.1.3.                             Boîte à fenêtres........................................................................................................ 196

6.1.4.                             Boîte à outils............................................................................................................ 197

6.1.4.1.                   Visualisation automatique d’allocations dynamiques....................................... 198

6.1.4.1.1.          Points d'entrée......................................................................................................... 200

6.1.4.1.2.          Détection des pointeurs......................................................................................... 202

6.1.4.1.3.          Représentation graphique des blocs de mémoire............................................... 203

6.1.4.1.4.          Actualisation dynamique et élastique.................................................................. 205

6.1.4.1.5.          Calcul des tensions élastiques.............................................................................. 208

6.1.4.1.6.          Manipulation des représentations........................................................................ 209

6.1.4.1.7.          Vent (ou placement semi-automatique)................................................................ 209

6.1.4.2.                   Descriptions de contrôles...................................................................................... 210

6.2.                                      Le module Métronome............................................................................................ 212

6.3.                                      Interface MIDI, le Système MIDIShare................................................................ 213

6.3.1.                             Enregistrement de flux MIDI dans les phonogrammes...................................... 214

6.3.2.                             Traitement MIDI...................................................................................................... 214

6.4.                                      Algorithme rythmique & dynamique de Métro3................................................ 215

6.4.1.                             Les durées................................................................................................................ 215

6.4.2.                             La dynamique........................................................................................................... 217

6.4.2.1.                   Accentuation dynamique aléatoire....................................................................... 217

6.4.2.2.                   Accentuation dynamique arborescente............................................................... 218

6.5.                                      Harmonies................................................................................................................. 219

6.5.1.                             Gammes..................................................................................................................... 222

6.5.2.                             Intervalles................................................................................................................. 225

6.5.3.                             Accords.................................................................................................................... 225

6.5.4.                             Composition algorithmique.................................................................................... 232

6.5.4.1.                   Module Intervalle.................................................................................................... 232

6.5.4.2.                   Le module Module.................................................................................................. 236

6.5.4.3.                   Le module Pouzzolane............................................................................................ 243

6.5.4.3.1.          Structure des mémoires mélodiques..................................................................... 245

6.5.4.3.2.          Algorithme de Pouzzolane..................................................................................... 246

6.5.4.4.                   Le module Alpha..................................................................................................... 249

6.6                                       Exosmose.................................................................................................................. 251

7.                                               Générateurs de partitions....................................................................................... 252

7.1.                                      Éditeurs de partitions.............................................................................................. 253

7.2.                                      Chnrng14 : Générateur de partitions pour piano et orchestre................................                253

7.3.                                      Impression de partitions......................................................................................... 254

7.3.1.                             Notation musicale.................................................................................................... 255

7.3.1.1.                   Structures des pages.............................................................................................. 258

7.3.1.2.                   La lecture.................................................................................................................. 263

7.3.2.                             Module d'impression.............................................................................................. 264

7.3.2.1.                   Structure des événements sonores et silencieux................................................ 264

7.3.2.1.1.          La structure des notes............................................................................................ 266

7.3.2.2.                   Information de mise en page et de sélection....................................................... 271

7.3.2.3.                   Décomposition en éléments graphiques.............................................................. 275

7.3.2.4.                   Tension élastique pour la mise en page............................................................... 276

7.3.2.5.                   Position des altérations.......................................................................................... 278

7.4.                                      Production de partitions à partir de phonogrammes.......................................... 278

7.5.                                      Conversion de partitions en phonogrammes...................................................... 283

7.6.                                      Lecture automatique de partitions musicales...................................................... 285

7.7.                                      Liberté Verticale....................................................................................................... 285

7.7.1.                             Le mouvement.......................................................................................................... 286

7.7.2.                             La mémoire................................................................................................................ 288

7.7.3.                             Les modes et les positions de doigts................................................................... 289

7.8.                                      Algorithme de génération mélodique................................................................... 293

7.8.1.                             Irlandais, pour violon.............................................................................................. 293

7.8.1.1.                   Reels et Hornpipes, structure rythmique, harmonique et mélodique....................                294

7.8.1.2.                   Base modale............................................................................................................. 295

7.8.1.3.                   Ligne mélodique...................................................................................................... 297

7.8.1.4.                   Règles de pondération des tirages aléatoires..................................................... 298

7.8.1.4.1.          Arbres d’appels de fonction pseudo-aléatoire................................................... 302

7.8.1.4.2.          Interface de construction des arbres binaires..................................................... 311

7.8.1.5.                   Paramétrage des choix aléatoires.......................................................................... 312

7.8.1.6.                   Plans de copies........................................................................................................ 312

7.8.1.6.1.          Les plans locaux : recopie d'une note................................................................... 312

7.8.1.6.2.          Les plans généraux : forme ABAC........................................................................ 313

7.8.2.                             Méduse, pour Contrebasse et Phonogrammes................................................... 314

Conclusion                              .................................................................................................................................... 317

8.1.                                      Les limitations actuelles et l’évolution de l’atelier............................................. 318

8.1.1.                             Les limitations actuelles de AIME dans le domaine graphique.............................                318

8.1.2.                             Limitations temporelles........................................................................................... 320

8.2.                                      Développements actuels et perspectives............................................................ 321

Annexe 1 Dimensions physiques des sons........................................................................................................... 331

L'effet Doppler                 .................................................................................................................................... 337

Annexe 2 : Irlandais               .................................................................................................................................... 342

Annexe 3 : Règle de couplage (frottement)............................................................................................................ 351

Annexe 4 : Phénomènes Physiques en Acoustique, Étude expérimentale du timbre des sons...........................                353

Analyse d’un son complexe par les résonnateurs (sic)................................................................................ 353

Composition des sons complexes.................................................................................................................... 355

Références bibliographiques................................................................................................................................... 356

 


1.         Introduction

 

Nous présentons notre atelier informatique d’expérimentation musicale : AIME (Atelier Incrémentiel pour la Musique Expérimentale), qui est le premier atelier musical permettant d’utiliser à la fois les outils de notation, de génération, de transformation de sons (ou de formes musicales) et la totalité des fonctionnalités de traitement des images, permettant au compositeur/interprète d’utiliser indistinctement l’une ou l’autre de ces représentations, dépendant des actions particulières (transpositions, étirement temporel, modifications dans le domaine spectral, collages, etc.) qu’il désire effectuer.

Dans cet atelier sont nées de multiples applications (dont Phonogramme, Métro3, Chnrng14) représentant des approches compositionnelles fondées sur des concepts spécifiques, inventés spécialement pour une pièce, ou permettant au contraire une expression directe des compositeurs à l’aide d’outils génériques, leurs offrant divers systèmes de représentation des formes musicales et des moyens de conversion d’une forme à une autre.

 

1.1.     Vocabulaire

 

Avant de présenter les trois principales applications qui serviront de support pour notre exposé, nous souhaitons ici introduire brièvement différents systèmes de représentation du son que nous utilisons dans la suite, ainsi que certains termes désignant nos systèmes ou procédés :

 

Les sons échantillonnés (ou signaux sonores échantillonnés), ou sons numériques, sont conservés sous la forme amplitude/temps. Un son est alors représenté par une suite de valeurs numériques décrivant les variations de pression de l’air[1] par rapport à la pression normale. Une façon intuitive de le présenter est de dire que les valeurs indiquent la position de la membrane du haut-parleur (ou du micro, ou encore du tympan) à chaque instant.

 

Les sonogrammes  (ou sonagrammes  selon Xavier RODET (RODET 1977)) sont des représentations du son dans un espace fréquence/temps. Un sonogramme est constitué d’une succession de spectres instantanés, chaque spectre donnant l’énergie du signal en fonction de la fréquence pour une fenêtre  ou tranche temporelle donnée.

 

Les phonogrammes  sont des représentations des sons proches des sonogrammes (dans le même espace fréquence/temps), mais l’échelle des fréquences est logarithmique. Nous en avons étudié la structure de données pour faciliter leur exploitation, tant du point de vue graphique que sonore.

 

Les couplages élastiques, sont des liens reliant les nœuds d’un graphe et appliquant une tension sur ces nœuds. Les nœuds du graphe peuvent être fixes ou mobiles : seuls les nœuds mobiles subissent un changement de coordonnées fonction des tensions des liens.

 

La transformée élastique est notre système d’analyse des sons basée sur les couplages élastiques. Elle permet de transformer des sons échantillonnés en phonogrammes.

 

Les trajectoires  que nous mentionnons ci-après sont les trajectoires de mobiles virtuels, dont la projection de la position sur un axe au cours du temps nous sert à construire un signal sonore échantillonné.

 

Les applications : Un programme exécutable, dans l’environnement Macintosh est désigné par le terme application. Nous avons gardé cette terminologie.

 

Les modules  : Nous dénommons module un ensemble cohérent de fonctions et structures de données, relatives à un problème particulier.

 

Les squelettes. : Un squelette est un programme type similaire aux schémata de Françoise BALMAS (BALMAS 1995), définissant les éléments minimums nécessaires pour implémenter une architecture particulière. Ce programme, est destiné à être recopié, puis transformé pour le spécialiser.

 

1.2.     AIME, l’atelier incrémentiel

 

L’atelier est formé par un ensemble d’applications, de bibliothèques de fonctions et de squelettes d’applications. L’écriture de nouvelles applications ou de nouveaux modules contribue à l’enrichissement de l’atelier, tant au niveau de la programmation (création de nouvelles bibliothèques, ou ajout de fonctions génériques dans les bibliothèques) qu’au niveau musical, l’activité de composition étant facilitée par les nouvelles fonctionnalités. Toutes les applications de l’atelier peuvent être connectées les unes aux autres via le système de communication implémenté dans MIDIShare. MIDIShare est développé à GRAME[2] (ORLAREY 1989) (cf. § Interface MIDI, le Système MIDIShare).

Ci dessous nous présentons brièvement Phonogramme, Métro3 et Chnrng14 qui représentent les trois grandes classes d'applications musicales que nous avons développées dans le cadre de cette thèse :

 

• Phonogramme (LESBROS 1995a, 1995b) (ROADS 1995) est fondé sur le concept d'édition interactive. Comme une palette graphique, les documents qu'il permet d'éditer sont des images, mais ces images sont encodées sous une forme telle qu'elles peuvent être interprétées comme des sonogrammes et être jouées en temps réel ou produire des fichiers de sons échantillonnés.

 

Figure 1.1 : Exemple d’image créée dans l’application Phonogramme.

 

Cette image (Figure 1.1) représente des sons d’intensités différentes exprimées en valeur de gris. Les traits superposés conservant constants les écarts verticaux sont ici à des distances correspondant à des harmoniques.

 

À l'inverse de cette possibilité de génération, des sons produits par des sources externes peuvent être intégrés aux images par notre procédé de transformée élastique. Dans la même application sont intégrés d'autres systèmes de représentation graphique des sons, telles que le module d'édition de trajectoires élastiques permettant la synthèse de vibrations amorties, et un module d'édition graphique de réseaux de couplages élastiques permettant une forme de synthèse par simulation de la propagation des vibrations, ainsi que le filtrage de sources sonores externes par la propagation des vibrations dans le réseau.

 

Figure 1.2 : Exemple de trajectoire.

 

Au cours de la simulation, la trajectoire se déforme sous l’action des couplages élastiques connectant les points successifs de la trajectoire. La projection sur l’axe horizontal de la position du mobile virtuel circulant le long la trajectoire au cours du temps fournit un son échantillonné.

 

Voici à présent un exemple de réseau de couplages élastiques (figure 1.3). L’interface homme-machine permet de créer et modifier le réseau directement à l’aide de la souris.

 

Figure 1.3 : Exemple de réseau de couplage

 

 Noeud fixe,  Noeud mobile,  Couplage élastique

 Émetteur,  Récepteur.

 

Les émetteurs permettent d’exciter le réseau en déplaçant chacun un ou plusieurs noeuds[3] selon les valeurs d’amplitude provenant d’un fichier de son échantillonné. Les récepteurs permettent de produire chacun un fichier de son échantillonné à partir de la position des noeuds et/ou de la longueur des liens auxquels ils sont connectés. Au cours de la simulation, les couplages modifient la position des noeuds mobiles, l’image est animée.

 

• Métro3 (ENGLERT 1993), dont le concept central est celui d'un séquenceur (Métronome), est une application permettant la préparation et l’exécution en direct de pièces de musique synthétique. Son interface et ses fonctionnalités en font un outil sophistiqué, permettant le contrôle de la génération des événements sonores, et des transformations des séquences de notes en temps réel. Son modèle est exploité dans d'autres applications (cf. § Composition algorithmique) temps réel à base algorithmique que nous présentons dans la suite.

 

• Chnrng14 (change ring 14) est représentative parmi nos applications pour la musique algorithmique générée automatiquement en vue d'une exécution par des instrumentistes. Elle comporte un module de génération spécifique d'une pièce : Chacones, pour orchestre et piano concertant (ENGLERT 1995), et un module de mise en page et d'impression de partitions pour orchestre et pour piano. Ce dernier module est utilisé dans d'autres applications génératrices de partitions, dont les modules de génération sont contrôlés par un ensemble de paramètres dépendants de l’algorithme tels que les instruments, l’ambitus, la densité d’événements, les paramètres rythmiques, etc.

 

L'exposé des différents passages existant entre les formes de représentations manipulées dans le système nous permettra de découvrir les cheminements possibles des compositeurs utilisant notre atelier (cf. § Conversions).

 

En effet, nous pouvons créer des sons d’après des images, nous pouvons modifier, transformer ces sons, utiliser des sons existant pour former de nouvelles images, transformer ces images, utiliser notre système pour produire une partition, ou au contraire intégrer une partition[4] dans une image. Les productions des algorithmes de génération peuvent également être intégrés dans les images, ou inversement, l’interprétation des images peut être transformée par l’application d’algorithmes. Toutes ces transformations et les conversions possibles entre différents modes de représentation du son ou des séquences musicales offrent de nouvelles voies dans le domaine de la composition de musique expérimentale.

Par exemple Marc BATTIER a composé sa pièce TOCA (BATTIER 1994), en utilisant Phonogramme pour transformer en son des images obtenues à partir de l’analyse spectrale de sons réels[5]

 

1.3.     Une représentation graphique des sons pour la synthèse additive en temps réel

 

Une pièce en quarts de tons est jouable par deux pianos : Chaque piano, pris séparément est accordé normalement, en demi-tons et peut être joué naturellement. Mais un des deux pianos est accordé un quart de ton plus haut que l’autre. Cet entrelacement des deux échelles, mis en valeur par un long travail de synchronisation, de mimétisme du jeu et des mouvements des interprètes, permet la perception pour l’auditeur de l’existence d’une unique échelle en quarts de tons.

Nous avons transposé cette idée, pour l’appliquer à un banc de seize synthétiseurs[6] limités chacun à la gamme chromatique[7]. Chaque synthétiseur a donc été accordé sur un seizième de demi-ton particulier. L’entrelacement des échelles chromatiques donnant ainsi naissance à une unique échelle microtonale en trente-deuxièmes de ton.

 

Figure 1.4 : Cette figure représente graphiquement l’entrelacement entre les différentes échelles, d’abord par un instrument seul, ensuite par deux, et ainsi de suite. En augmentant le nombre d’instruments chromatiques (numérotés à gauche), nous obtenons des échelles de plus en plus fines. Pour n instruments, l’échelle obtenue est en demi-tons divisé par n.

 

Figure 1.5 : L’échelle totale dont nous disposons avec les 16 synthétiseurs couvre 128 demi-tons avec un pas de 1/32ième de ton (2048 notes).

 

Notre but initial étant la synthèse en temps réel de sons représentés dans le domaine temps-fréquence tel les sonogrammes, nous avons créé une représentation particulière, proche de sonogrammes, adaptée à la visualisation et aux manipulations graphiques, qui est principalement une tablature pour ce système d’échelles multiples entrelacées. Nous désignons cette représentation par le terme phonogramme.

 

Figure 1.6 : Cette figure présente un extrait d’une page de la pièce Phonographiques  (LESBROS 1994) représentant environ 85 secondes. L’image est ici réduite à 50% de sa taille originale.

 

Les traits épais de la figure 1.6, orientés horizontalement et dessinés à la souris forment des sons harmoniques à caractère vocal. La série de barres verticales prolongées par des traits horizontaux représentent des sons percussifs subissant une diminution d’amplitude assez rapide suivie d’une résonance. Le nuage de points dans le registre aigu (la partie supérieure de l’image) a été formé aléatoirement et produit des sons évoquant des tintements ou cliquetis de petits objets légers et durs.

 

Les phonogrammes permettent à la fois la représentation des images et des sons. L’exécution en temps réel d’un phonogramme consiste globalement à transmettre des messages décrits par ces structures aux seize modules de synthèse externes. Ceci est réalisable avec un micro-ordinateur de faible puissance[8].

Ce système de représentation a ouvert un champ de recherche et d’investigation important et nous avons développé des outils et des fonctionnalités d’une part pour explorer ce domaine et établir des liens avec d’autres systèmes de représentation de la musique (partitions, signaux échantillonnées, trajectoires, etc.) et d’autre part pour rendre accessible un système de composition graphique de musique à d’autres compositeurs.

La base du système, le module d’exécution des phonogrammes a été développée en utilisant le module Métronome (cf. Chapitre 6). Puis nous avons adjoint des outils graphiques spécifiques, en particulier un pinceau à timbres, que nous présentons dans le chapitre Outils graphiques spécialisés. Nous nous sommes affranchis des modules de synthèse externes[9] en implantant la synthèse additive (cf. § Synthèse additive ou synthèse directe), quitte à perdre les avantages de l’exécution en temps réel, mais en gagnant le contrôle complet sur le signal généré.

Les problèmes d’entrée/sortie des images étant résolus (import de fichiers au format PICT[10], copie des images depuis et vers le presse-papiers), le passage des images aux sons existant sous plusieurs formes, il nous manquait la possibilité de passer de signaux sonores vers la représentation en phonogramme correspondant. Nous présentons dans le chapitre L'analyse du son pour la synthèse d'images,  les systèmes classiques d’analyse que nous avons utilisé : les convolutions, la transformée de FOURIER (SOIZE 1993) (BEAUCHAMP 1987) (BRACEWELL 1986), puis dans les chapitres suivants, nous présentons notre système de transformée élastique, mieux adapté à ce traitement. Les sons percussifs de l’image précédente (figure 1.6) ont été obtenus par la transformée élastique d’un signal échantillonné préexistant.

 

Nous avons utilisé les phonogrammes dans des œuvres différentes, parmi lesquelles : Farni-NT[11], une pièce réalisée pour mettre en musique une histoire mise en scène par les enfants de l’école de CHELLES, Phonographiques, une pièce pour phonogramme basée sur l’usage de différentes techniques graphiques : par exemple le choix des supports et des outils, ainsi que l’exploitation de différentes techniques gestuelles utilisées pour créer les graphismes, Pouzzolane, une pièce composée pour un festival sur la microtonalité[12], et Midisonnante  composée pour le centième anniversaire de Prélude à l’après-midi d’un faune de Debussy[13].

Giuseppe ENGLERT a utilisé Phonogramme[14] pour réaliser l’intégralité de la pièce Triptyque . Dans un concert à KOBE, Marc BATTIER (BATTIER 1993) fut le premier à utiliser des sons produits par Phonogramme , avec la création de la pièce Toca, pour sons électroniques et marimba.

 

1.4.     Trajectoires élastiques de mobiles virtuels

 

Avant d’être perçu, le son est une vibration. Pour synthétiser des sons nous devons construire des oscillateurs. Nous présentons dans le chapitre Oscillateurs et trajectoires, des oscillateurs numériques basés sur la construction de signaux résultant de la projection sur une dimension, de trajectoires de mobiles virtuels d’un espace à deux dimensions.

Les déformations élastiques appliquées sur des trajectoires permettent la synthèse de sons à caractère naturel. Un cas particulier de trajectoires élastiques correspond à l’algorithme de Karplus-Strong (KARPLUS STRONG 1983) (JAFFE SMITH 1983) pour la synthèse de sons de cordes pincées et de percussions.

La simplicité avec laquelle nous pouvons dessiner les trajectoires et obtenir les sons nous a conduit à la réalisation d’une application indépendante de Phonogramme, nommée Sound Potato, que des enfants peuvent utiliser pour créer des sons avec la souris.

 

1.5.     Couplages élastiques

 

Les premières simulations de couplages élastiques que nous avons réalisées (LESBROS 1988) étaient exploitées uniquement sur le plan graphique. Le réalisme de la simulation du mouvement ne nous intéressait pas, seule la convergence du réseau formé par les couplages, entre points fixes et points mobiles vers un état stable était l’objet de notre étude.

 

1.5.1.         L’aspect statique des réseaux de couplages

 

Le traitement de la propagation de l’influence mutuelle des tensions élastiques dans le réseau était initialement écrit de manière récursive. Ceci reste correct tant que l’on souhaite n’utiliser que l’état final du réseau, mais les configurations intermédiaires du réseau dépendaient de l’ordre de traitement de l’action des liens sur les points, lui-même dépendant de l’ordre de construction du réseau.

 

Voici, par exemple un réseau très simple (figure 1.7), constitué de trois points fixes reliés à un point mobile.

 

Figure 1.7 : Un réseau de couplages élastiques

 

La représentation interne que nous avions adoptée donnerait le schéma correspondant ci-dessous (figure 1.8) :

 

Figure 1.8 : Représentation interne d’un réseau de couplages

 

Les points connaissent leur position et la liste (ordonnée par construction) de leurs liens, les liens pointent sur les deux points qu’ils relient.

Nous pouvons simplifier la représentation interne, en éliminant la représentation des liens en tant qu’objets indépendants (figure 9), et en les représentant implicitement par la liste des points voisins de chaque point. Les liens seront alors incapables de mémoriser des caractéristiques particulières (telle la tension), mais le schéma correspondant s’éclaircit considérablement.

 

Figure 1.9 : Représentation interne simplifiée du réseau de couplages.

 

L’ordre de traitement des tensions est déterminé ici par l’ordre d’apparition des liens dans la liste des liens du point ou dans la liste des voisins d’un point selon la représentation choisie.

 

L’algorithme de traitement pouvait se résumer ainsi :

 

Déplacement d’un point :

 

• Calculer les tensions appliquées sur ce point[15]

• Si la tension est supérieure à un seuil[16]

      • Changer la position du point

      • Effectuer récursivement le déplacement des points voisins.

 

 

Cet algorithme entraîne l’effet suivant : des parties du réseau peuvent se stabiliser localement, puis les modifications des positions des points se propagent à d’autres parties du réseau, jusqu’à la stabilisation globale.

 

Dans le cas de réseaux linéaires, tels ceux utilisés pour le trajet des flèches des schémas temporels de Phonogramme (voir ci-dessous), ou ceux utilisés dans le module de mise en page des pentagrammes (cf. chapitre Générateurs de partitions), la conjugaison de ce principe résulte en une simple boucle, qui, applique la tension sur chaque point l’un après l’autre.

 

1.5.2.         L’aspect dynamique des réseaux de couplages

 

L’utilisation des réseaux de couplages élastiques pour la synthèse et l’analyse de signaux acoustiques a nécessité la prise en compte des états intermédiaires des réseaux élastiques en cours de stabilisation, ou excités continûment par un apport externe d’énergie. C’est-à-dire la prise en compte de la dynamique du réseau donnée par le mouvement des points.

 

La description des mouvements s’effectue dans l’espace et dans le temps (alors que la position stable d’un réseau ne nécessite qu’une description spatiale).

Ce nouveau paramètre, le temps, doit subir une discrétisation, de façon à pouvoir manipuler des états successifs du réseau de couplage.

La représentation doit permettre de fournir la position de tout point à un instant donné de manière à calculer la position des points pour l’instant suivant. Le calcul des positions au temps ti+1 ne doit pas modifier les données concernant la position au temps ti.

L’implémentation des réseaux de couplages élastiques que nous présentons dans le chapitre Couplages élastiques, utilise un algorithme simulant le parallélisme temporel de l’influence des couplages élastiques sur la position des points.

 

1.6.     La transformée élastique

 

La synthèse sonore à partir de réseaux de couplages élastiques est effectuée en enregistrant les mouvements des points du réseau au cours du temps. D’autre part, nous avons utilisé les réseaux élastiques pour filtrer des sons : nous pouvons exciter le réseau en déplaçant un ou des points selon les valeurs d’amplitudes de signaux existant, et enregistrer les mouvements d’autres points du réseau. Suivant la configuration du réseau, les tensions des couplages, et la viscosité[17] du milieu, nous obtenons des filtrages différents. Ceci nous a conduit à la réalisation de bancs de résonateurs constitués d’un point fixe, d’un point mobile et d’un point mu par le signal. Le réglage de la tension des couplages entre ces points s’avère lié à la fréquence de résonance du système. Le banc de résonateur agit comme un banc de filtres, chaque filtre étant sensible à une bande de fréquence réduite. Nous nommons transformée élastique le processus de filtrage d’un signal par ce type de banc de résonateurs en vue de la production d’un phonogramme.

 

Figure 1.10 : Spectre obtenu par le banc de résonateurs à partir d’un signal sinusoïdal. De chaque coté, on voit que, en dessous d’un seuil donné, seul un resonateur sur 16 reste actif.

 

Figure 1.11 :  Un extrait de Summer time  joué par Charlie Parker (PARKER 1988) analysé par la transformée élastique entre 100 et 3000 Hertz.

 

La transformée élastique peut être utilisée pour analyser des séquences musicales (figure 1.11). Dans les harmoniques, on voit nettement le vibrato (variation de fréquence des notes) sur les notes tenues. L’image a été traitée pour ne retenir que les valeurs dépassant un certain seuil.

 

Outre la synthèse directe et l’analyse des sons, la composition de musique expérimentale nécessite des outils permettant la manipulation de diverses formes sonores, par exemple des séquences de notes. Phonogramme permet d’analyser un son (par la transformée élastique) et de le transformer en séquences de notes (sous forme de fichiers MIDI). Ou inversement, le séquenceur Métro 3, décrit dans le paragraphe suivant, peut générer des séquences qui seront retranscrites en phonogrammes en vue de leur transformation et/ou de leur synthèse.

 

1.7.     Un séquenceur algorithmique interactif

 

Depuis 1982, nous développions[18] des programmes de composition musicale interactifs, permettant une exécution en temps réel. Nous utilisions le système Synclavier Model A[19], constitué d’un micro-ordinateur et d’un module de synthèse mixte basé sur la modulation de fréquence. La mémoire de cette machine était de 64 kilo octets (32 K mots de 16 bits), et nous ne disposions pas de mémoire de masse autre que des disquettes souples d’une capacité inférieure à 300K. Ces contraintes physiques nous imposaient l’élaboration d’algorithmes de génération musicale nécessitant peu de mémoire, utilisant donc des modèles de génération basés sur un ensemble restreint de paramètres. Il était pratiquement impossible de mémoriser l’ensemble des événements d’une pièce.

Pour chaque œuvre, nous réécrivions un système complet comprenant un niveau de lutherie pour l’élaboration des timbres, un niveau de construction d’événements constituant les enveloppes à partir de segments successifs, et un ou plusieurs niveaux macrocompositionnels, pour l’organisation générale. La tâche la plus délicate étant l’écriture du système d’organisation temporelle des événements, permettant de gérer indépendamment plusieurs voix, tout en offrant la possibilité de synchronisation. Lirio MARTINEZ (MARTINEZ 1995), développe actuellement un atelier de composition, d’expérimentation, et d’interprétation de musique informatique basé sur ce synthétiseur, et interfacé avec les machines de type PC sous l’environnementWindows.

Le passage vers des micro-ordinateurs plus puissants (mémoire de l’ordre du mégaoctet, et unité de disque dur), munis d’écran graphiques, et associés à des synthétiseurs externes commandés par des interfaces MIDI nous à fait reconsidérer notre démarche. Les timbres étant élaborés grâce à des applications existantes, et synthétisés par les modules externes, notre programmation pouvait s’abstraire de la gestion de ceux-ci. Les couches de gestion des interfaces MIDI et du temps étant déléguées à une bibliothèque externe[20], nous avons pu construire un modèle de programme plus général, utilisable par plusieurs compositeurs, permettant de gérer des séquences mélodiques, et d’appliquer des traitements sur ces séquences.

 

La base de ce système est le traitement de séquences de hauteurs exprimées en numéro de demi-ton. Nous pouvons créer des séquences de longueurs diverses, les mémoriser, les visualiser simplement sous forme de textes, les copier, et appliquer des transformations telles que la transposition, les inversions (de hauteur ou d’intervalles mélodiques). Nous pouvons également opérer des combinaisons de séquences telles les insertions, la concaténation, ou encore des combinaisons logiques telles que le ou exclusif des hauteurs exprimées sous leur forme binaire. Les séquences peuvent être générées par un algorithme pseudo-aléatoire entre des limites fixées.

 

Le système est organisé en huit voix indépendantes. Chaque voix peut être activée ou désactivée et jouée de façon cyclique ou non.

Chaque voix possède ses propres valeurs des paramètres rythmiques, son propre timbre.

L’interface permet une commande indépendante pour chaque voix, ou bien la commande simultanée de plusieurs voix sélectionnées.

Tous les paramètres de l’interface peuvent être mémorisés dans des registres de configurations. Et l’ensemble des configurations peuvent être sauvegardées dans des fichiers.

 

Les œuvres composées avec ce système (ENGLERT 1992), (MARIETAN 1991) nécessitent une préparation des configurations et des séquences, puis lors de l’exécution, une partition indique à l’interprète les opérations à effectuer.

Toutes les opérations de traitement peuvent être effectuées pendant l’activité du système. Certaines opérations, telles que les mutations d’une séquence vers une autre n’opèrent que pendant l’exécution de la séquence.

 

Nous exposerons en particulier le système rythmique et dynamique que nous avons développé pour ce séquenceur. En effet, les séquenceurs existants (YAVELOW 1992) mémorisent des séquences contenant pour chaque événement (ou note) non seulement la hauteur de la note, mais également d’autres données. La durée et l’intensité sont les deux principales. Notre séquenceur génère automatiquement les durées et les intensités d’après un algorithme que nous détaillerons dans le paragraphe Algorithme rythmique & dynamique de métro3.

 

Les générateurs obtenus par l’utilisation du module Métronome et le développement d’algorithmes spécifiques permettent la commande de synthétiseurs en temps réel (ou synthèse mixte). Mais certaines compositions utilisant des instruments traditionnels, nécessitent l’écriture de partitions classiques. Dans le paragraphe suivant, nous introduisons CHNRNG14, un générateur de partitions pour orchestre.

 

1.8.     Un générateur de partitions pour piano et orchestre

 

Nous avons conçu et réalisé, avec la collaboration de Giuseppe G. ENGLERT, un système capable de produire l’ensemble du matériel d’orchestre[21] et les partitions pour le piano d’une pièce : CHACONES, pour orchestre et piano concertant.


     Figure 1.12


 

La page précédente (Figure 1.12) est le premier système de la première page de la partition de piano de CHACONES. L’impression est réduite à 80%.

 

Le module d’impression est spécialisé de manière à contrôler finement toutes les caractéristiques graphiques des partitions. Il eut été possible en effet de se consacrer uniquement sur l’aspect génératif de la pièce, et de déléguer l’impression à des éditeurs de partition externes (BELKIN 1994) en utilisant un format standard tel que les fichiers MIDI (MIDI 1989), ou des formats plus complets, spécialisés pour les partitions et intégrant les articulations, mais notre but était d’assurer l’intégralité de la composition et de la mise en page automatiquement, pour éviter toute intervention manuelle.

Globalement, la forme interne que produit le module générateur de la pièce est un ensemble de chaînages d’événements, sonores ou silencieux, ordonnés chronologiquement et répartis selon des pistes.

Les pistes correspondent pour la partition d’orchestre à des portées, et pour les parties séparées à des instruments. Elles peuvent toutefois changer d’instrument dans la partition d’orchestre, et pour la partition de piano, la répartition des notes sur les portées est déterminée uniquement par leur hauteur, les pistes ne représentent alors que la possibilité harmonique de l’instrument.

 

Le module d’impression permet la visualisation sous plusieurs formes de cette structure interne. Son rôle est de calculer les signes graphiques qui doivent apparaître sur une page (ou sur une section de page) du matériel d’orchestre.



 

Ci-dessus (Figure 1.13), une page de la partie de la première flûte. Réduction 75%.

 

La composition, œuvre de Giuseppe ENGLERT, réalisée par le module générateur, est basée sur une structure verticale, constituée d’une suite de 14 accords, qui subit les 52 périodes d’un algorithme de permutation avant de retrouver l’ordre initial. La partie de piano et la partie d’orchestre utilisent la même séquence de 52 périodes mais dans l’ordre inverse. Les modules de génération de la partie d’orchestre et de la partie de piano sont séparés et indépendants.

L’algorithme utilise des générateurs pseudo-aléatoires pour effectuer des choix, mais les graines[22] sont initialisées de manière à générer toujours la même pièce. Le contrôle de l’algorithme s’étend sur les hauteurs, les durées des notes et également sur les articulations (trémolo, vibrato, staccato, etc...) mais n’englobe pas la dynamique, qui est fixée par l’auteur après l’impression finale du résultat, et d’après une écoute mentale du produit de la synthèse.

Les articulations sont visualisées par la forme des têtes des notes, ou par des signes suivant la note ou encore pour les trémolos, par des barres obliques sur les hampes des notes.

 

Nous avons particulièrement travaillé sur la simplicité et la lisibilité de la partition d’orchestre[23]. D’après BYRD (BYRD 1994), l’écriture musicale est beaucoup plus complexe que l’écriture Chinoise. Cette complexité s’explique, malgré le nombre restreint de symboles, par le nombre de contraintes, de liaisons et de règles d’écritures. BYRD donne des exemples de partitions classiques (telles les Variations GOLDBERG de J.S.BACH) enfreignant les règles habituelles, mais qui sont tout à fait lisibles par les instrumentistes.

 

Figure 1.14 : Extrait de CHACONES

 

Voici un extrait (figure 1.14) de la partition avec dans la portée supérieure, les deux voix de flûte, et dans la portée inférieure les deux voix de hautbois. Chaque instrument est distingué par l’orientation des hampes des notes, et la position des silences. L’alignement vertical des signes correspond en principe à une synchronicité des événements sonores, mais cette règle peut être contrariée par des déplacements imposés pour la lisibilité des altérations ou la proximité des notes : le troisième temps de la portée inférieure est à gauche du troisième temps de la portée supérieure, à cause des densités différentes. Nous avons utilisé des couplages élastiques pour effectuer la mise en page horizontale des éléments graphiques apparaissant dans chaque mesure.

 

La pièce doit pouvoir être préparée avec peu de répétitions d’orchestre. Par contre, la partie de piano est soumise au soliste longtemps à l’avance et le travail d’interprétation peut être plus important.

Ci-dessus (figure 1.15) un extrait de la partition d’orchestre de CHACONES (premier groupe d’instruments) neuvième période. Réduction 75%. Une page de la partition complète représente 5 fois cette hauteur (25 portées).

 

Notre système intègre également la possibilité de jouer la pièce par groupe d’instruments, mais cette fonctionnalité, écrite dans un but de contrôle, n’a pratiquement pas été utilisée. Nous présentons dans le chapitre Générateurs de partitions, les méthodes développées pour traiter les problèmes sensibles de la mise en page, et nous montrons l’utilisation de couplages élastiques reliant les éléments graphiques.

Nous détaillerons ensuite l’algorithme de génération d’une pièce pour piano seul, utilisant le même module d’impression, et dont la base de la génération repose sur des couplages élastiques reliant une représentation virtuelle des mains du pianiste.

Nous exposerons enfin notre travail portant sur un algorithme de génération de monodies pour violon dont le principe nous a été inspiré par l’observation de propriétés des airs de danse Irlandais; et une adaptation de ce générateur à la contrebasse pour une pièce mixte intégrant les phonogrammes et la contrebasse.

 

1.9.     Conversions

 

Nous manipulons l’information musicale et sonore sous différentes formes :

• Les signaux sous forme de fichiers ou tables d'échantillons.

• Les phonogrammes.

• Les codes MIDI.

• Les images sous forme de bitmaps ou pixmaps.

• Les partitions.

Nous ajoutons à cette liste les éléments suivants :

• Les trajectoires élastiques.

• Les réseaux élastiques, et bancs de résonateurs.

Qui ne représentent pas directement de l’information sonore mais peuvent la produire ou la transformer.

 

Notre atelier permet des passages entre des systèmes de représentation qui étaient autrefois séparés. L’avantage des possibilités de conversion est évidemment la richesse et la multiplicité des traitements que l’on pourra appliquer sur les sons. Nous offrons ainsi un large choix de nouvelles possibilités pour les compositeurs, en ouvrant la possibilité d’utiliser toutes les fonctions de traitement des images pour la transformation du son.


 

Nous résumons dans la table ci-dessous les conversions possibles ou les concepts apparaissant à la jonction entre ses éléments pris deux à deux.

Les cellules de la table revoient chacune à un ou plusieurs paragraphes.

 

 

Signal

Phono-gramme

MIDI

Bitmap

Réseau

élastique

Trajectoire

Partition

Signal

Traite-ment du signal.

Accès disque, flux et flux AIFF

FT. FFT

 

Transfor-mée élastique d'un signal par un banc de résona-teurs

 

Analyse acousti-que directe

 

Visuali-sation du signal

Généra-tion d’un réseau élastique à partir d’un signal

 

 

Phonogramme

Synthèse additive

Édition palette d'outils graphi-ques

 

Conver-sion des phono-grammes vers la norme MIDI

Exécution temps réel des phono-grammes

Généra-tion de fichiers MIDI

Conver-sion vectoriel-le/bit-map

Conver-sion de phonogrammes en réseaux élastique

Convers-ion de phono-grammes vers des trajectoi-res

Produc-tion de parti-tions à partir de phono-grammes

MIDI

Liaison avec un synthéti-seur externe

Enregis-trement MIDI

Traite-ments MIDI

 

Stimula-tion des bancs de résona-teurs par des flux MIDI

 

Éditeurs de parti-tions

Bitmap

 

Conver-sion bitmap vers Phono-gramme, vectori-sation

 

Traite-ment numéri-que d'images

 

 

 

Réseau

élastique

Produc-tion de signal par bancs de résona-teurs.

Filtrage d'un signal par bancs de résona-teurs

Transfor-mée élastique.

Réseau - MIDI

Représen-tation graphi-que du réseau

Édition de réseaux

Généra-tion de trajectoi-res à partir de réseaux de couplages

Composi-tion utilisant les résona-teurs (mouve-ments des mains)

trajectoi-res

Parcours du mobile le long de la trajectoi-re en évolution

 

 

Représen-tation graphi-que de la trajectoi-re

Conver-sion des trajectoi-res en réseaux élasti-ques circulai-res

 

 

Partition

Exécution de parti-tions par un instru-mentiste

Conver-sion de parti-tions en phono-grammes

 

Lecture automa-tique de parti-tions musicales

Par exécution dans un éditeur de partition classique

Forme graphi-que de la partition

 

 

 

 

Signal

Phono-gramme

MIDI

Bitmap

Réseau

élastique

Trajectoire

Partition

 

 


2.         Représentation graphique des sons

 

De très nombreux auteurs dans le domaine de l’informatique musicale utilisent des représentations graphiques des sons ou des structures musicales. L’utilité de ces représentations, au delà d’une simple illustration (il est difficile de transmettre un son sur du papier), est parfois liée au processus même de l’élaboration des sons. On parle alors de synthèse graphique des sons (ROADS 1995). L’UPIC[24] de XENAKIS en est l’exemple le plus net. Son système permet de créer les sons à partir d’images composées d’arcs dans l’espace fréquence/temps (XENAKIS 1971). Le système UPIC actuel nécessite un matériel dédié pour réaliser la synthèse sonore.

GOGINS (GOGINS 1991) utilise les fonctions itérées (IFS Iterated Fonctions Systems) (BARNSLEY 1989) qui sont habituellement utilisées pour la création d’images (ou leur compression) pour générer des structures musicales. Nous avons également et indépendamment utilisé des fractales pour générer des sons. Dans ces expériences, des fractales générées par Harald WERTZ (WERTZ 1994) ont été directement intégrées dans des phonogrammes. À la différence du système de GOGINS, les notes n’étaient pas limitées aux seules notes de la gamme chromatique, mais étaient prises dans l’échelle microtonale des phonogrammes[25]. Nous pensons que ces fractales doivent être expressément conçues en vue de la synthèse pour obtenir des résultats sonores intéressants. En effet, les fractales que nous avons utilisées étaient destinées principalement à séduire l’œil et leur utilisation en tant que phonogrammes peut déboucher sur des résultats sonores très divers selon les choix des paramètres d’exécution tels que la vitesse, ou la position et l’échelle[26] de l’image.

 

CORDIS-ANIMA (CADOZ 1993, 1994) est un système utilisant la simulation de modèles physiques pour produire les images, le son, et des effets tactiles. L’image est ici au même niveau que le son, un élément perceptible du modèle simulé dans le système. Dans notre simulation de couplages élastiques et de ressorts, nous avons également la visualisation et la sonorisation d’un modèle, l’image n’est alors plus directement liée au son, elle permet d’aider à la construction du modèle produisant le son.

 

Daniel ARFIB (ARFIB 1993) utilise des représentations formées de deux images, une pour visualiser l’amplitude (sonogramme) et l’autre pour visualiser la phase (phasogramme) en fonction des fréquences par rapport au temps.

Les sonogrammes sont utilisés par SCHOTTSTAEDT en tant que traduction graphique des événements décrits dans le langage Pla (SCHOTTSTAEDT 1983). L’épaisseur des lignes correspondant à l’amplitude, il est impossible alors d’utiliser l’image pour reconstruire un son.

 

2.1.      Principe des phonogrammes

 

Les phonogrammes sont des graphes plans dont la dimension horizontale représente le temps et la dimension verticale représente les hauteurs des sons. Un trait horizontal dans ce graphe représente un son de fréquence fixe, plusieurs traits superposés représentent un accord. Toute image peut se décomposer en une juxtaposition de traits horizontaux et être interprétée comme un phonogramme.

L’implémentation des phonogrammes est conditionnée par le double but de représentation de sons et d’images. La structure des phonogrammes est proche des structures musicales telles les notes (événements possédant une amplitude, une durée, un instant de départ et une hauteur) et est directement exploitable en tant qu’image (les segments horizontaux les constituant possèdent leur valeur de gris et leurs coordonnées).

 

Afin d’expliquer le principe physique utilisé dans les phonogrammes, nous donnons en annexe un rappel de notions acoustiques (Dimensions Physiques des sons)

 

2.1.1.         Échelle microtonale des phonogrammes

 

Dans les phonogrammes, nous utilisons une gamme tempérée microtonale, décomposant chaque demi-ton en 16 parties égales, décomposant ainsi l'octave en 12 x 16 = 192 intervalles.

 

Chaque ligne horizontale du phonogramme représente une fréquence.

 

 

   où pitch  est le numéro de la ligne (position verticale)

 et 69 est le numéro du demi-ton correspondant à la note “la” 440.0 Hertz en notation MIDI.

12 est le nombre de demi-tons dans une octave.

et 16 est le nombre d'intervalles de notre échelle correspondant à un demi-ton.

 

Pour construire le signal sous la forme amplitude/temps à partir d'un phonogramme, nous effectuons une synthèse additive dont les composants ne sont pas en rapport harmoniques.

Le signal s(t) est une somme de sinus, chaque terme étant pondéré par un coefficient d’amplitude Ai(t) :

 

s(t) = A0(t) . sin ( w0 t + F0 ) + ... + An(t) . sin (wn t + Fn )

 

La fréquence angulaire, wi, de chaque terme peut s’écrire :

 

wi = 2πfi            

 

Où la fréquence fi, se calcule à partir de la fréquence la plus grave, f0, correspondant à la fréquence de la première ligne, par le produit avec une puissance entière de e :

 

fi  = f0 . e i

 

e correspond au pas de l’échelle microtonale utilisée (192 intervalles égaux dans une octave) :

 

e = 2 (1/192)

 

Les amplitudes Ai(t) sont fonction du temps pour rendre compte des enveloppes et de l'évolution du son au cours du temps. Elles sont représentées par les valeurs de gris des pixels du phonogramme.

La fréquence f0 est celle de la première ligne. les fréquences fi sont en progression géométrique, alors que les fréquences de la série de Fourier étaient en progression arithmétique.

 

Voici un exemple de signal (figure 2.1), produit à partir d’un rectangle dans un phonogramme. Le rectangle est composé de lignes couvrant les fréquences de 680 Hertz à 800 Hertz en allant par seizième de demi-ton. Les amplitudes sont constantes et égales. Toutes les phases Fi sont fixées à 0 au début.

 

 

Figure 2.1 : Signal produit à partir d’un rectangle dans un phonogramme.

(exemple sonore RectangleGrisPhase.AIFF)

 

Dans la vue globale, ci-dessus, des pics d’amplitude apparaissent régulièrement. Les pics sont séparés de 370 millisecondes (fréquence 2,7 Hertz).

Dans la vue de détail, ci-dessous, nous voyons nettement la variation d’amplitude : un phénomène de battement apparaît lorsque toutes les phases sont égales.

 

Figure 2.2 : Détail du signal de la figure 2.1

 

Dans l’exemple suivant, obtenu à partir du même phonogramme, les phases Fi sont fixées aléatoirement au début du processus, indépendamment pour chaque ligne.

 

 

Figure 2.3 : Signal produit par un rectangle, avec déphasage aléatoire.

(exemple sonore RectangleGris.AIFF)

 

Figure 2.4 : Détail du signal de la figure 2.3

 

Avec les phases aléatoires (figure 2.3 et 2.4), l’enveloppe est plus régulière, et l’effet des battements est nettement moins perceptible. Les battements sont toujours présents, mais l’importance relative des pics les plus élevés par rapport à l’amplitude moyenne est plus faible.

 

2.2.      Représentation interne des phonogrammes

 

Nous traitons deux types de phonogrammes : les phonogrammes en noir et blanc, et les phonogrammes en niveaux de gris.

Nous détaillons maintenant différentes implémentations des structures supportant la mémorisation, le rappel, et la modification des phonogrammes.

 

2.2.1.         Dissection des images

 

Nous sommes familiers avec la décomposition des images en pixels[27] et la méthode de représentation d'une image[28], par un système de table :

En noir et blanc, chaque bit d'une zone mémoire contient l'information pour un pixel, avec une convention associant le noir à la valeur 1 et le blanc à la valeur zéro (ou la convention inverse).

La zone mémoire contiguë est déroulée de gauche à droite et ligne à ligne sur l'image. La mémoire, pour des raisons techniques[29], est préférentiellement découpée en mots (paquets de 8, 16, 32 bits), Lorsque la largeur de l'image n'est pas un multiple de la taille du mot, quelques bits sont ignorés à chaque fin de ligne, de manière à recommencer une nouvelle ligne au début d'un mot.

À l'intérieur d'un mot, ont peut utiliser les bits, du poids faible au poids fort, pour ranger les pixels, soit de gauche à droite, soit de droite à gauche.

Cette mémoire d'image est nommée bitmap.

 

Exemple d'accès en lecture à un pixel de l'image :

 

Image(x, y) =

(bitmap [ ((largeur + M - 1)//M)*y + x//M ] >> (x%M)) & 1

 

où M est le nombre de bits du mot, et largeur la largeur de l'image en nombre de pixels, // la division entière, % le reste de la division entière, & l'opération et logique (pour extraire le bit après l'opération de décalage des bits >>). La formule ((largeur + M - 1)//M) donne le nombre de mots par ligne.

 

Lorsque plus d'un bit par pixel est nécessaire pour encoder l’information de couleur, deux solutions se présentent : soit on forme autant de bitmaps (ayant la structure précédemment décrite) qu'il faut de bits par pixel (structure par plans de bits), soit on encode chaque pixels par le nombre de mots nécessaires (et on juxtapose les pixels). C'est cette seconde solution qui est la plus fréquemment retenue (l’information concernant un pixel n’est pas dispersée).

 

Nous allons maintenant voir les images d'une tout autre manière : à la loupe, l'image apparaît comme une collection (ordonnée et indéxée) de lignes. Chaque ligne de l'image est une entité indépendante des autres lignes (quelque soit l'image représentée). Disséquons une ligne à présent : au microscope, elle nous apparaît comme une succession de couleurs, mais souvent (en particulier dans les images en noir et blanc), la même couleur apparaît plusieurs fois de suite. Nous formerons donc une ligne en enchaînant des segments monochromes. Les lignes blanches ne contiennent aucun segment. En sélectionnant un meilleur grossissement sur notre microscope, nous discernons les composants d'un segment : l'abscisse de départ, l'abscisse de fin du segment, et (si l'image n'est pas uniquement noire et blanche) l'information donnant la couleur du segment.

Avec la lentille C (un filtre sur le microscope), la ligne est une structure donnant le nombre de segments alloués, le nombre de segments actifs, et un pointeur vers une table de structures segment. Les structures segment  comprennent les champs x1, x2 pour mémoriser les abscisses de début et de fin du segment, et un champ pour mémoriser sa couleur.

Avec une lentille Smalltalk (GOLDBERG, ROBSON 1989) (LESBROS 1989), la classe Ligne possède une variable d'instance segment, (pour chaque ligne, la variable segment pointe vers le premier segment de la ligne). La classe Segment a ses variables d'instance x1 et x2 pour les abscisses et des variables suivant et précédant, pour indiquer les segments voisins dans la même ligne. Une sous classe SegmentColoré possède en outre l'information de couleur.

Les opérations à effectuer sur les images peuvent se décomposer en des opérations à appliquer sur des lignes.

Les opérations sur les lignes se résument à trois primitives :

• Copier tout ou partie d’une ligne.

• Intégrer un segment dans une ligne.

• Effacer un segment d’une ligne.

 

La copie d’une ligne est nécessaire pour assurer la possibilité d’annuler l’effet de toute action sur un phonogramme. Par exemple, quand on donne un coup de pinceau, on intègre de nouveaux segments dans le phonogramme, nous souhaitons permettre d’annuler le coup de pinceau (et pouvoir agir de même pour toute opération modifiant un phonogramme). Avant l’intégration d’un segment dans une ligne, ou avant l’effacement d’un segment, nous mémorisons une copie de la ligne (si elle n’est pas déjà copiée). Lors de l’annulation, nous permutons les lignes mémorisées avec les lignes actuelles. Ainsi, deux annulations successives restaurent l’état modifié. Avant chaque action considérée comme unitaire, nous libérons l’espace occupé par les copies.

 

 

2.2.2.         Algorithme d’intégration d’un segment

 

La figure ci-dessous indique les treize positions relatives que peuvent prendre deux segments en considérant leurs bornes : nous devons distinguer les cas ou les bornes sont inférieures, égales ou supérieures. Le segment délimité par x1 et x2 en haut de la figure représente un segment existant dans le phonogramme, et les 13 positions représentent les positions d’un segment à intégrer ou à effacer.

 

Figure 2.5 : Positions relatives de deux segments

 

L’algorithme d’intégration n’est pas le même en noir et blanc et en niveaux de gris. En effet, la position 3 par exemple provoquera un allongement du segment à gauche en noir et blanc ou lorsque les niveaux de gris des deux segments sont égaux, alors qu’avec des niveaux de gris différents, le segment sera raccourci à gauche et un nouveau segment sera inséré. De même, dans la position 9, l’intégration en noir et blanc est immédiate, il n’y a pas de modification, alors que lorsque les niveaux de gris sont différents, le segment initial sera remplacé par trois segments adjacents.

 

Notons z1 et z2 les coordonnées du segment à intégrer.

 

La comparaison de la borne z1 avec x1 et x2 crée cinq cas :

a/ (z1 < x1) positions 1, 2, 3, 4, et 5

b/ (z1 = x2) positions 6, 7 et 8.

c/ (z1 > x1) et (z1 < x2) positions 9, 10 et 11.

d/ (z1 = x2) position 12.

e/ (z1 > x2) position 13.

 

La comparaison de la borne z2 avec x1 et x2 détermine (avec les cas précédents) la position du segment.

On traite les segments existants dans la ligne de gauche à droite. S’il n’y a pas de segment, ou si on doit continuer l’intégration à droite avec le segment suivant (positions 5, 8, 11, 12 et 13) et qu’il n’y a pas de segment suivant, on crée un nouveau segment.

Le terme insérer signifie créer un nouveau segment avant le segment courant. et le terme ajouter signifie créer un nouveau segment après le segment courant.

Le terme remplacer signifie que l’on conserve le segment et son niveau de gris, mais que l’on change une de ses bornes.

Lorsqu’on change le niveau de gris du segment dont la borne supérieure est égale à x2, (positions 4, 7, et 10), nous devons vérifier le niveau de gris du segment suivant : Si le niveau de gris est différent ou s’il n’y a pas de segment suivant, la vérification s’arrête. Si le niveau de gris est égal, le segment suivant doit être supprimé et le segment courant remplacé avec la borne supérieure du segment suivant, puis, la vérification se poursuit tant que le segment suivant est adjacent (x1 du suivant = x2 du segment).

Dans l’algorithme ci-dessous, les cas notés n&b signifient que le niveau de gris du segment à insérer est égal au niveau du segment courant, ou que le phonogramme est en noir et blanc. Le cas gris est à appliquer dans les autres cas.

 

1 : (z2 < x1)

   insérer (z1, z2) avant (x1, x2)

2 : (z2 = x1)

              n&b : remplacer (x1, x2) par (z1, x2)

               gris : insérer (z1, z2) avant (x1, x2)

3 : (z2 > x1) et (z2 < x2)

               n&b : remplacer (x1, x2) par (z1, x2)

              gris :  remplacer (x1, x2) par (z2, x2), insérer (z1, z2) avant (z2, x2)

4 : (z2 = x2)

              n&b : remplacer (x1, x2) par (z1, x2)

               gris : remplacer (x1, x2) par (z1, x2)

                          donner un nouveau niveau de gris.

                          vérification du niveau de gris à droite.

5 : (z2 > x2)

              supprimer le segment (x1, x2)

              continuer l’intégration avec le segment suivant à droite.

6 : (z2 < x2)

              n&b : néant

              gris : remplacer (x1, x2) par (z2, x2), insérer (z1, z2) avant (z2, x2)

7 : (z2 = x2)

              n&b : néant

              gris : donner un nouveau niveau de gris

                          vérification du niveau de gris à droite.

8 : (z2 > x2)

              position traitée comme la position 5

9 : (z2 < x2)

              n&b : néant

              gris : insérer (x1, z1) avec le niveau de gris de (x1, x2),

                          insérer (z1, z2),

                          remplacer (x1, x2) par (z2, x2).

10 : (z2 = x2)

              n&b : néant

              gris : remplacer (x1, x2) par (x1, z1), ajouter (z1, z2)

                          vérification du niveau de gris à droite.

11 : (z2 > x2)

              n&b : supprimer le segment (x1, x2)

                          remplacer z1 par x1

                          continuer l’intégration avec le segment suivant à droite.

              gris : remplacer (x1, x2) par (x1, z1)

                          continuer l’intégration avec le segment suivant à droite.

12 : (z2 = x2)

              n&b : traitement identique à 11.

              gris : continuer l’intégration avec le segment suivant à droite.

13 : (z2 > x2)

              continuer l’intégration avec le segment suivant à droite.

 

Les treize configurations[30] ci-dessus sont décrites dans l’article de ALLEN (ALLEN 1983) et citées dans (BARBAR 1995), elles portent sept dénominations :

Cas 1 : Z before X, cas 13 : X before Z

Cas 2 : Z meets X, cas 12 : X meets Z

Cas 3 : Z overlaps X, cas 11 : X overlaps Z

Cas 4 : X finishes Z, cas 10 : Z finishes X

Cas 5 : X during Z, cas 9 : Z during X

Cas 6 : Z starts X, cas 8 : X starts Z,

Cas 7 : Z equal X

 

2.2.3.         Vectorisation

 

L’intégration d’une image bitmap externe dans un phonogramme constitue une étape de vectorisation de l’image. En effet, notre représentation est intermédiaire entre les images bitmap et les images vectorielles. Les images vectorielles sont constituées d’une liste d’ordres d’appels de primitives graphiques avec leurs paramètres (par exemple tracé d’un cercle dont le centre est à telles coordonnées et de rayon tant, tracé d’un segment de droite de tel point à tel autre, tracé d’un rectangle ou d’un polygone). C’est cette représentation qui est utilisée dans les fichiers et images au format PICT[31] (Apple 1985).

Dans notre représentation l’image est vue comme une liste d’instruction de tracé de droites horizontales (ou de rectangles suivant l’échelle de visualisation).

 

Voici un exemple d’image vectorielle (figure 2.6), les éléments constitutifs de cette image sont indépendants, et peuvent être individuellement modifiés.

 

Figure 2.6

 

La réduction de cette image vectorielle produit ceci (figure 2.7) :

 

Figure 2.7

 

L’exemple de texte est remis en forme (par le programme) pour occuper moins de place, mais la fonte et le corps des caractères ont été conservés, toutes les entités constituantes sont tracées avec de nouvelles coordonnées. Les épaisseurs des lignes sont toujours d’un pixel.

En traduisant l’image en bitmap, puis en appliquant une réduction de l’image bitmap, certaines lignes ou points disparaissent (figure 2.8).

 

Figure 2.8

 

En traduisant l’image bitmap initiale en phonogramme, puis en réduisant le phonogramme, nous ne perdons pas de lignes ni de points (figure 2.9). Les éléments ne sont plus des cercles ni des rectangles ni du texte, mais des segments de droites horizontaux.

Les lignes verticales sont constituées de lignes horizontales juxtaposées. Les lignes horizontales (à gauche dans l’image) se placent sur le pixel le plus proche de leur position théorique. Toutes les lignes sont présentes. Le texte a été traité de la même façon et est réduit, à cette échelle. Il reste alors lisible.

 

Figure 2.9

 

En grossissant l’image provenant du phonogramme (figure 2.10), les segments de droites sont traduits automatiquement en rectangles sans autre perte d’information que l’identité de la structure initiale (les entités cercles, rectangle, etc.).

 

Figure 2.10

 

L’opération de conversion des bitmaps en phonogrammes est finalement une vectorisation simple, puisque, une fois la conversion faite, l’image complète est représentée par des segments de droites. Mais il n’y a évidemment aucune reconnaissance de formes géométriques. La traduction est triviale.

Lors de la visualisation, nous bénéficions tout de même de l’avantage de pouvoir afficher et modifier les phonogrammes à toutes les échelles (figure 2.11 et 2.12). En grossissant, chaque segment est représenté par un rectangle.

 

Figure 2.11 Échelle 1

 

Figure 2.12 : Échelle 5

 

 

2.2.4.         Conversion vectorielle/bitmap

 

La conversion vectorielle/bitmap est immédiatement réalisée par la bibliothèque graphique. Il suffit d’allouer un espace mémoire suffisant pour l’image en fonction de sa taille et de sa résolution, puis de bâtir un contexte graphique portant sur cette mémoire. Ensuite, toutes les opérations graphiques de la bibliothèque seront effectuées dans cette image au lieu d’être effectuées dans la mémoire vidéo.

Un principe similaire est utilisé pour générer les images au format PICT, telles que celles transmises dans le presse-papiers du Macintosh. En ouvrant un contexte graphique portant sur une mémoire représentant une image vectorielle (Picture), les opérations graphiques sont enregistrées en séquence dans cette image. Pour les images dépassant 32 Ko il est souhaitable de rediriger le vecteur[32] correspondant à l’écriture dans la mémoire de l’image pour écrire dans un fichier.

 

La possibilité de convertir des phonogrammes en bitmaps donne accès à toutes les possibilités offertes par les logiciels de traitement d’image.

 

2.2.4.1.      Traitement numérique d'images

 

Nous laissons la grande partie des traitements numériques des images aux applications externes, avec lesquelles nous pouvons toutefois communiquer. Le presse-papiers du Macintosh permet de transmettre des images vectorielles et bitmaps d’une application à l’autre. Nous pouvons également lire un format d’image standard (PICT). Le seul traitement que nous effectuons localement est la modification de valeur des phonogrammes en niveau de gris, ce qui correspond à une opération courante musicalement : la modification de la dynamique. Les opérations de copie et mixage de deux images sont également effectuées localement, mais ce ne sont pas véritablement des traitements d’images.

Mis à part les transformations spatiales des images, telles la sphérisation, les homotéties...., nous utilisons fréquemment une transformation proposée par le logiciel PHOTOSHOP : la facétisation : elle agit en fabriquant une mosaïque de facettes unicolores de formes diverses reproduisant globalement les intensités lumineuses de l’image originale.

Nous utilisons ce filtre pour simplifier les images produites par l’analyse de sons, ou pour simplifier les images provenant de digitalisation en niveaux de gris. La simplification obtenue étant la réduction du nombre de segments des phonogrammes pour un résultat globalement équivalent.

 

Figure 2.13

 

A gauche (figure 2.13), l’image originale, et à droite, l’image facétisée.

 

Si les traitements graphiques standard sont laissés aux soins d’autres applications, nous avons ressenti rapidement le besoin d’intégrer des outils graphiques correspondants à des opérations dans l’espace sonore, ou à des facilités pour construire des éléments sonores. Ces outils sont décrits dans le paragraphe suivant.

 

          

Figure 2.14 : Facétisation d’un son (Échelle 1 et 5)

 

2.3.      Outils graphiques spécialisés

 

Les premières expériences avec phonogramme ont été réalisées en dessinant les phonogrammes à la main, en utilisant des crayons, stylos, des plumes et de l’encre de chine. Les dessins sont digitalisés, puis intégrés dans les phonogrammes. Avec une résolution de 240 points par pouce, l’échelle des hauteurs complète tient dans la petite dimension d’un format A4, et nous avons à peu près une octave pour deux centimètres[33].

 

Figure 2.15 : Phonogramme (extrait de Phonographiques) réduit à 20% de la taille originale.

 

Les lignes tracées à la main ne sont pas rigoureuses, et il est délicat de tracer des lignes exactement en rapport harmonique par exemple ou encore à une distance verticale constante l’une de l’autre. Ceci est important pour que les sons produits se recomposent en un timbre. Si plusieurs lignes se superposent, sans conserver des écarts constants, plusieurs sons distincts sont perçus. Si a contrario, les lignes superposées conservent des écarts constants, un son complexe unique est perçu.

 

Figure 2.16 : Phonogramme (extrait de Phonographiques).

 

Pour tracer manuellement des lignes espacées d’écarts arbitraires ou correspondant aux distances entre les harmoniques, nous nous sommes inspiré des plumes utilisées pour tracer les portées des partitions. Ces plumes sont en forme de griffes et laissent cinq traces parallèles en un seul mouvement. Nous avons découpé des plumes diverses dans du carton (figure 2.17) en ménageant des pointes correspondant à chaque partiel du son à dessiner.

 

Figure 2.17 : Une plume en carton

 

Figure 2.18 : Détail d’une trace de plume en carton (les lignes sont pratiquement parallèles et l’épaisseur varie selon la pression).

 

Ce qui importe ici (figure 2.18) n’est pas le parallélisme des traits, mais la conservation des écarts verticaux entre les traits, les écart verticaux correspondant aux intervalles entre les sons.

 

Figure 2.19 : Phonogramme (extrait de Phonographiques) dessiné uniquement avec des plumes en carton.

 

Les traits laissés par les plumes en carton forment des accords ou des sons harmoniques, suivant les écarts. Les traits sont plus ou moins épais. Pour permettre de réaliser de tels tracés directement à l’écran, et en contrôlant exactement l’épaisseur et les écarts entre les traits, nous avons implémenté un pinceau à harmoniques.

 

2.3.1.         Pinceau à harmoniques

 

Le pinceau à harmoniques permet de tracer automatiquement les harmoniques en traçant uniquement le fondamental. Dans la procédure intégrant un rectangle à un phonogramme, nous adjoignons deux paramètres donnant le nombre d’harmoniques à tracer et un mode de calcul de l’amplitude relative des partiels.

Les partiels peuvent avoir soit la même intensité que le son fondamental, soit l’intensité du fondamental divisé par le rang du partiel, soit encore l’intensité du fondamental divisé par le rang du partiel si le rang est impair ou une intensité nulle si le rang est pair.

Ces trois règles de calcul (figure 2.20) ont été choisie arbitrairement pour l’expérience, elles devraient être complétées, ou définissable par l’utilisateur. Par exemple à l’aide d’une courbe donnant l’amplitude relative en fonction du rang. Nous verrons dans la suite que le pinceau à timbres permet de définir des amplitudes relatives différentes ainsi que leur évolution au cours du temps.

Voici des exemples de tracés réalisés avec le pinceau à harmoniques :

 

            

Figure 2.20 : Les trois règles.                                               Figure 2.21 La valeur augmentant.

 

Les traits peuvent être tracés avec une valeur constante, ou augmentant ou diminuant au cours du déplacement (figure 2.21).

Comme l’échelle des fréquences des phonogrammes est logarithmique, l’écart entre les partiels est constant quelque soit le fondamental. Nous précalculons donc une table donnant le nombre de pixels d’écart entre le fondamental et les partiels successifs. Au contraire, dans une échelle linéaire des fréquences (telle celle des sonogrammes), les écarts entre les partiels changent en fonction de la hauteur du son. Dans un phonogramme, nous pouvons copier un son harmonique ou complexe, et le transposer sans changer le rapport des fréquences, par une simple translation verticale.

Les distances inter partiels sont arrondies au seizième de demi-ton le plus proche. Seul le calcul des octaves est correct. Nous produisons donc des harmoniques tempérées au seizième de demi-ton.

Les expériences montrent que les sons produits sont perçus comme des sons uniques, le timbre seul étant affecté. En synthèse mixte, les seize synthétiseurs produisent des sons correspondant à leur échelle chromatique et l’addition des partiels est réalisée de manière analogique par la table de mixage.

 

2.3.2.         Pinceau à timbres

 

Le pinceau à timbres permet d’utiliser un phonogramme en tant que source ou description de timbre pour tracer des sons dans un autre phonogramme.

 

Figure 2.22 : Phonogramme source (l’image source est basée à l’origine, la partie grisée est en dehors du phonogramme).

 

Figure 2.23 : Phonogramme destination.

 

L’image source (figure 2.22) est transférée dans la destination (figure 2.23) à chaque coup de pinceau, elle est déformée pour suivre les mouvements du pinceau.

L’image source peut contenir n’importe quel dessin, mais a priori, nous dessinons dans la source un seul son avec ses partiels, et les variations des partiels dans le temps, en amplitude, en épaisseur, en hauteur.

 

Figure 2.24

 

Voici un exemple (figure 2.24) de phonogramme source, en noir et blanc, nous avons épaissi les partiels correspondants au moment de l’attaque.

 

L’image source est transférée dans la destination colonne par colonne au cours du déplacement du pinceau. Si le pinceau se déplace de plus d’un pixel horizontalement, la colonne de la source est étirée pour atteindre le nombre de pixels correspondant. La colonne de la source subit une translation verticale correspondant à la position verticale du pinceau.

 

Figure 2.25

 

Ci-dessus (figure 2.25), des exemples de tracés du pinceau à timbres avec la source précédente (figure 2.24). Le pinceau peut se déplacer dans toutes les directions, la source sera contrainte à suivre les mouvements de celui-ci (le dernier son à droite est tracé en deux temps, de droite à gauche et de gauche à droite).

Si le déplacement du pinceau est rapide, la source est allongée, et la durée du son résultant sera plus grande.

Les valeurs de gris de la source peuvent être utilisées directement ou être mélangées (moyenne) avec la valeur de gris sélectionnée. Ceci permet d’utiliser la même source en faisant varier les amplitudes.

Nous avons introduit une option permettant de respecter l’échelle de visualisation ou non. C'est-à-dire que la source peut être intégrée dans la destination à la même échelle ou bien à l’échelle de visualisation courante. Ceci permet de grossir ou de réduire l’image source d’un facteur entier.

 

Figure 2.26

(Exemple sonore : harmonique PhonoTrimbre2.AIFF)

 

La figure 2.26 est un exemple de sons différents formés avec une source identique, les sons produits sont perçus comme ayant le même timbre, malgré les variations de durée et de hauteur. Les partiels de ce timbre sont en rapports harmoniques.

 

 

Figure 2.27 (Exemples sonore : non harmonique PhonoTimbres.AIFF)

 

Dans cet exemple (figure 2.27), les sons sont également perçus comme ayant le même timbre, la source est une image où les partiels ne sont pas harmoniques.

 

2.3.3.         Tracé élastique de courbes et de droites

 

Les mouvements de la souris sont difficiles à contrôler, par exemple, pour tracer des courbes ou des droites régulières. Nous avons créé un outil permettant de lisser les tracés effectués à la souris. Cet outil est basé sur l’utilisation des couplages élastiques.

La trace initiale est mémorisée sous la forme d’une liste de points. Puis une tension élastique est appliquée, entre les points consécutifs, comme pour la tension des trajectoires ou des trajets des flèches des schémas. Ensuite, la liste de points est parcourue, une droite est tracée avec le pinceau reliant chaque point de la liste.

Les droites sont tracées en utilisant l’algorithme de BRESENHAM (ROGERS 1988). Chaque point d’une droite représente un coup de pinceau prenant en compte la taille du pinceau, les harmoniques éventuelles, et l’activité des canaux[34]. Différentes règles de tension sont applicables sur le tracé initial et permettent d’obtenir des variations de la qualité du trait, ou de son allure générale.

 

   

a/                                               b/                                           c/                                            d/

Figure 2.28

 

Différentes règles de tension appliquées sur le trait sont présentées ci-dessus (figure 2.28) : la première (a) tend à lisser la courbe, les points du tracé initial sont déplacés dans le sens de la tension calculée d’après ses voisins. La seconde (b) introduit un vecteur supplémentaire dans le calcul de la tension, et ce vecteur effectue une rotation au cour du déplacement au long du trait, ceci produit des boucles si le tracé comporte beaucoup de points, ou des ondulations si le tracé initial est plus tendu, c'est-à-dire effectué plus promptement. La troisième image (c) est formée par l’application d’une règle de tension ajoutant un vecteur constant orienté vers le bas donnant un effet de poids. Enfin, la dernière image (d) est obtenue avec la règle suivante :

En chaque point, les tensions avec le point suivant et le point précédent sont calculées, si une des deux tensions est supérieure à un seuil donné (ou si les deux tensions sont égales au seuil), alors la tension est appliquée normalement c'est-à-dire, en provoquant le déplacement du point d’un pixel dans le sens de la tension, sinon, si l’une des tensions est inférieure au seuil, alors la tension opposée est appliquée. Ceci est calculé indépendamment en x et en y. Cette règle a pour conséquence de favoriser les segments orientés à 45 degrés par rapport aux axes.

 

2.3.4.         Masques pour échelles microtonales

 

La sélection des canaux permet de choisir une échelle des hauteurs dont le pas, compris entre le 32ème de ton et le demi-ton, est une puissance du demi-ton : 1/2, 1/4, 1/8 ou 1/16ème de demi-ton.

Nous avons adjoint un système permettant de masquer les lignes de phonogramme dont le numéro n’appartient pas à une classe résiduelle donnée d’un module donné. Par exemple : nous pouvons masquer toutes les lignes dont le reste de la division par 3 du numéro n’est pas égal à 2. Le module (3) et le reste (2) étant réglables dans l’interface.

Ceci permet d’utiliser tous les outils précédemment décrits, ainsi que toutes les fonctions d’analyse dont la description suit, en contraignant l’écriture dans une échelle microtonale régulière dont le pas est un multiple du seizième de demi-ton. Les masques agissant aussi bien sur les fonctions de dessin que sur la fonction d’effacement, nous pouvons les utiliser pour retrancher les notes appartenant à une échelle donnée d’une image existante.

 

Les outils décrits précédemment aident à construire de nouvelles images ou modifier des images existantes. Pour obtenir des images correspondant aux sons provenant du monde réel, nous avons besoin de fonctions d’analyse du son; pour produire les sons correspondant aux images, nous avons besoin de fonction de synthèse. Nous présentons ces fonctions dans les paragraphes suivants.

 

2.4.      Synthèse et analyse des sons dans Phonogramme

 

Nous présentons une adaptation de la Transformée de Fourier Discrète (TFD) pour la génération d'images de Phonogramme à partir de sons échantillonnés.

 

2.4.1.         Les images de Phonogramme

 

Les images de Phonogramme sont une représentation du son en trois dimensions : Le temps, sur l'axe des x, Les fréquences, sur l'axe des y, et enfin l'amplitude, représentée par des niveaux de gris, ou, simplement l'absence ou la présence d'énergie supérieure à un certain seuil, quand l'image est en noir et blanc.

Cette représentation est proche d'un sonogramme, mais, d'une part elle ne contient pas l'information de phase obtenue lors de l'analyse d'un son par une transformée de Fourier, et d'autre part, l'échelle des fréquences habituellement linéaire a été choisie logarithmique pour faciliter les correspondances entre les opérations graphiques et leurs contreparties musicales.

L’information de phase a souvent été décrite comme étant secondaire voire non significative (RISSET 1969) quant à la perception des timbres : Si l’on change la phase d’un partiel (ou de plusieurs partiels) lors de la synthèse additive, le son produit est perçu inchangé. Mais, les phases instantanées délivrées par la transformée de Fourier sont de nature différente[35], elles sont nécessaires à la reconstitution exacte du son analysé, comme montrent ARFIB et DELPRAT (ARFIB 1993-95) qui proposent également un système de représentation du son dans l’espace fréquence/temps mais démontrent l’importance de la phase en effectuant des transformations sonores modifiant uniquement les phases.

 

2.4.2.         La synthèse sonore à partir des images

 

Les deux procédés que nous avons élaborés pour faire la synthèse du son à partir de ces images régénèrent des phases arbitraires pour chaque partiel : le procédé temps réel, fonctionnant par commande de modules de synthèse externes ne contrôle pas assez finement le temps (limitation du protocole MIDI), et ne dispose pas de commande permettant de spécifier les phases, et le procédé de synthèse directe, qui propose deux modes de génération des phases : toutes les phases synchronisées à zéro au premier pixel, ou un déphasage aléatoire choisi pour chaque fréquence, puis conservé tout au long du traitement.

 

Cette information de phase n'est pas conservée dans notre représentation car des sons identiques quant aux fréquences des partiels, et synthétisés avec un réglage des phases différent sont perçus comme étant similaires.

Dans certains cas, pourtant, la phase est une information importante, notamment sur les attaques des sons instrumentaux (dans les transitoires). Les effets des variations de phase sont particulièrement sensibles si, par exemple, tous les partiels se voient attribuer une phase différente à un instant précis au cours du son, la perception du timbre est alors modifiée.

Les déphasages aléatoires ont étés introduits dans le procédé de synthèse pour contrecarrer les effets des battements dus à la proximité des fréquences : lorsque tous les partiels sont en phase au départ, les battements provoquent des pics d'amplitude réguliers nettement perceptibles, et d'une grande importance par rapport à l'amplitude moyenne, par contre, avec des phases attribuées au hasard, les conjonctions sont rares, et les pulsations parasites disparaissent.

 

2.4.2.1.          Synthèse additive ou synthèse directe

 

La synthèse additive est la méthode de synthèse nous paraissant la plus primitive, ou fondamentale. Elle est limitée, dans son exploitation informatique, par le nombre d’oscillateurs à simuler pour produire les sons complexes (SNELL 1977), mais elle ne l’est pas, théoriquement, quant aux classes de timbres qu’elle permet de produire. Quand on définit les timbres simplement en termes d’amplitudes relatives de partiels harmoniques, la classe de timbres produite est restreinte aux seuls sons harmoniques et périodiques, mais si les oscillateurs peuvent être commandés par des enveloppes d’amplitudes dynamiques, et que les fréquences ne sont pas limitées aux fréquences harmoniques, toutes les classes de timbres deviennent accessibles. La puissance des ordinateurs augmentant, cette méthode de synthèse devient exploitable avec plus de souplesse. Un système actuel de génération de timbres, SeaWave, utilise la synthèse additive (ETHINGTON 1994) préférentiellement à d’autre méthodes de synthèse telles la synthèse granulaire (ROADS 1978) ou la synthèse par modulation de fréquence (CHOWNING 1973) (CHOWNING 1986) (HOLM 1992). Pour générer les timbres d’orgue, COMERFORD utilise également la synthèse additive. Il compare la synthèse additive avec l’utilisation de banques de sons échantillonnés (COMERFORD 1993) dans le but de la reproduction fidèle de timbres instrumentaux.

 

La synthèse additive décrite ici est la conversion des phonogrammes en signal amplitude/temps. Globalement, l'algorithme est très simple, mais certains détails techniques méritent une description.

À chaque ligne du phonogramme correspond une fréquence particulière, donnée par la formule suivante :

 

  

 

Chaque ligne du phonogramme est composée d'une suite de segments, chaque segment comportant la coordonnée de départ (x1), la coordonnée de fin (x2) et une valeur proportionnelle à l'amplitude pour les phonogrammes en niveaux de gris.

 

phonogramme [ y ] = ligne

ligne = (segment 1, segment 2, ... , segment n)

segment i = { x1, x2, gris } | { x1, x2 }

 

La conversion est effectuée pour une valeur donnée de la vitesse d'interprétation de l'image en millisecondes par pixel. Connaissant également la fréquence d'échantillonnage souhaitée, nous pouvons calculer le nombre d'échantillons correspondant à une colonne de pixels, ainsi que le nombre total d'échantillons à produire pour la section d'image à convertir.

Chaque segment du phonogramme représente un son périodique de durée et d'amplitude déterminés qu'il faut additionner au résultat. Le son doit débuter par une attaque, se maintenir, puis choir. Nous avons choisi une enveloppe la plus simple possible : l'attaque correspond au premier pixel du segment, et la chute débute au dernier pixel et les pentes d'enveloppes sont linéaires. Dans le cas d'un segment représentant un unique pixel, nous avions dans une première implémentation (en noir et blanc) condensé l'attaque et la chute dans la durée du pixel, mais pour simplifier les formes d'enveloppes résultant de l'addition de plusieurs segments mono-pixels consécutifs en niveaux de gris, nous avons opté pour une attaque pendant la durée du pixel suivie par une chute pendant la durée du pixel suivant.

 

Figure 2.29

 

Le schéma ci-dessus (figure 2.29) représente une ligne constituée de trois segments consécutifs (en haut, le premier segment en gris moyen, le second en noir et le troisième en gris clair). En dessous, nous avons tracé les enveloppes de chaque segment, puis l’enveloppe du son résultant de la somme des trois.

 

La forme de l'enveloppe influe sur le son, le timbre est modifié par le choix de la courbe suivie par l'enveloppe d'amplitude. Ceci pour les mêmes raisons que celles qui déterminent les fenêtres des fonctions d'analyse.

Les fréquences parasites apparaissent surtout à la jonction des segments linéaires de l'enveloppe quand l'angle formé est trop fort. En fait, d'après la règle de construction de l'enveloppe décrite ci-dessus, cet angle est déterminé par l'amplitude du segment de phonogramme et la vitesse en millisecondes par pixel. Il ne nous a pas semblé nécessaire, aux vue et ouie des résultats d'affiner ce point.

 

Pour éviter des appels constant à une fonction sinus, il est nécessaire de mémoriser dans une table une période de la fonction (ou un quart de la période en utilisant les symétries). Ceci permet également de changer la période de base sans changer le code.

Le problème principal est de savoir trouver, en fonction du temps, de la fréquence à produire et de la taille de la table d’onde, l’indice de l’échantillon à prendre dans la table.

Par exemple, si la fréquence d’échantillonnage est 22000 Hertz, et que la table d’onde a une longueur de 16000 échantillons, la fréquence produite en recopiant les échantillons de 1 en 1 sera de 22000 / 16000 = 1,375 Hertz. En prenant un échantillon sur 10, nous obtiendrons 13,75 Hertz, etc.

En prenant 1 échantillon sur n, nous obtenons toutes les fréquences harmoniques de la fréquence de la table d’onde. Si n n’est pas un multiple de la longueur de la table, il faut faire comme si la table était circulaire pour éviter les ruptures dans le signal (opération modulo sur l’indice).

Mais les fréquences à produire ne sont pas forcément des harmoniques de la fréquence de la table. Pour produire ces fréquences intermédiaires, il faudrait pouvoir prendre des valeurs entre les échantillons de la table. Une méthode d’interpolation serait envisageable, mais ces calculs nous ont semblés trop lourds. Nous avons préféré construire une approximation du rapport entre la fréquence à reproduire et la fréquence de la table par une fraction, puis écrire un algorithme calculant en entier, utilisant le numérateur et dénominateur de cette fraction ainsi que les propriétés de l’arithmétique modulaire.

 

 

Algorithme de calcul en entier pour trouver les échantillons dans la table d’onde

 

Constantes pour tout le phonogramme :

 length_wave_buffer = 16K (16384 échantillons dans la table d’onde)

 wave_buffer_frequency = sample_rate / length_wave_buffer (valeurs réelles)

 

Pour chaque ligne :

 ratio = line_frequency / wave_buffer_frequency

±= num / den

 (num et den sont des entiers qui approchent la valeur de ratio)

 length_den = length_wave_buffer * den

 

Pour le premier échantillon :

 moduleNum = (sample modulo length_den) * num

 

Pour chaque échantillon suivant :

 value = wave_buffer[(moduleNum / den) modulo length_wave_buffer]

 moduleNum += num

 if(moduleNum == length_den) moduleNum = 0

 

 

L’opération modulo length_wave_buffer  est réalisée par un ET logique car length_wave_buffer  est une puissance de deux.

Ensuite la valeur obtenue est modifiée par le coefficient d’amplitude donné par l’enveloppe, puis elle est ajoutée à la valeur de la mémoire du signal.

Comme les fréquences des lignes de phonogramme sont constantes, nous précalculons la table des fractions. Cette table n’est recalculée que si l’on souhaite désaccorder, en donnant une nouvelle fréquence pour le la[36].

 

Nous avons développé cet algorithme indépendamment des techniques habituelles utilisant l’incrémentation d’un registre de phase par une valeur en correspondance avec la fréquence. La partie haute du registre de phase indexant la table d’onde (SNELL 1977). Notre système demande une division supplémentaire (la division de moduleNum par den) mais donne une approximation de la fréquence plus précise.

 

2.4.2.1.1.               Traitement du signal

 

Les techniques de traitement du signal ne sont pas développées particulièrement dans l'atelier AIME. Les seuls traitements appliqués directement sur les signaux sous la forme échantillonnés sont la mise à l'échelle et la fusion de deux fichiers monophoniques en un fichier stéréophonique. La mise à l’échelle (scaling), permet, par le simple produit de chaque échantillon par un coefficient, de ramener l'amplitude de crête à la valeur maximale autorisée par la définition du format. Cette opération est faite sur fichiers d'échantillons 32 bits produits par l'algorithme de synthèse additive, par la simulation de couplages élastiques, ou par l'exécution d'une trajectoire, pour les ramener au format 16 bits. L'algorithme de synthèse écrit les échantillons sur 32 bits, en mémorisant l'amplitude maximale (en valeur absolue), puis nous effectuons cette opération en lisant et écrivant dans le même fichier. La structure des fichiers d'échantillons le permet, car ils sont composés d'une entête suivie par la séquence d'échantillons. Comme la taille des nouveaux échantillons est plus petite (ou égale dans le pire des cas) à celle des échantillons à lire, le chevauchement entre la position d'écriture et celle de la lecture est impossible[37].

 

Figure 2.30

 

Le fichier est éventuellement tronqué à la fin de l'opération.

Nous utilisons le format AIFF (Audio Interchange File Format) le standard Macintoch pour le stockage des sons échantillonnés. Ceci a l'avantage de permettre les échanges inter-applications, de profiter d'outils standards pour la génération des entêtes des fichiers, de garantir la compatibilité ascendante, et enfin d'utiliser toutes les routines spécialisées du SoundManager qui permettent l'enregistrement (prise de son direct to disk), l'exécution (émission sur la sortie audio), la compression, etc...

Par contre, nous avons dû programmer les routines nécessaires à la lecture de tels fichiers (décodage des entêtes et localisation des blocs de données), de manière à être en mesure d'accéder simplement aux échantillons. Nous ne reconnaissons pas actuellement toutes les possibilités offertes par le standard, mais les plus courantes sont traitées, et en particulier celles que nous générons.

 

2.4.2.1.2.               Visualisation du signal

 

Au cours du travail d'un timbre ou d'un son particulier, la visualisation du signal sous la forme amplitude/temps peut apporter de l’information, nous l'avons utilisée en particulier pour contrôler la production des algorithmes de synthèse. Mais cette visualisation n'est généralement pas très intéressante dans le travail de composition. Elle l'est dans certains cas, pour avoir une vision précise dans le temps d'une partie du signal, ou au contraire pour avoir une vue globale de l'enveloppe (vue en réduction). Par contre elle est imprécise dans la dimension des amplitudes (les amplitudes d'un signal 16 bits varient entre -32768 et 32767 alors que la hauteur de l'écran de visualisation est de l'ordre du millier de pixels).

Les problèmes d'échelle se posent également dans la dimension temporelle. Dès que le signal dépasse le dixième de seconde, l'échelle doit être réduite pour en voir la totalité, et l’on doit choisir entre le détail ou l'ensemble. Cela prend du temps par exemple pour localiser une discontinuité dans le signal (glitch), car elles ne sont visibles qu'à l'échelle 1, tout en produisant un effet sonore nettement perceptible et désagréable.

Nous déléguons la visualisation du signal à d'autres applications qui permettent de surcroît l'édition, quelques manipulations élémentaires, et certains traitements ou analyses avec des techniques standard.

 

2.4.2.1.3.               Accès disque, flux et flux AIFF

 

Les accès disque pour la lecture ou l'écriture des fichiers d'échantillons sont étagés sur trois niveaux :

• Un premier niveau (nommé disque) permet d'encapsuler les appels aux routines standard du Macintosh (pour le choix des fichiers par l'utilisateur, l'ouverture, la fermeture des fichiers, etc...), de manière à être plus facilement portable dans d'autres environnements. Les routines de ce niveau sont utilisées dans d'autres modules accédant aux fichiers.

• Un second niveau (nommé flux) joue un rôle similaire aux Streams de Smalltalk, il gère une mémoire tampon pour limiter les accès disques.

• Le dernier niveau (nommé fluxAIFF) spécialise les flux pour le format AIFF.

 

 

2.4.2.2.          Conversion des phonogrammes vers la norme MIDI

 

Nous proposons deux façons de passer d’un phonogramme vers la norme MIDI :

1/ En exécutant le phonogramme, c’est-à-dire en déclenchant le jeu par l’émission d’un flux MIDI.

2/ En générant un fichier MIDI, ce qui correspond à l’enregistrement du flux MIDI associé à de l’information temporelle.

 

2.4.2.2.1.               Exécution en temps réel des phonogrammes.

 

Chaque segment du phonogramme est traduit en une note : Le début du segment (x1) correspond à l’émission d’un message Note On[38], et la fin du segment (x2) correspond à l’émission d’un message Note Off[39] pour la même hauteur. Ces messages contiennent l’information de canal MIDI sélectionnant un instrument (calculé par l’opération modulo 16 appliquée au numéro de ligne de phonogramme), l’information de hauteur (numéro de demi-ton) étant ici le reste de la division du numéro de ligne par 16, et enfin la vélocité (ou intensité) donnée par le niveau de gris du segment (ou par une variable globale si le phonogramme est en noir et blanc).

 

Pour envoyer les messages MIDI nous utilisons le système de gestion d’événements de MIDIShare (cf. § Interface MIDI, le Système MIDIShare). Les événements de MIDIShare sont des structures typées et datées, contenant toute l’information à transmettre dans le message MIDI. Une note est émise en créant un événement, en renseignant ses champs, puis en appelant la routine d’émission. La date à laquelle l’événement doit physiquement être émis peut être postérieure à la date d’émission logique de l’événement : MIDIShare réorganise automatiquement les événements selon leur date.

Nous pouvons ainsi précalculer tous les messages MIDI correspondant à la section de phonogramme à jouer : c’est la première forme d’exécution. Quelques secondes (ou quelques dixièmes de secondes) sont nécessaires pour préparer et envoyer les événements. Il est impossible alors d’arrêter l’exécution du phonogramme[40].

Une deuxième forme d’exécution consiste à traiter le phonogramme par tranches temporelles successives. Pour chaque tranche, toute la hauteur du phonogramme est parcourue, et les segments des lignes débutant dans cette tranche sont traduits en événements. La structure décrivant une ligne de phonogramme contient un champ qui permet de mémoriser le numéro du dernier segment traité, de manière à optimiser le temps de recherche des segments. Le calcul d’une tranche est effectué sous interruption, par la routine Métronome appelée regulièrement à chaque terminaison d’une tranche temporelle. L’avantage de cette seconde forme d’exécution est la possibilité d’arrêter l’exécution à chaque tranche. L’inconvénient est le risque d’imprécision temporelle due au fait que l’horloge de MIDIShare s’arrête tant qu’une routine d’interruption s’exécute. Dans la première forme, en effet, toutes les dates d’émission sont respectées, car, le programme principal, générant les événements est interrompu par l’exécution de la routine d’émission des événements (de priorité plus forte). Dans la deuxième forme, au contraire, la génération des événements possède le même niveau de priorité que leur émission, et un décalage peut apparaître. Ce décalage est surtout sensible sur des machines de faible puissance de calcul, ou lorsque la densité du phonogramme est grande. Le résultat perceptible étant une suspension des sons durant le calcul de chaque tranche, suivie par l’émission précipitée de tous les événements suspendus au début de chaque tranche.

 

2.4.2.2.1.1.             Liaison avec un synthétiseur externe

 

La conversion de flux MIDI en signal audio est réalisée par les synthétiseurs externes. Le point critique pour nous dans cette opération est le goulet d’étranglement engendré par la vitesse de transmission fixée par le norme MIDI à 31250 bauds. En effet, le programme générateur des événements MIDI parvient à saturer les synthétiseurs dès que la densité de l’image dépasse un certain seuil : 2 ou 3 octets sont nécéssaires (suivant le contexte) pour envoyer un message de début ou de fin de note. Chaque octet est transmis sur 10 bits, donc nous ne pouvons dépasser le millier de messages par seconde. Nous émettons 8 canaux sur un premier port de sortie, et les 8 autres sur un second port[41]. Les modules de synthèse externes reçoivent donc chacun un flux destiné à huit modules, et il doivent sélectionner dans le flux d’une part les messages qui leur sont spécifiquement adressés (par un numéro de canal sur 4 bits contenu dans le message), et d’autre part les messages système destinés à tous les modules. Une solution envisagée est de créer un module matériel pour effectuer la séparation des canaux MIDI, et insérer ce module entre l’ordinateur et les synthétiseurs.

La solution actuelle, pour limiter l’étranglement, consiste en la répartition de toutes les notes correspondant à une colonne de pixels sur la durée totale correspondant à la colonne, par l’ajout d’un délai aléatoire (entre 0 et le nombre de millisecondes par pixel) au temps calculé pour le départ de la note soit :

 

t = ts + ((s->x1 - xd) * mspp) + aléatoire(0, mspp - 1)

 

où : t est l’instant de départ du segment s.

ts : est l’instant de départ de la section à jouer.

s->x1 la coordonnée horizontale du segment s.

xd : la coordonnée horizontale de la section à jouer.

mspp : la vitesse d’exécution en millisecondes par pixel.

 

Ceci peut être considéré comme étant l’équivalent MIDI du déphasage aléatoire utilisé dans l’algorithme de synthèse directe, la différence étant la durée du décalage temporel : dans le cas de la synthèse directe liée (inversement proportionnelle) à la fréquence, et dans le cas MIDI, liée à la vitesse d’éxecution.

 

2.4.2.2.2.               Génération de fichiers MIDI

 

La seconde façon de transformer un phonogramme en notation MIDI agit de manière similaire à la première, mais au lieu d’émettre les notes, celles-ci sont rangées dans un fichier ; soit canal par canal, soit tous canaux confondus suivant le format MIDI souhaité (format 0 ou 1). Dans le fichier, une indication temporelle (time stamp) est associée à chaque message MIDI.

 

 

2.4.3.         L'analyse du son pour la synthèse d'images

 

Pour obtenir le contenu spectral d’un son au cours du temps, c’est-à-dire le sonogramme (constitué du succession de spectrogrammes), on emploie habituellement l’algorithme de transformée de Fourier rapide (FFT : Fast Fourier Transform) (SOIZE 1993) (BRACEWELL 1986).

 

2.4.3.1.      Transformée de Fourier Rapide

 

Notre première approche a donc été d'utiliser l'algorithme de transformée de Fourier rapide appliqué à une fenêtre (rectangulaire) se déplaçant tout au long du signal à traduire, avec un pas de déplacement correspondant à la durée représentée par un pixel (une colonne de pixels) de l'image.

La première difficulté a été de trouver la règle permettant de faire correspondre les niveaux de gris (valeurs entières comprises entre 0 et 126), représentant des vélocités de notes MIDI, et les modules des nombres complexes résultant de la transformée, représentant les amplitudes. En effet, chaque fenêtre contient une tranche du signal qui a son énergie propre, et avant d'avoir analysé tout le signal, nous ne pouvons pas connaître l'énergie maximale.

Si nous appliquions les méthodes classiques d’analyse du signal telles qu’elles sont appliquées pour la reconnaissance vocale par exemple, nous calculerions simplement les extremums des modules indépendamment pour chaque position de fenêtre analysée, et nous assignerions la valeur de gris maximale aux valeurs de module maximales. Mais ceci, bien que plus simple à implanter, donne des images à rayures verticales, dues à la différence d’énergie d’une fenêtre à l’autre.

Pour obtenir une continuité horizontale dans l’image, il faut que la correspondance entre les modules et les valeurs de gris soient la même pour toutes les positions prises par la fenêtre. Malheureusement, avant l’analyse effective, nous ne savons pas quelles seront les valeurs extrêmes des modules. Une solution consisterait à conserver tous les résultats sous forme de module jusqu’à la fin du traitement, puis, d’effectuer la correspondance d’après les extremums de l’ensemble. Nous n’avons pas retenu cette solution pour deux raisons :

D’une part l’espace nécessaire au traitement eut été trop important, d’autre part, nous préférions une solution où les résultats se forment progressivement sur l’écran pendant le traitement, pour que l’utilisateur puisse connaître l’état d’avancement du processus.

 

Nous parcourons l’ensemble des échantillons à traiter, pour déterminer les extremums d’amplitude, ce qui permet ensuite de normaliser le signal, c’est-à-dire amener les amplitudes entre -1 et 1, avec le même facteur pour tous les pas (toutes les positions de fenêtre).

Pour chaque pas, nous calculons l’énergie du signal  , puis après l’application de la FFT, nous calculons l’énergie spectrale  nous obtenons enfin la correspondance recherchée par :

  

 

Les résultats obtenus sont exploitables musicalement, les sons vocaux, analysés par cette méthode puis reconstitués par synthèse additive différée sont reconnaissables. On reconnaît la voix, et le locuteur. Mais le son est perceptiblement transformé. Une sorte de granularité apparaît dans le timbre.

 

Le signal étant échantillonné à la fréquence Fe, la réponse de FFT est un spectre harmonique dont la fréquence fondamentale est donnée par , où N est la puissance de deux représentant le nombre d’échantillons de la fenêtre.

Donc, les réponses sont données pour des fréquences multiples de .

D’autre part, lorsqu’on augmente la précision fréquencielle, la précision temporelle diminue et inversement.

Or nous voulons obtenir des réponses pour la totalité des lignes des phonogrammes dont les fréquences sont données par :

 

fi = f0 . e i

 

e = 2 (1/192)

 

où f0 représente la fréquence de la première ligne, ceci conduirait à l’utilisation d’une précision fréquencielle maximale, imposant une perte totale de précision temporelle, et l’utilisation de fenêtres d’une taille interdisant les manipulations en mémoire.

En utilisant des valeurs raisonnables (de l’ordre de 212 à 214) pour la taille des fenêtres, le résultat de la FFT est une image constituée de lignes horizontales séparées par des espaces importants dans les basses fréquences, et allant en diminuant vers les hautes fréquences.

Le résultat graphique n’est donc pas satisfaisant, et cela est dû à l’incompatibilité entre les échelles de fréquences harmoniques délivrées par la FFT, et l’échelle microtonale des phonogrammes.

Figure 2.31 : Transformée de Fourier Rapide dans un phonogramme

 

Ceci (figure 2.31) est le résultat de l’analyse par la transformée de Fourier Rapide, avec une vitesse de 10 millisecondes par pixel de la phrase “parmi des milliers d’étoiles...”. On observe principalement le resserrement des harmoniques vers les fréquences aiguës. Cette figure est à comparer avec celle obtenue par notre système de transformée élastique, pour le même échantillon sonore (figure 2.32).

 

Figure 2.32 : Résultat de la transformée élastique (cf. chapitre suivant), même échantillon sonore, même vitesse de 10 millisecondes par pixel. Les réglages du banc de résonateurs étaient de 0.995 pour la viscosité, de 5 pour le seuil d’activité, et 8 pour le seuil d’affichage. Le coefficient d’amplitude a varié de 7.10-11 à 5.10-11. La différence entre le seuil d’activité et le seuil d’affichage étant trop faible, on aperçoit, sur les attaques, les lignes correspondant aux résonateurs insomniaques.

 

2.4.3.2.      Transformée de Fourier discrète

 

Pour obtenir des réponses dans la gamme de fréquences correspondant à l’échelle microtonale des phonogrammes, nous sommes donc revenus à l’étape antérieure à la FFT, en utilisant la transformée de Fourier discrète :

  

 

 

représente la fréquence angulaire.

La fréquence correspondante est .

La formule permet d’obtenir les réponses pour N intervalles égaux entre -Fe/2 et +Fe/2.

N est le nombre de réponses fréquencielles et M la taille de la table d’échantillons.

 

En remplaçant eiw par cos(w) + i sin(w) et en calculant indépendamment les valeurs réelles et imaginaires, nous pouvons obtenir la transformée pour n’importe quelle fréquence entre -Fe/2 et +Fe/2, avec toujours, une précision dépendant de la longueur de la fenêtre.

 

Nous précalculons un peigne de fréquences correspondant aux fréquences des lignes de phonogrammes. Les fonctions sinus et cosinus sont précalculées également dans des tables.

 

Transformée de Fourier adaptée à un peigne de fréquences non harmonique :

• Pour chaque ligne :

 

      *(peigne + ligne) =

          TailleTableSinus * fréquence(ligne)

          / FréquenceEchantillonnage.

 

Le pas d’avance de la fenêtre doit correspondre à une colonne de pixels de l’image :

 

      PasDAvance = FréquenceEchantillonnage

          * NombreDeSecondeParPixel ;

 

• Pour chaque position de fenêtre

      • Pour chaque fréquence du peigne (indéxée par ligne)

          Initialisation à zéro de la somme (partie imaginaire et réelle)

          somme.reel = somme.image = 0

     

          • Pour chaque échantillon m de la fenêtre :

               l’index dans la table des sinus et cosinus est la valeur du peigne multiplié par l’indice de l’échantillon (m) modulo la longueur de la table de sinus.

               index = fmod(*(peigne + ligne) * m,

                    TailleTableSinus)

               Si l’index est négatif, on ajoute la taille de la table.

 

               Nous pouvons maintenant calculer les sinus et cosinus :

               expon.reel = *(tableCos + index)

               expon.image = *(tableSin + index)

         

               Faire le produit par la valeur d’amplitude de l’échantillon :

 

               expon.reel *= *(signal + m)

               expon.image *= *(signal + m)

         

               Puis cumuler le résultat dans la somme :

               somme.reel += expon.reel

               somme.image += expon.image

          • Fin de boucle sur m

     

     

          Calcul du module :

          module = sqrt (somme.reel * somme.reel

               + somme.image * somme.image)

          Le module est rangé dans la table de résultats à l’index correspondant à la fréquence. La phase n’est pas utilisée.

      • Fin de boucle sur ligne

• Fin de boucle sur les fenêtres

 

Les résultats obtenus sont conformes à ceux attendus, les images ont un aspect continu, nous n’avons plus de manques (de lignes vides), et le procédé de calcul de l’énergie est toujours applicable pour obtenir une continuité horizontale. Mais le temps de calcul est rédhibitoire.

La taille de la fenêtre d’analyse peut couvrir un temps supérieur à la durée correspondant à un pixel, dans ce cas, les fenêtres se chevauchent, et une optimisation est possible. Mais ce n’est pas toujours le cas (suivant la précision d’analyse et la vitesse en millisecondes par pixel). Une machine parallèle serait mieux adaptée à ce traitement, puisque les calculs sont indépendants pour chaque ligne.

Cet échec nous a orienté vers d’autres procédés d’analyse[42], par exemple chercher une possibilité physique (matérielle) d’analyse (prisme sonore, cf § Analyse acoustique directe), ou encore le procédé que nous nommons la transformée élastique qui sera finalement retenu.

 

2.5.      Organisation temporelle des phonogrammes

 

L’organisation temporelle est primordiale dans l’écriture d’algorithmes de génération musicale. La représentation par phonogramme possède une relation très simple avec le temps : Une longueur correspond à une durée. Il suffit de spécifier une vitesse d’exécution, et l’interprétation temporelle des éléments graphiques est déterminée.

Mais ceci ne fait que reporter dans la structure de l’image le problème de l’organisation temporelle de la pièce. Le programme n’effectue qu’une simple multiplication pour chaque extrémité de segment du phonogramme, le compositeur, graphiste, doit composer, décomposer, structurer et organiser le temps.

 

Nous présentons dans ce chapitre le système de marquage des sections temporelles des phonogrammes et notre système de schémas d’organisation temporelle.

 

2.5.1.         Les marques

 

Pour repérer des sections temporelles précises dans les phonogrammes, nous avons donné la possibilité de placer des marques dans la marge de pied des fenêtres de phonogrammes, flottant au dessus des graduations. Lors d’un déplacement d’une marque, une ligne verticale indique précisément la position de la marque par rapport à l’ensemble de la fenêtre. Les marques sont identifiées par des lettres et sont créées et détruites par couple (marque de début et de fin de section).

 

Figure 2.33 : Exemple de phonogramme avec deux couples de marques a et b.

 

Les marques servent à définir, par exemple, la section à traduire en fichier MIDI ou la section à synthétiser. Les marques servent également d’interface pour déclencher l’exécution de la section.

 

En dessinant, plaçant des marques, et déclenchant l’exécution de sections, qui peuvent être exécutées en parallèle, nous pouvons improviser avec des phonogrammes. L’exécution étant traitée par interruption, elle ne bloque pas l’usage des outils graphiques[43].

 

2.5.2.         Les schémas

 

Pour permettre une planification abstraite et automatiser l’enchaînement des sections temporelles des phonogrammes, nous avons conçu un éditeur de graphes provoquant le déclenchement des sections marquées. Nous désignerons ce type de graphe par le terme schéma. (figure 2.34)

 

Figure 2.34 : Exemple de schéma permettant le déclenchement des marques a et b.

 

2.5.2.1.      Structure et réflexes des schémas

 

Les schémas sont constitués de cellules et de flèches reliant les cellules.

Les cellules et les flèches possèdent des réflexes graphiques simplifiant leur création, leur manipulation et leur destruction.

 

2.5.2.1.1.               Structure des cellules et des flèches

 

Les cellules possèdent un pointeur vers la cellule qui les englobe. Les cellules principales du schéma n’ont pas de cellule englobante. Chaque cellule possède un chaînage contenant les références vers ses sous-cellules, un autre chaînage vers les flèches partant de cette cellule, et un dernier chaînage contenant les références vers les flèches incidente à cette cellule (figure 2.35). Tous les chaînages sont bidirectionnels pour simplifier l’écriture des fonctions de manipulation du graphe.

Les cellules possèdent enfin des données indépendantes de la structure du graphe : le texte et les coordonnées du cadre de la cellule. Et l’information concernant la gestion du temps et les mécanismes que nous décrirons ci-après.

 

Cellule :

            Cellule englobante     

            Sous-cellules          

            Flèches partantes

            Flèches incidentes     

            Texte

            Cadre

            Information temporelle

            Mécanismes

 

Figure 2.35

 

Flèche :

            Cellule origine        

            Cellule arrivée        

            Point origine

            Point arrivée          

            Trajet de la flèche         

            Mécanismes

 

Figure 2.36

             

Les flèches (figure 2.36) possèdent un pointeur vers la cellule d’origine, et un pointeur vers la cellule d’arrivée, elles connaissent les coordonnées des points de l’origine et de l’extrémité ainsi que tous les points du trajet de la flèche mémorisés dans un double chaînage.

 

2.5.2.1.2.               Propriétés des cellules et des flèches

 

Les cellules peuvent s’emboîter les unes dans les autres, elles détectent la relation d’inclusion (dans le schéma ci-dessus, figure 2.34, la cellule b est emboîtée dans une autre). Les cellules sont représentées par des rectangles dont les cotés sont parallèles aux axes verticaux et horizontaux (rectangles droits). Si une cellule est déposée ou créée à l’intérieur d’une autre, elle apparaîtra au dessus de sa cellule englobante[44].

 

Figure 2.37

 

La relation d’inclusion des cellules n’est pas la relation mathématique d’inclusion des rectangles des cellules. Dans le schéma ci-dessus (figure 2.37), le rectangle de B est inclus à la fois par le rectangle de A et de E, mais l’historique des créations et déplacements a une influence, et une cellule ne peut être incluse que dans une seule cellule englobante. Ce schéma pourrait être formulé par l’expression E, A(C(D), B). L’inclusion des cellules définit une relation d’ordre partielle. Le graphe d’inclusion est toujours un arbre dont la racine est le schéma.

 

Toutes les cellules englobées se déplacent lorsque la cellule englobante est déplacée (en déplaçant A on déplace B, C et D de la même translation). Mais, à l’inverse, si l’on déplace une cellule englobée, on peut la faire sortir de sa cellule englobante (en déplaçant C on emmène D mais A et B restent en place).

 

Les cellules d’un même niveau d’imbrication sont tracées dans un ordre qui est modifié lors d’un déplacement ou d’un changement de taille d’une cellule. La dernière cellule déplacée ou modifiée apparaît devant (comme la cellule A apparaît devant E dans le schéma).

Chaque cellule peut contenir un texte (ici les lettres désignant les cellules, mais le texte est limité à 32K caractères).

 

Pour créer une cellule, il suffit de faire une trace formant une boucle avec le pointeur de la souris en gardant le bouton enfoncé. Dès que l’on relâche le bouton, près de la position d’origine, une nouvelle cellule est créée dont le cadre est le plus petit rectangle droit contenant tous les points du trajet du pointeur de la souris. Un double clic est un cas particulier de trajet (à un seul point) formant une boucle, le double clic déclenche donc la création d’une cellule ayant la taille minimale attribuée aux cellules pour qu’elles puissent contenir une lettre.

Quand des touches du clavier sont pressées, la dernière cellule déplacée ou modifiée entre en mode d’édition, et l’on peut modifier, éditer son texte. On quitte le mode d’édition en cliquant en dehors de la cellule.

 

Figure 2.38

 

Pour déplacer une cellule, on clique dans la partie supérieure de la cellule (bandeau de déplacement, figure 2.38). Pour l’agrandir ou la réduire, indépendamment de son contenu, on attrape la cellule par le coin bas droite (changement de taille). Le coin bas gauche (zoom) permet de changer la taille de la cellule en modifiant proportionnellement la taille des cellules englobées.

 

Les flèches partent d’une cellule, arrivent à une autre cellule. Pour les former, une trace ouverte, partant d’une cellule suffit. Leur point d’origine ou leur pointe peuvent être en dehors de toute cellule, mais si aucune des extrémités n’est dans une cellule, la flèche est supprimée.

Le trajet des flèches subit l’action de couplages élastiques lors de leur création ou lors du déplacement ou des modifications des cellules. Nous décrivons ceci dans le chapitre portant sur les couplages élastiques.

 

2.5.2.1.3.               Surfaces sensibles et déclencheurs

 

Les différentes zones indiquées dans la figure 2.38 ci-dessus sont gérées par une structure de la bibliothèque boîte à outils que nous nommons surface sensible.

Une surface sensible est un dictionnaire faisant correspondre des listes ordonnées de déclencheurs à des clefs formées par les coordonnées des points d’une grille virtuelle.

Un déclencheur est une structure comprenant un cadre (un rectangle droit limitant la portée du déclenchement ou zone) un pointeur de fonction et un pointeur vers le ou les paramètres à fournir à la fonction.

 

Figure 2.39

 

Lors d’un clic de l’utilisateur, les coordonnées du point indiqué sont tronquées pour correspondre à un point d’une grille virtuelle puis concaténées (l’abscisse et l’ordonnée forment un mot de 32 bits). Cette clef permet de sélectionner immédiatement (par recherche dichotomique binaire) une liste de déclencheurs correspondant à ce point de la surface. Les différents déclencheurs pointent vers les fonctions de création des cellules et des flèches, les fonctions de déplacement et modification des cellules. Le premier déclencheur de la liste est exécuté. Son exécution consiste en l’appel de la fonction avec la référence aux paramètres, et c’est la fonction elle-même qui connaît la nature et le nombre des paramètres précalculés.

Les déclencheurs sont dans une liste, pour pouvoir superposer les zones sensibles. En effet, les cellules peuvent se chevaucher, et dans ce cas, ce sont les fonctions de la cellule placée en dernier qui doivent être déclenchées en priorité. Mais lors d’un déplacement ou d’une suppression de la cellule, tous ses déclencheurs doivent être retirés, laissant alors la priorité aux déclencheurs suivants dans les listes. Nous nommons mécanismes l’ensemble des zones sensibles d’un élément graphique. Les flèches possèdent également des mécanismes, situés sur les extrémités, et permettant les déplacements de celles-ci. Par contre, les réflexes élastiques des trajets permettent d’élider l’installation de mécanismes le long du parcours.

 

La bibliothèque permet d’installer une zone sensible dans une surface sensible en la plaçant prioritaire, ou de retirer une zone sensible quelle que soit sa priorité.

 

L’avantage de cette représentation des actions liées à des éléments graphiques mobiles est le temps constant (et immédiat) de réponse à l’action de l’utilisateur quelque soit le nombre d’éléments graphiques actifs à gérer. En effet, la démarche habituelle est de parcourir la structure décrivant les éléments graphiques pour calculer l’élément sur lequel porte l’action (en calculant d’après l’ordre des superpositions et les coordonnées des éléments), puis de détailler éventuellement, en fonction de la position dans l’élément, pour déterminer la fonction à lancer. Lorsque le nombre d’éléments augmente, ce temps peut devenir non négligeable, et il est situé entre le moment de l’action de l’utilisateur, et le déclenchement d’un effet en retour visible par celui-ci (feed-back visuel), ce qui est un moment critique par rapport au confort de l’interface. Dans notre système, cette réaction arrive immédiatement, par contre, l’installation des mécanismes prend du temps (c’est une sorte de précalcul de l’ensemble des actions que l’utilisateur pourra faire). Mais cette installation des mécanismes n’intervient qu’après la terminaison de l’action de l’utilisateur, pendant que celui-ci voyant le résultat de son action réfléchit à ce qu’il fera ensuite, et qu’il n’est pas encore prêt à agir de nouveau.

 

Les réflexes des cellules et des flèches permettent la création, la modification et la suppression[45] des éléments du graphe sans avoir recours à des menus, ou des palettes d’outils, simplement en analysant le point d’origine et la forme des mouvements effectués par l’utilisateur. Nous avons utilisé une démarche similaire pour construire l’interface des réseaux de couplages élastiques.

 

2.5.2.2.      La clepsydre ou le sablier

 

Les clepsydres et les sabliers sont des instruments de mesure du temps très anciens, leur principe est d’utiliser le mouvement d’un fluide pour représenter analogiquement l’écoulement du temps.

Nous utilisons les cellules des schémas comme des réservoirs, dont la contenance dépend de la surface, et les flèches comme des conduits. Les cellules peuvent contenir des grains de temps, qui s’écoulent le long des flèches.

Les flèches prélèvent un grain de temps à leur origine et l’ajoutent à leur arrivée. Si l’origine de la flèche n’est dans aucune cellule, la flèche crée le grain de temps. Si la flèche n’arrive dans aucune cellule, la flèche détruit le grain de temps.

Lorsqu’une cellule est remplie, un événement est déclenché, et la cellule est vidée de son contenu. L’événement peut être le déclenchement de l’exécution d’une section de phonogramme marquée par une lettre correspondant au texte de la cellule. L’événement peut également être le remplissage de toutes les sous cellules.

Le traitement (l’activation des flèches) est effectué en tâche de fond, avec une très faible priorité : L’activation n’est faite que si aucune action de l’utilisateur n’est en cours. La routine d’activation ne traite que les flèches du schéma actif (le schéma de la fenêtre active, au premier plan) et ne déclenche les événements que dans le phonogramme actif (la dernière fenêtre de phonogramme à avoir été activée).

Pour éviter les cycles, dans la circulation des grains de temps, les flèches étant traitées séquentiellement, le traitement n’est fait que si la valeur d’un tirage aléatoire dépasse un seuil. Ceci permet de ne pas traiter les flèches dans un ordre constant, et permet une répartition équitable des grains dans les sorties d’une cellule possédant moins de sources que de sorties par exemple.

 

2.6.      Convolutions

 

Pour comprendre la transformée de Fourier, nous avons étudié les convolutions (et les corrélations). Cette étude a débouché sur un nouvel algorithme de multiplication applicable sur les grand nombres. Nous présentons dans ce chapitre le principe des convolutions, puis nous introduirons une modification de ce principe permettant de produire des séries de nombre connues, telles la suite de Fibonacci et la suite des nombres Catalans, et enfin nous détaillerons notre algorithme de multiplication.

 

La convolution de deux fonctions est :

ou f(x) * g(x)

 

Prenons deux séries de nombres {ai} et {bi} écrivons les ai de gauche à droite et les bi de droite à gauche sur deux bandes de papier indépendantes, puis amenons a0 en face de b0 (figure 2.40):

 

Figure 2.40

 

On note le premier produit a0.b0.

 

Figure 2.41

 

Puis on déplace la bande b un cran sur la droite et on effectue la somme des produits des valeurs face à face (figure 2.41).

 

Figure 2.42

 

On réitère jusqu'à ce que la dernière valeur de a soit en face de la dernière valeur de b.

 

La suite des sommes de produits ainsi obtenue est le résultat de la convolution de a et de b.

 

{ai} * {bi} = {a0.b0 a0.b1+a1.b0  ... an.bm} = {hi}

 

Une autre façon de le noter, sans utiliser les bandes de papier glissantes, est de former une grille rectangulaire, de porter les bi verticalement en index de ligne, et les ai horizontalement en index des colonnes.

 

Figure 2.43

 

Puis de porter dans chaque case le produit des index.

 

Figure 2.44

 

Et enfin de faire la somme des valeurs des diagonales :

 

Figure 2.45

 

En permutant les deux séries, a et b, les résultats seraient équivalents :

 

Figure 2.46 La même grille après rotation de 90° et miroir horizontal : la convolution est commutative.

 

Si les ai et les bi étaient les coefficients de deux polynômes, les hi obtenus par {hi} = {ai} * {bi} seraient les coefficients du produit de ces deux polynômes.

 

(a0 + a1x + a2x2 + ... anxn ) . (b0 + b1x + b2x2 + ... bmxm)

= a0.b0 + (a0.b1+a1.b0)x + ... an.bm.x(n+m)

= h0 + h1x + h2x2 + ... h(n+m-1)x(n+m)

 

Voici un exemple plus simple :

 

(a + b) . (a + b)

 

Figure 2.47

 

la notation en grille rectangulaire correspondante :

 

Figure 2.48

 

Tous les termes de la suite n’ont pas besoin d’être connus :

 

Figure 2.49

 

{1 1} * {1 2 3 4 5... } = {1 3 5 7 9 ...}

 

ou encore :

Figure 2.50

 

{1 -1} * {1 2 3 4 5 ...} = {1 1 1 1 1 ...}

 

Nous pouvons effectuer la convolution de deux suites semi-infinies :

par exemple {1 2 3 4 5 ... } * {1 2 3 4 5 ... } = {1 4 10 20 35 ...}

Les premiers termes suffisent pour trouver les premiers termes du résultat.

 

Figure 2.51

 

Cette idée nous a conduit à générer des suites, en supposant les premiers termes connus, et en déterminant les suivants par le calcul de la convolution.

 

2.6.1.         Génération de suites

 

Nous construisons une suite A avec les résultats de la convolution des premiers éléments connus de la suite A avec une autre suite B qui elle, reste constante.

 

La suite de Fibonacci : Fibonacci = {0 1 ...} * {1 1}

 

Figure 2.52

 

On commence avec les suites A = {0 1} et B = {1 1}, on calcule le deuxième terme de la convolution : 0 x 1 + 1 x 1 = 1 puis on ajoute ce résultat à la fin de la suite A. Dorénavant A = {0 1 1}. Continuons la convolution, le troisième terme est 1 x 1 + 1 x 1 = 2. On ajoute le 2 à la suite A qui devient A = {0 1 1 2}. En itérant ce processus, tous les termes de la suite de Fibonacci sont générés.

 

Construisons maintenant une suite avec elle-même.

 

La suite des nombres Catalans : Catalan = {1 ...} * {1 ...}

 

Figure 2.53

 

Première étape : {1} * {1} = {1}, nous ajoutons ce 1 à la fin de la suite : {1 1}, ce qui permet de calculer la valeur suivante, le 2, etc...

 

2.6.2.         Les multiplications

 

La multiplication est une convolution : {2} * {3 2 9 5 } = {6 4 18 10}

La figure 2.54 montre comment obtenir le résultat de la multiplication à partir de la convolution.

 

Figure 2.54

 

Les nombres écrits en base B avec la suite de chiffres {ai} peuvent être vus comme un polynôme :

 

   a0.Bn + a1.Bn-1 + ... + an.B0

 

La convolution des séries formées par les chiffres des deux opérandes produit une nouvelle suite de nombres correspondant au résultat de la multiplication si on les considère comme les coefficients des différentes puissances de la base, mais ces chiffres peuvent être supérieurs à la base.

L'opération qui est effectuée après la convolution est la propagation des retenues. Pour la multiplication de 23 par 257, la convolution donne :

{2 3} * {2 5 7} = {4 16 29 21}

 

Figure 2.55

 

Puis la propagation des retenues donne le résultat : 5911.

 

La convolution utilise n.m multiplications de chiffres (6 dans cet exemple) et (n-1).(m-1) additions de nombres (2 dans cet exemple)

 

Le système de la multiplication musulmane exposé dans "Les nombres et leurs mystères" d'André Warusfel (page 24) (WARUSFEL 1961) est très proche de celui-ci, mais plus pratique pour la gestion des additions et des retenues. Le nombre écrit verticalement l'est de bas en haut, et l'autre nombre reste écrit de gauche à droite. Enfin, les produits de chiffres sont inscrits dans les cases clivées par une diagonale, les dizaines des produits sont placées en bas à gauche et les unités en haut à droite de chaque case. Les additions sont faites diagonale par diagonale, en débutant en haut à droite, et en reportant la retenue éventuelle dans la diagonale suivante (en dessous à gauche). Le résultat est alors directement lisible, inscrit de gauche à droite puis de bas en haut.

 

Figure 2.56 : 23 x 257 = 5911

 

 

2.6.3.         Des nombres infinis à gauche vers une méthode de multiplication

 

Prenons le nombre suivant ...2068965517241379310344827586 et multiplions le par 3. Ce nombre est infini à gauche c'est-à-dire que les chiffres qui sont donnés doivent être répétés indéfiniment vers la gauche.

 

    ...2068965517241379310344827586

                                                  x          3

=    ...206896551724137931034482758

 

Le résultat est identique au nombre lui-même divisé par 10 (en division entière).

Ce nombre a été construit de la manière suivante :

Choisissons un couple de chiffres quelconque, ici le 6 et le 3, multiplions ces chiffres, 3 x 6 = 18, le 8 est donc le chiffre suivant et la retenue est de 1, continuons en multipliant 8 par 3, ajoutons la retenue ce qui donne 25, le chiffre suivant est 5 et la retenue 2, etc... Continuons ainsi pour l'éternité.

 

01212021110002210102011122200.. (retenues)

68572844301397314271556986026.. (chiffres de gauche à droite)

3

 

L'éternité n'est pas très grande par ici, l'état de l'automate capable d'effectuer cette alchimie numérique ne dépend que du multiplicateur et de la base d'une part, et du couple formé par le dernier chiffre découvert et de la retenue. En base 10, en multipliant un chiffre par 3, la retenue ne peut prendre de valeur que dans {0, 1, 2}. Dans le pire des cas, nous aurons fait le tour en 30 pas. Dans cet exemple il a suffi de 28 pas. C'est étonnamment proche de 30, hasard extraordinaire ou cas normal ?

Nous sommes passés par la quasi totalité des couples (chiffre, retenue) avant de revenir sur le point de départ. Évidemment, en base 10 avec 3 pour multiplicateur, si nous repartions de n'importe quel chiffre de 1 à 9 nous obtiendrions le même résultat, à une permutation circulaire près.


Représentons ces choses sous forme de graphes dont les points seront les couples (chiffre, retenue) et les arcs pointant vers le couple suivant dans la série.

 

Figure 2.57 Graphe de la multiplication par trois en base dix. Les carrés noirs dans les coins des cases représentent les retenues.

 

 

Figure 2.58 : Graphe de la multiplication par deux en base dix.

 

 

Soit B la base du système de numération, (x, y) le couple (retenue, chiffre), et M le multiplicateur avec 0 < M < B.

 

E est l'ensemble des couples (retenue, chiffre) :

 

E = { (x, y) | x Π[ 0, M-1] , y Π[ 0, B-1] } = [ 0, M-1] x [ 0, B-1]

 

soit f l'application qui fait correspondre la valeur n à chaque couple.

 

f : E Æ [ 0, M.B-1]

(x, y) Æ x.B + y = n

 

Son application réciproque f -1 permet de retrouver à partir d'un entier positif ou nul inférieur à M.B le couple correspondant :

 

f -1 : [ 0, M.B-1] Æ E

n Æ ( n // B , n % B )

 

.//. représente la division entière et .%. le reste de la division.

 

Soit d de E dans E l'application symétrique définie par :

d (x, y) = (M-1-x, B-1-y)

 

on a bien d'une part (x, y) ΠE (M-1-x, B-1-y) ΠE

et d'autre part la symétrie :

 

d(d(x, y)) = (M-1-(M-1-x), B-1-(B-1-y)) = (x, y)

 

L'application R de E dans E qui à un couple (x, y) fait correspondre le couple suivant dans notre automate est :

R: EÆ E

(x, y) Æ (x', y') | M.y + x = n = x'.B + y'

 

On multiplie le chiffre y par M et on ajoute la retenue, on obtient un entier positif ou nul n < M.B qui transformé par f -1 donne (x', y').

 

f (R (M-1, B-1)) =

   M.(B-1) + (M-1) = M.B - 1 = (M-1).B + (B-1) = f (M-1, B-1)

donc

R (M-1, B-1) = (M-1, B-1).

 

On a aussi f(R(0, 0)) = 0 = f (0, 0).

 

Soit (x, y) et (x',y') | R(x, y) = (x', y')

 

d(x, y) = (M-1-x, B-1-y)

f(R(d(x, y))) =

   M.(B-1-y) + M- 1 - x =

   MB - M - y.M + M - 1 - x =

   MB - (M.y + x) - 1 =

   MB - (x'.B + y') - 1 =

   B.(M-x') - y' - 1 =

   (M-1-x').B + B - y' - 1 =

   f(d(x', y')).

 

donc R(x, y) = (x', y') R(d(x, y)) = d(x', y')

Ce qui explique et démontre la symétrie du graphe de R, quelle que soit la base et le multiplicateur, choisi inférieur à la base.

 

 

En disposant le graphe sous forme de table, les choses se simplifient.

Voici le graphe de la multiplication par 2 en base 3 (figure 2.59)

Les retenues sont 0 ou 1, en entête, et les chiffres 0, 1 et 2 en index.

 

Figure 2.59

 

Un couple (retenue, chiffre) détermine une ligne de la table, et le point dans cette ligne indique une colonne désignant ainsi le couple suivant.

Prenons un exemple : 221(base 3) à multiplier par 2.

Au départ la retenue est 0 le chiffre est 1 (le chiffre de droite du nombre 221(3)), nous visons donc la deuxième ligne, qui contient un point dans la troisième colonne désignant le chiffre 2 que nous posons, et la nouvelle retenue 0. Nous prenons le chiffre suivant dans le nombre : 2, et nous réitérons : (0, 2) -> (1, 1) nous posons 1 (ce qui fait à présent 12), et formons le nouveau couple (1, 2) qui donnera (1, 2), nous posons le 2 : 212, et nous continuons avec le couple (1, 0) puisque nous avons traité tous les chiffres du nombre. (1, 0) -> (0, 1), nous posons le 1 ce qui fait 1212, et continuons avec le couple (0, 0). mais (0,0) donne (0,0) ce qui formera une infinité de 0 devant le résultat : ...0001212(3)

 

retenues    chiffres    (r, c)     

      .           1     ->    (0, 2)     

      0           2     ->    (1, 1)

      1           2     ->    (1, 2)

      1           .     ->    (0, 1)

      0           .     ->    (0, 0)

      0           .     .     ...

 

Rien n'empêche de former des tables pour un multiplicateur plus grand que la base. Voici la table de la multiplication par 3 en base 2 (figure 2.60).

 

Figure 2.60

 

Cette table (figure 2.60) ressemble étrangement à la table précédente (figure 2.59) : les points sont à la même place à une inversion des lignes et colonnes près. C'est comme si on lisait la table précédente à l'envers : La multiplication par M en base B est équivalente à la division par B en base M.

 

Prenons dix : 1010(2) en base 2 et appliquons notre table.

 

      retenues    chiffres    (r, c)     

      .           0     ->    (0, 0)     

      0           1     ->    (1, 1)

      1           0     ->    (0, 1)

      0           1     ->    (1, 1)

      1           .     ->    (0, 1)

      0    

           

 

Le résultat est bien 11110(2) trente en base 2, (qui se lit de bas en haut dans la colonne c).

 

Peut-on faire l'opération inverse ?

 

Essayons avec trente et divisons par 3 en utilisant la table dans l'autre sens. Cette opération inverse est possible, puisque qu'il n'y a qu'un seul point par colonne dans la table. Cette fois ci, nous écrivons le chiffre en commençant par le plus à gauche

 

      retenues    chiffres    (r, c)

      .           1     >-    (1, 0)

      1           1     >-    (0, 1)

      0           1     >-    (1, 0)

      1           1     >-    (0, 1)

      0           0,    >-    (0, 0),

      0           .    

 

Le résultat est bien 1010 (qui se lit dans la colonne c mais de haut en bas cette fois).

 

Et avec un nombre non divisible par 3 comme 1101(2) qu'adviendra-t-il ?

 

      retenue     chiffre     (r, c)

      .           1     >-    (1, 0)

      1           1     >-    (0, 1)

      0           0     >-    (0, 0)

      0           1,    >-    (1, 0),    

            ici nous avons la partie entière 0100(2) = 4(10)

      1           .     >-    (2, 0)     

            il reste quelque chose, continuons...

      2           .     >-    (1, 1)

      1           .     >-    (2, 0)     

            nous avons déjà été dans cet état 2 lignes plus haut

      2           .     >-    (1, 1)     

            comme il n'y a plus que des zéros dans notre

      1           .     .     ...        

            nombre, la division continue indéfiniment.

 

Le résultat est donc 100.01010101...(2) c'est-à-dire 4,33333... en base dix.

 

 

 

Figure 2.61 : La table des 5 en base 2.

 

Comment construire les tables.

 

Les chiffres vont de 0 à B-1, les retenues vont de 0 à M-1. La table est une grille carrée de coté M.B. On dépose un point dans la première case : (0, 0), puis on compte M cases sur la droite, et on descend d'une ligne pour déposer le point suivant.

Quand nous avons rempli les B premières lignes, il suffit de les recopier M-1 fois en les décalant d'une case sur la droite à chaque fois.

Il doit y avoir un point dans la dernière case. La grille est symétrique par rapport au centre.

 

En fait, tous ces graphes peuvent être résumés par la formule suivante :

 

Dans le sens de la multiplication :

 

   r' = (c.M + r ) // B.      (.//. est la division entière)

   c' = (c.M + r) % B.                 (.%. est la reste de la division entière).

 

Le couple (r, c) produit le résultat (r', c') dans la table de M en base B.

 

En particulier pour la base 2, la formule se simplifie terriblement ; comme le chiffre c ne peut-être que 0 ou 1, le produit c.M devient 0 ou M d'où :

 

Multiplication en base 2 :

 

si c = 0

      r' = r >> 1

      c' = r & 1

si c = 1

      r' = (M+r) >> 1

      c' = (M+r) & 1

 

Où a >> b est l'opération de décalage des bits de a de b rangs vers la droite (en perdant les bits de poids faible) ce qui correspond à la division entière par 2 lorsque b vaut 1. Et & est l'opération et logique, appliquée bit à bit. Le masque 1 permet de ne conserver que le bit de poids faible, et force les autres bits à zéro, ceci fournissant le reste de la division entière par 2, encore nommée parité.

 

Cet algorithme de multiplication ou de division de (grands) nombres ou de polynômes est très efficace lorsque que le diviseur et la base sont constants[46]. La table, ne dépendant que du diviseur (ou du multiplicateur) et de la base, n’est à construire qu’une seule fois lorsque ceux-ci sont constants.

Une fois la table construite, l’opération, division ou multiplication, est effectuée en un temps directement proportionnel au nombre de chiffres de l’opérande.

On peut envisager pour certaines applications de spécifier les tables au niveau matériel (hardware), et de câbler l’algorithme de multiplication ou de division lorsque qu’un haut débit est nécessaire et que les multiplicateurs et/ou les diviseurs sont en petits nombres.

Cet algorithme a été utilisé par Sabah BEKKOUCHE, (BEKKOUCHE 1994) pour la division polynomiale employée dans un algorithme de détection d’erreur lors des transferts de données dans les réseaux.

 

2.6.3.1.      Représentation graphique des tables de divisions et multiplications

 

Les tables précédentes peuvent être condensées, en utilisant pour index les chiffres de la base d’une part et les valeurs possibles des retenues d’autre part. Les cellules des tables doivent alors contenir des couples (chiffre, retenue).

Nous proposons ici une représentation graphique de ces tables la figure  2.62 représente la table de division et de multiplication par 2 en base 10.

 

Figure 2.62 : table de 2 en base 10

 

En haut comme en bas, apparaît deux fois la série des dix chiffres de la base. Chaque série représente une valeur possible de retenue. Les chemins blancs mènent d’un couple (chiffre, retenue) à un autre.

 

2.6.3.1.1.         Division

 

Pour faire une division, on écrit d’abord le nombre à diviser, prenons par exemple 47, puis on regarde le premier chiffre à partir de la gauche (4). On repère ce chiffre dans la première série du haut et on suit le chemin blanc jusqu’en bas. Le 4 descend vers le 2 de la première série. On écrit 2. On cherche le chiffre suivant (7) dans la même série en haut. Le 7 conduit au 3 de la seconde série. On écrit 3. Le résultat est donc 23 en entier, mais on peut continuer la division après la virgule, (notre nombre est 47.000...) le chiffre suivant à chercher est le 0 dans la même série que le dernier résultat obtenu (la seconde). Le 0 mène au 5 de la première série. On écrit 5 et on continue. Le 0 de la première série mène au 0 de la première série, il y a donc une infinité de 0 après le 5. Le résultat est 23.50000...

 

2.6.3.1.2.         Multiplication

 

Pour faire une multiplication, le principe est le même : on commence toujours dans la première série, mais on prend les chiffres du nombre à multiplier de droite à gauche et on cherche les chiffres dans les séries du bas pour écrire les résultats donnés par les séries du haut.

Par exemple pour multiplier 19, on cherche le 9 en bas, ce qui donne 8 en haut (dans la seconde série, ce qui correspond à une retenue), puis on cherche le 1 dans la seconde série du bas, ce qui donne 3 dans la première série en haut. Le résultat est 38, mais on peut continuer avec 0 qui donne 0, etc... le résultat est ...00038 (avec une infinité de zéros à gauche).

La table ci-dessous est la table de division et de multiplication par 3 en base 10. On l’utilise de la même façon. Elle est formée de 3 séries de dix chiffres.

 

Figure 2.63 : Table de 3 en base 10.

 

2.6.3.1.3.         Constructions

 

Pour construire une table, de N en base B, on répète N fois les chiffres de la base. Puis on regroupe les chiffres en B groupes (numérotés de 0 à B-1) de N chiffres en numérotant les chiffres de 0 à N-1 dans chaque groupe. Les résultats sont les numéros des groupes (qui correspondent à des chiffres de la base). Pour réordonner les chiffres de façon d’une part à pouvoir les écrire dans l’ordre en bas, et d’autre part à guider vers les bonnes séries, on permute les chemins des couples de chiffres dont celui de gauche porte un numéro plus grand que celui de droite, et on répète l’opération jusqu’à ce que plus aucune permutation ne soit possible. Chaque chemin conduit alors vers le chiffre des séries du bas de la table (qui correspond au numéro du groupe du chiffre de départ).

Par exemple pour écrire la table de 5 en base 2 on répète 5 fois les chiffres 0 et 1.

 

0 1 0 1 0 1 0 1 0 1

Nous regroupons les chiffres en 2 groupes de 5.

 

0 1 2 3 4 0 1 2 3 4

Puis nous permutons les couples de numéros dont le second est inférieur au premier.

 

0 1 2 3 4 0 1 2 3 4

0 1 2 3 0 4 1 2 3 4

0 1 2 0 3 1 4 2 3 4

0 1 0 2 1 3 2 4 3 4

0 0 1 1 2 2 3 3 4 4

Lorsque plus aucune permutation n’est possible. La table est complète, et les numéros indiquent les chemins à suivre.

 

0 1 0 1 0 1 0 1 0 1

-------------------

0 1 2 3 4 0 1 2 3 4     Nous partons de 2 groupes de 5

0 1 2 3 0 4 1 2 3 4

0 1 2 0 3 1 4 2 3 4

0 1 0 2 1 3 2 4 3 4

0 0 1 1 2 2 3 3 4 4     Nous arrivons à 5 groupes de 2

-------------------

0 1 0 1 0 1 0 1 0 1

 

Par exemple pour diviser vingt, 10100 en base 2 par cinq on obtient :

1 -(1)-> 0 (groupe 1)

0 -(2)-> 0 (groupe 2)

1 -(0)-> 1 (groupe 0)

0 -(0)-> 0 (groupe 0)

0 -(0)-> 0 (groupe 0)

Le résultat est bien 00100 quatre en base 2.

 

L’exploration de l’univers mathématique est pour nous une source inépuisable d’éléments étonnants, voire magiques, alimentant nos recherches. La transmutation de ces formules opaques en éléments musicaux est une alchimie passionnante. La représentation des objets mathématiques par des formules ne correspond pas à notre propre représentation mentale de ces objets. C’est pourquoi nous recherchons des représentations graphiques telles que la précédente.

Deux points de vue, opposés et complémentaires, sont apparus au cours de nos démarches compositionnelles : soit les formules (ou objets mathématiques) sont elles-mêmes le modèle que nous cherchons à écouter, le programme est alors, tel un stéthoscope, un outil pour rendre audible un phénomène existant; soit les formules ne sont que les outils à adapter pour produire les effets sonores désirés.

Les trajectoires, présentées dans le chapitre suivant, peuvent être utiles à ces deux points de vue : l’objet mathématique sous-jacent est présenté sous forme graphique et peut être écouté.; d’autre part, la création de trajectoires peut être orientée selon le type d’effet sonore recherché.

 


3.         Oscillateurs et trajectoires

 

Les synthétiseurs numériques, tels qu’ils nous sont proposés sur le marché, deviennent de plus en plus fermés : ce sont des boîtes noires, produisant des sons préfabriqués utilisant différents systèmes de synthèse. Les réglages accessibles à l'utilisateur ont tendance à se limiter à la simple sélection de timbre, et non au contrôle des procédés de synthèse comme c'était le cas il y a une dizaine d'années.

D'autre part, les ordinateurs deviennent de plus en plus performants, et possèdent, pour les applications multimédias, la possibilité de jouer des sons mémorisés sous la forme de fichiers d'échantillons.

La conjonction de ces deux points favorise l'écriture de modules logiciels de synthèse[47]. Nous effectuons la synthèse en temps différé actuellement, elle pourrait être en temps réel en utilisant les capacités des processeurs spécialisés dans le traitement du signal : les DSP (Digital Signal Processor)[48].

 

3.1.      Le bruissement des feuilles

 

Pour synthétiser (des sons) il faut osciller. Osciller, vibrer, bouger, aller et venir, tourner autour d'un point, zigzaguer..., sans rupture dans le temps, bref, il faut générer une suite de valeurs qui commandera finalement les déplacements de la membrane du haut-parleur au cours du temps.

Avec les couplages élastiques, nous avons de bons oscillateurs : le déplacement d'un point d'une chaîne de couplages génère des sons intéressants. Mais nous pouvons trouver d'autres formules très simples aboutissant à des suites de valeurs que l'on peut rendre audibles.

Nous pourrions aussi écouter des phénomènes qui naturellement ont des fréquences très basses et/ou des amplitudes très faibles, et qui une fois ramenés dans une plage audible pourraient être appréhendés d'une manière nouvelle. Prenons un arbre par exemple, ses branches oscillent lentement sous l'effet du vent, nous entendons le bruissement des feuilles (une sorte de bruit coloré) mais nous n'entendons pas les branches. En enregistrant les déplacements des branches et en les accélérant, peut-être pourrions-nous déceler des différences de sonorités entre les espèces d’arbres. Ou encore en enregistrant le mouvement des ailes d’un oiseau en vol : nous sommes bien capable de distinguer un moustique d’une mouche ! Je pense qu’en augmentant la fréquence des battements d’ailes des oiseaux, nous pourrions discerner à l’oreille les caractéristiques des styles de vols.

La possibilité de transformer la trace d'un phénomène en fichier d'échantillons peut sans doute nous permettre d'utiliser nos capacités auditives pour l'analyse des données (au lieu de les visualiser).

 

3.2.      Les trajectoires

 

L’oscillation la plus simple (pour un informaticien) est fournie par une boucle qui génère alternativement un zéro puis un un.

 

01010101010101....     

 

Ceci produit un signal carré (il apparaît carré si on trace les lignes verticales reliant les traits horizontaux) (figure 3.1) :           

 

Figure 3.1

 

En étirant l’image verticalement on change l’amplitude (l’intensité sonore), et en étirant horizontalement, on change la fréquence (qui correspond à la hauteur du son).

 

Une formule plus générale pourrait être ainsi :

 

" t Œ [0, n]         s(t) = A . ((t.w ) & 1).

 

L’opérateur & désignant l’opération et logique.

 

La suite des nombres entiers, écrite en binaire (figure 3.2) donne autant d’oscillateurs qu’il y a de bits dans la représentation :

 

Figure 3.2

 

En se déplaçant d’une colonne vers la gauche, on divise la fréquence par 2 (on descend d’une octave).

 

Si nous comptions en base dix, notre onde ne serait plus carrée mais en dent de scie (figure 3.3) :

 

" t Œ [0, n]         s(t) = A . ((t.w ) % Base).

 

où l’opérateur % désigne l’opération modulo.

 

         -         -         -

        -         -         -

       -         -         - 

      -         -         -  

     -         -         -   

    -         -         -    

   -         -         -   

  -         -         -         -      

 -         -         -         -       

-         -         -         -        

012345678901234567890123456789012...

Figure 3.3

 

On peut voir la dent de scie comme étant la valeur d’un accumulateur, incrémenté à chaque pas, et vidé d’un coup lorsqu’une valeur limite est atteinte.

 

Des discontinuités, des passages abrupts d’un échantillon à l’autre par des valeurs extrêmes, existent dans le carré et la dent de scie (figure 3.4),.

 

              

Figure 3.4

 

 L’onde triangulaire au contraire est continue (figure 3.5) :

 

Figure 3.5

 

Elle est avec l’onde sinusoïdale, le carré et la dent de scie une onde de base (des plus simples) et des plus fréquemment rencontrées dans les générateurs.

 

Comment générer le triangle ? Si nous le voyons comme un accumulateur, il faudra incrémenter celui-ci tant qu’il est inférieur à une limite, puis le décrémenter tant qu’il est supérieur à zéro. Ceci implique la mémorisation d’un état indiquant si on est dans une phase montante ou descendante.

Au contraire, si nous voyons le triangle comme étant la trace dans le temps d’un mobile faisant des allers et retours entre deux points (comme faisant les cent pas entre deux murs (figure 3.6)), nous n’avons plus d’état particulier à mémoriser : il suffit d’inverser le signe de la vitesse (de valeur absolue constante) du mobile à chaque fois que la position atteint une limite.

 

              

Figure 3.6                                                 Figure 3.7

 

La sinusoïde peut s’interpréter de la même façon, comme étant la trace dans le temps d’un mobile dont la trajectoire est circulaire (figure 3.7), en observant cette trajectoire de profil.

 

La dent de scie (figure 3.8) est la trace dans le temps d’un mobile se déplaçant toujours dans le même sens, mais dans un espace torique (Quand le mobile sort d’un côté, il rentre de l’autre - d’où le lien avec l’opération modulo).

 

Figure 3.8

 

Le carré n’est qu’un cas particulier de dent de scie (dans un espace discret), avec un module de 2.

  

Cette vision sous forme de projection de la trajectoire d’un mobile sur une droite (la vue de profil) et le développement des points projetés dans le temps nous permet d’unifier tous ces oscillateurs (y compris les couplages élastiques) et nous suggère de nouvelles façons de créer des oscillateurs.

 

Nous pourrions par exemple simplement dessiner une trajectoire à l’aide de la souris et générer directement le son correspondant.

Un cercle donnerait un son sinusoïdal pur, mais que donnerait une trajectoire en huit, en lemniscate, ou en patate ?

Toutes les formes fixes de trajectoires donneront évidemment des sons périodiques (chaque tour correspondant à une période).

La fréquence sera donc déterminée par la vitesse du mobile. L’amplitude quant à elle étant la largeur de la trajectoire (perpendiculairement au sens de projection).

 

Les trajectoires pourraient se déformer progressivement, introduisant des modifications dynamiques du spectre.

 

La trajectoire du mobile peut également être décrite par des règles et non par une suite de valeurs prédéterminées.

Le mobile peut avoir ses règles de conduite, et interagir avec un environnement, introduisant ainsi des variations de la trajectoire. Les variations de trajectoire impliquent des modifications de timbre. Par exemple en enfermant une mouche dans une boîte de forme spéciale (figure 3.9), et en faisant en sorte que la mouche vole toujours, repoussée par les murs.

 

Figure 3.9

 

3.3.      Mise en œuvre des trajectoires

 

Nous avons réalisé un programme permettant de créer les trajectoires à l’aide de la souris, puis de générer les fichiers d’échantillons correspondant à la projection sur l’axe des x, de la position d’un mobile circulant sur cette trajectoire. Nous avions précédemment élaboré un module implémentant les couplages élastiques des trajets des flèches de graphes, en calcul entier, et le module permettant de construire des réseaux de couplages à maillage linéaire, carré ou cubique.

Nous avons combiné les deux modules pour représenter les trajectoires. Une trajectoire de notre système sera une liste de points, formant une boucle, chaque point étant relié au point suivant et précédent par un couplage élastique.

Un geste de la souris avec le bouton enfoncé dans une fenêtre de trajectoires permet de former une trajectoire. Le dernier point étant automatiquement relié au premier. Pendant le geste, la trajectoire se forme sur l’écran.

Pendant la simulation, les tensions des couplages élastiques appliquées sur les points des trajectoires déplacent ceux-ci, modifiant la trajectoire, et modifiant ainsi le signal correspondant. Tous les points de la trajectoire sont mobiles[49]. L’état initial de la trajectoire est conservé en mémoire de façon à ce que la production de son à partir d’une trajectoire ne soit pas destructeur.

 

Toute la couche d'interface, gestion des fenêtres de trajectoires, de l'association entre les fenêtres et les données correspondantes, des barres de défilement, de la sauvegarde des documents, de l'impression, des actions du clavier et de la souris, a été réalisée à partir d'un squelette préexistant : il suffit de recopier et changer le nom de la structure associée au nouveau type de fenêtre pour obtenir un squelette fonctionnel. Puis, l'intégration dans le programme principal est localisée au niveau des fonctions gérant l'action des menus, qui doit pouvoir distinguer les différents types de documents coexistants.

La structure associée aux fenêtres de trajectoires est une liste (double chaînage) de trajectoires. Chaque trajectoire est constituée d'un pointeur vers une structure élastique (double chaînage de points en coordonnées entières) mémorisant l’état initial, d'un pointeur vers un réseau linéaire de même taille (mais en coordonnées flottantes) pour la simulation, et enfin d'une structure contenant les paramètres de réglage des propriétés du réseau : tension des couplages, viscosité, plus les valeurs enregistrées lors des expériences telles que la durée du son, la fréquence d'échantillonnage souhaitée.


 

3.4.      Conversion de phonogrammes vers des trajectoires

 

Il semble impossible de convertir des phonogrammes ou d’autres représentations spectrales en trajectoires dans le sens où nous l’avons utilisé Comment retrouver la trajectoire d’un mobile hypothétique dont la projection sur une dimension correspondrait au signal dont la transformée est le phonogramme original ?

Par contre, en élargissant la notion de trajectoire à une succession de positions dans un espace quelconque au cours du temps, nous pouvons construire des trajectoires à partir de sonogrammes ou de phonogrammes. FEITEN et GÜNZEL (FEITEN 1994) utilisent une notion similaire pour classifier les sons dans une base de données : Les sons sont d’abord analysés avec la transformée de Fourier rapide, par tranches temporelles successives. Les spectres sont rapprochés de ceux d’une grille de spectres types préexistants en utilisant un réseau neuromimétique. Chaque spectre est alors assimilé à un point de la grille. Le sonogramme étant constitué d’une succession de spectres, une trajectoire dans la grille est ainsi constituée. Une nouvelle grille contenant des trajectoires est utilisée alors pour classifier (à l’aide d’un second réseau neuromimétique) la trajectoire correspondant au son analysé.


 

3.5.      Expériences avec les trajectoires

 

Nous présentons ici les résultats obtenus avec les trajectoires, nous montrons ensuite l’analogie avec l’algorithme de Karplus-Strong (KARPLUS 1983), (JAFFE 1983).

 

 

Figure 3.10 : Un exemple de trajectoire

 

Figure 3.11 : Le signal correspondant à la trajectoire de la figure 3.10. (l’image a été réduite).

 

Dans l’exemple de la figure 3.11, le réglage de tension était de zéro (pas de tension) et la viscosité était à 1 (pas de viscosité), donc le signal est périodique, et son amplitude est constante (enveloppe rectangulaire). La fréquence fondamentale du signal est directement liée au nombre de points de la trajectoire et à la fréquence d’échantillonnage choisie.

 

Lorsqu’on augmente la tension, la trajectoire se modifie progressivement : la courbe se lisse, et tend vers un cercle, puis vers un point.

Voici (figure 3.12) des extraits du signal généré avec la même trajectoire (figure 3.10), et une tension de 4.

 

Figure 3.12

 

Au fur et à mesure de l’application de la tension sur les points de la trajectoire, celle-ci s’arrondit, se lisse. Les petites aspérités disparaissent en premier et le signal produit se rapproche de plus en plus d’une sinusoïde.

La vue en réduction de l’ensemble du signal donne la forme d’enveloppe représentée par le figure 3.13.

 

Figure 3.13

 

Le son obtenu est très proche d’un son de corde pincée, le spectre (figure 3.14 et 3.15) se simplifie au cours du temps. Les partiels harmoniques aigus sont les premiers à disparaître.

 

Figure 3.14 : Portion du spectre au début du signal.

 

Figure 3.15 : Portion du spectre pris vers la fin du signal.

 

Les fréquences du fondamental et des harmoniques n’ont pas changé (l’échelle de visualisation n’est pas exactement la même).

 

Figure 3.16

 

Ci-dessus (figure 3.16), le phonogramme résultant de la transformée élastique (cf. chapitre Transformée élastique) du son généré par la trajectoire, on voit nettement les harmoniques disparaître au cours du temps (de gauche à droite). L’échelle indique les fréquences. (à droite, image en niveaux de gris, à gauche, image en noir et blanc, tramée par méthode de propagation d’erreur, algorithme de FLOYD-STEINBERG (ROGERS 1988)).

 

En utilisant de l’inertie, dans l’expérience ci-dessous (figures 3.17, 3.18 et 3.19), l’inertie est réglée à 1, nous obtenons un signal dont la forme évolue périodiquement :

 

Figure 3.17 : Vue globale

 

Figure 3.18 : des vues du même signal à des échelles de réduction décroissantes :

 

 

 

Figure 3.19 : Détails du signal

 

Dans les premières expériences, nous avons simplement généré des sons périodiques, résultats directs de la circulation de point en point le long des trajectoires, en utilisant la projection des points sur l'axe horizontal.

Puis, nous avons appliqué la tension élastique (avec ou sans inertie) à la trajectoire elle-même, à chaque tour de la trajectoire un ou plusieurs cycles de tension : Le résultat est étonnamment proche des résultats obtenus par l'observation de points dans les réseaux de couplages, ce sont des sons proches des cordes pincées, des sons percussifs si l'inertie est faible, et entretenus si l'inertie est grande. Le rôle de l'inertie n'est pas le même que dans les réseaux de couplages. Sans inertie les réseaux de couplages excités par une impulsion se stabilisent sans résonner, alors que les trajectoires évoluent lentement vers un point (le centre de gravité) en se lissant au début, puis en prenant des formes ayant tendance à se rapprocher du cercle, et donnant un son de corde. Avec de l'inertie, les réseaux excités par une impulsion initiale résonnent comme une corde, alors que les trajectoires se contractent puis s'étendent alternativement, en reprenant à chaque cycle de contraction-expansion une position isomorphe à la position initiale (même forme, mais réduite) donnant un son entretenu plus longtemps, soumis à des variations cycliques d'amplitudes de chacun des partiels. C'est-à-dire théoriquement, une variation cyclique du timbre, mais à une vitesse telle que l'oreille la perçoit globalement comme un timbre nouveau, phénomène à rapprocher des modulations de fréquence et d'amplitude tels qu'ils ont été exploités dans la musique électroacoustique tant analogique que numérique.


4.         Couplages élastiques

 

Nous avons utilisé les couplages élastiques pour réaliser des liens souples dans des interfaces graphiques (par exemple dans les schémas d’organisation temporelle des phonogrammes). Nous les utilisons également pour transformer, analyser ou créer des sons.

 

4.1.      Des interfaces graphiques

 

Le trajet des flèches des schémas est constitué d'une série de points enregistrés lors du geste de l'utilisateur créant le lien.

 

Figure 4.1 : Schéma dont les trajets des flèches ne sont pas lissés.

 

Ces points forment une ligne brisée assez irrégulière (figure 4.1) que les couplages élastiques permettent de lisser (figure 4.2).

 

Figure 4.2 : Schéma de la figure 4.1 après le lissage par les couplages élastiques.

 

Puis une fois le lien construit et installé, ses extrémités doivent pouvoir subir des déplacements : par exemple lors du déplacement d'une cellule du schéma (d'un nœud du graphe) connectée par ce lien (figure 4.3).

 

Figure 4.3 : Nous avons déplacé une cellule du schéma de la figure 4.2.

 

Pour gérer ces déplacements, deux procédés ont étés mis en œuvre : pendant que l'utilisateur presse le bouton de la souris pour contrôler la position, le premier procédé propage le mouvement de l'extrémité du lien le long du trajet, avec une règle de répartition (ou déperdition du mouvement) mais si la position reste identique, le second procédé applique une règle de tension sur le trajet.

Différentes règles de tension entraînent des comportements rappelant des réactions physiques naturelles, telles l'élasticité, le poids, les torsions, ou artificielles telles la répulsion, les spirales, ou encore ayant un intérêt graphique et ergonomique, telles les styles de trajets (certains angles favorisés) ou encore la détection des cellules (les liens évitent de se superposer aux nœuds).

 

Figure 4.4

 

La figure 4.4 illustre le principe de base des couplages élastiques : La tension au point A, relié aux points B et C, est le vecteur AT = AB + AC.

En déplaçant le point A dans le sens de la tension, et en agissant de même pour tous les points connectés, la tension de chacun des points se réduit progressivement (figure 4.5).

 

Figure 4.5 : De haut en bas sont présentées trois étapes successives d'application des couplages élastiques : la première correspond au tracé original à la souris, la seconde représente le même trajet après quelques cycles de tension, et la dernière après stabilisation.

 

Nous décrivons maintenant différentes règles que nous avons implémentées.

La règle de tension utilisée pour la figure 4.5 est le déplacement de 1 pixel dans la direction de la tension indépendamment en x et en y :

 

déplacementunitaire = signe ( tension )

 

Pour donner un effet de poids, nous ajoutons un vecteur constant orienté vers le bas à la tension.

 

Figure 4.6 : Règle du poids

 

En appliquant la règle du poids, le trajet (figuré en 4.5) se déforme jusqu’à cette nouvelle position (figure 4.6).

 

déplacementpoids = signe(tension) + (0, 1)

 

Figure 4.7 : Règle de répulsion

 

En utilisant de la répulsion entre les points nous pouvons visualiser la position des points le long du trajet. La répulsion est produite en utilisant l’opposé du signe de la tension. Cette règle ne fait pas converger les points du trajet vers une position stable, au contraire, les points ont tendance à se repousser indéfiniment.

 

déplacementrépulsion = - signe(tension)

 

Figure 4.8 : Règle de torsion

 

Figure 4.9 : Règle de torsion, même flèche que pour la figure 4.8, mais avec une distance plus courte entre les extrémités de la flèche.

 

La règle de torsion (figures 4.8 et 4.9) applique une tension unitaire plus un poids  (un vecteur de module constant) changeant de direction, d'un huitième de tour, à chaque point.

 

Une règle arrivant rapidement à la stabilisation est la suivante :

 

déplacementrapide = tension / 2 + signe (tension)

 

On ajoute le signe de la tension pour conserver un déplacement tant que la tension n'est pas nulle : Si on applique uniquement la moitié de la tension (sans ajouter le signe de la tension), en calcul entier, les tensions ne se résorbent pas toutes, et des tensions unitaires (dont la moitié entière est nulle) sont conservées tout au long du trajet, résultant en une courbe dépendant de la position initiale. Le résultat stable de la tension rapide est le même que pour la tension unitaire, mais il est atteint plus rapidement.

 

 

Figure 4.10 : Règle de détection

 

Avec la règle de détection (figure 4.10), le trajet évite (ou tente d'éviter) les cellules.

La détection est calculée par un champ de vecteurs déterminé par la position des cellules et ajouté localement à la tension. La valeur des vecteurs du champ est dirigée vers l'extérieur de chaque cellule. Chaque point du plan détermine une clef d'accès dans une surface sensible mémorisant la liste des cellules présentes en ce point, les vecteurs du champ sont ensuite calculés d'après le cadre de chaque cellule.

 

Toutes ces règles sont calculées localement, mis à part la règle de détection qui fait appel à une représentation des champs des cellules, seules les coordonnées des points du trajet de la flèche sont utilisées et pour un point donné, nous utilisons ses coordonnées et les coordonnées de ses deux points voisins.

 

Les coordonnées sont notées dans des structures ayant la taille d'un pointeur. Par exemple sur une machine 32 bits, les coordonnées h et v (horizontale, verticale) sont notées chacune sur 16 bits. Ceci permet d'utiliser la place qui est prévue dans les routines de traitement de chaînages pour les références en plaçant directement un point (et non un pointeur vers un point) dans l'espace prévu pour désigner l'élément membre du chaînage. L'union PointPointeur permet d'accéder à un élément soit en tant que point, soit en tant que pointeur.

La structure elastique permet d'accéder directement au premier et au dernier maillon d'un chaînage bidirectionnel.

La structure chaineIter décrit l'état d'un parcours d'un tel chaînage et permet de simplifier l'écriture de boucles parcourant ce type de chaînage, ou de combiner plusieurs parcours simultanément.

 

La fonction DeplOrigineElastique (donnée ci-dessous) transmet le mouvement de l'origine le long du trajet de la flèche.

Le premier point du trajet est déplacé du mouvement imposé.

Puis le parcours est effectué depuis le second point jusqu'à l'avant dernier point de sorte que chaque point possède un précédent et un suivant.

Le parcours s'arrête également si le mouvement est totalement absorbé.

En chaque point, la tension est calculée, et si le mouvement imposé va dans le sens de la tension, le mouvement est appliqué au point puis décrémenté d'une unité (ou incrémenté si le mouvement était négatif).

La tension est calculée sur la position actuelle des voisins, mais comme le point précédent a déjà été traité, le calcul n'est pas parallèle, mais séquentiel.

 

void deplOrigineElastique(elastik, mouvrel)

elastique *elastik;

Point mouvrel;

{

       register PointPointeur chose;

 

       chose.ptr = elastik->fil.debut->chose;

       chose.p.h += mouvrel.h;

       chose.p.v += mouvrel.v;

       elastik->fil.debut->chose = chose.ptr;

       /* transmission du déplacement aux mailles suivantes... */

       {

            chaineIter mailles;

           

            iterPremier(&mailles, &elastik->fil);

            iterSuivant(&mailles); /* passe le premier */

            while( (mouvrel.h || mouvrel.v)

            && iterParcours(&mailles)

            && mailles.leMaillon->apres ) /* sauf le dernier */

            {

                  Point tension;

                  PointPointeur prec, suiv;

                 

                  prec.ptr = mailles.leMaillon->avant->chose;

                  suiv.ptr = mailles.leMaillon->apres->chose;

                 

                  chose.ptr = iterElement(&mailles);

                  tension.h = prec.p.h + suiv.p.h - (chose.p.h << 1);

                  tension.v = prec.p.v + suiv.p.v - (chose.p.v << 1);

                  if(mouvrel.h > 0 && tension.h > 0)

                  {

                        chose.p.h += mouvrel.h;

                        --mouvrel.h;

                  }

                  else if(mouvrel.h < 0 && tension.h < 0)

                  {

                        chose.p.h += mouvrel.h;

                        ++mouvrel.h;

                  }

                  if(mouvrel.v > 0 && tension.v > 0)

                  {

                        chose.p.v += mouvrel.v;

                        --mouvrel.v;

                  }

                  else if(mouvrel.v < 0 && tension.v < 0)

                  {

                        chose.p.v += mouvrel.v;

                        ++mouvrel.v;

                  }

                  iterChangeElement(&mailles, chose.ptr);

                  iterSuivant(&mailles);

            }

       }

}

 

Voici la procédure calculant et appliquant la moitié de la tension :

 

static void tendre1(elastik)

elastique *elastik;

{

       register PointPointeur chose;

       chaineIter avance;

       iterPremier(&avance, &elastik->fil);

       iterSuivant(&avance); /* passe le premier */

       while( iterParcours(&avance)

       && avance.leMaillon->apres )

       {

            Point tension;

            PointPointeur aprec, asuiv;

           

            aprec.ptr = avance.leMaillon->avant->chose;

            asuiv.ptr = avance.leMaillon->apres->chose;

           

            chose.ptr = iterElement(&avance);

            tension.h = aprec.p.h + asuiv.p.h - (chose.p.h << 1);

            tension.v = aprec.p.v + asuiv.p.v - (chose.p.v << 1);

            /* appliquer 1/2 de la tension.

              */

            chose.p.h += (tension.h >> 1);

            chose.p.v += (tension.v >> 1);

            iterChangeElement(&avance, chose.ptr);

            iterSuivant(&avance);

       }

}

 

 

4.2.      De la transformation, de l'analyse et de la création de sons

 

Le son est le résultat de la perception des variations de pression de l'air (ou du milieu transmettant le son).

L'idée est de simuler cette propagation du son dans un milieu artificiel constitué de points organisés en réseaux, reliés entre-eux par des couplages élastiques.

L'ACROE à Grenoble dirigé par Claude CADOZ effectue des expériences de synthèse par simulation de modèles physiques ou synthèse modale (DJOHARIAN 1993). Synthèses de cordes pincées, frottées, de billes. Un système tel que CORDIS-ANIMA (CADOZ 1993) permet de modéliser des systèmes, de les visualiser, de les écouter, et, par l’intermédiaire de transducteurs gestuels rétroactifs, de les manipuler.

La synthèse modale est également étudiée à l’IRCAM où le système MOSAIC (MORRISON 1993) est développé.

 

A priori nous voulons pouvoir constituer toutes sortes de formes de réseaux (différents types de maillages) mais nous commençons par les maillages carrés tridimensionnels les plus rapidement programmables, et permettant d'économiser de l'espace mémoire en encodant les liaisons implicitement d'après la position des points dans la mémoire.

 

Une structure décrivant un réseau contient la taille du réseau (le nombre de points dans chacune des trois dimensions) et deux espaces mémoires : l'espace présent et l'espace futur, contenant les coordonnées de chaque point.

Les deux espaces sont nécessaires pour simuler une évolution parallèle des couplages élastiques. Dans des implantations précédentes, pour les réseaux de couplages et les trajets de flèches, le parallélisme n'était pas important, et nous modifiions les coordonnées des points directement (les points étant traités séquentiellement). Mais pour cette simulation, il parait souhaitable de traiter les points parallèlement pour étudier la propagation des déformations dans le réseau.

Les calculs de tension sont effectués dans l'espace présent, les nouvelles positions mémorisées dans l'espace futur et enfin, une fois que tous les points sont calculés, les pointeurs des deux espaces sont permutés.

 

En chaque point du réseau, nous effectuons la somme des vecteurs ayant pour origine le point et pour extrémité un point voisin (voisin d'après le maillage et non la distance entre les points) cette somme est la tension en ce point.

 

tension (p) = S (vi - p) où p est un point, et les v1, ... vn les points voisins.

 

Le déplacement du point est calculé d'après la tension : Par exemple en appliquant un déplacement d'une unité dans le sens de chaque composante non nulle de la tension.

Cette règle (de déplacement unitaire) conduit à une stabilisation du réseau, quel que soit l'état initial, dans une position de repos unique (ou un ensemble de positions proches du repos, cycliques et de faible amplitude, dépendant du nombre de couplages par point et du fait de la discrétisation de l'espace). Cette position de repos est déterminée uniquement par la position des points fixes du réseau.

Les points fixes sont les extrémités des réseaux à une dimension (droites), les coins des plans, les sommets des volumes.

 

Quand les points ont des coordonnées mémorisées en nombres flottants, nous pouvons régler un coefficient (entre 0 et 1) appliqué à la tension pour calculer le déplacement :

 

déplacement = tension (p) * coefficient.

 

Avec des nombres entiers nous appliquons simplement un décalage sur la tension, c’est-à-dire une division entière par une puissance de 2. La perte d’information avec les nombres entiers est telle que nous sommes obligés finalement d’utiliser une représentation en nombres flottants pour pouvoir exploiter les petites vibrations et être en mesure de les amplifier (ou de les atténuer).

 

Nous pouvons également introduire une notion d’inertie, en utilisant un coefficient appliqué à la vitesse précédente pour l’ajouter au déplacement.

 

vitesse (p) = position(p) - passé(p)

(ou le passé est la position précédente).

 

déplacement = inertie * vitesse (p) + tension (p) * coefficient.

 

Figure 4.11 : Calcul de la nouvelle position d’un point du réseau

Le point A' est la position passée de A.

A'A = V (la vitesse). V multipliée par l'inertie donne I.

Les points B et C voisins de A permettent de calculer T la tension.

Enfin, la tension T multipliée par un coefficient donne t, et la somme de I et de t donne comme résultat A'', la nouvelle position du point A.

 

Les règles de tensions que nous avons appliquées jusqu'alors laissent les n dimensions d'espace indépendantes : Le déplacement d'un point parallèlement à un axe n’entraînant aucune modification des coordonnées des points sur les autres axes. De ce fait, la transmission du signal perpendiculairement à une droite donne le même résultat que la transmission parallèle à la droite.

 

4.2.1.         Filtrage

 

Nous construisons un réseau unidimensionnel, une droite fixée à ses extrémités. Nous excitons le système en imposant un déplacement à l’un des points (par exemple une des extrémités, voir figure 4.12). Le déplacement imposé peut provenir directement d’un signal enregistré ou généré auparavant.

 

Figure 4.12 : Filtrage du signal par un réseau unidimensionnel

 

Puis pour chaque échantillon, nous lançons le procédé de tension élastique (une ou plusieurs fois), et nous enregistrons dans un nouveau fichier les déplacements d’un autre point du réseau.

Sans inertie, le système se comporte alors comme une série de filtres passe bas. Avec l’entrée à une extrémité, plus le point de sortie est éloigné, plus les aigus sont filtrés. En traitant un signal harmonique de cette façon, nous pouvons (en sélectionnant correctement la longueur du réseau, la tension et la position d’écoute) extraire le fondamental.

 

4.2.2.         Synthèse

 

Avec le même réseau que précédemment (§ Filtrage), en ajoutant de l’inertie et en prenant en entrée un signal impulsionnel, nous obtenons la synthèse de sons proches de cordes pincées. La longueur de la corde est équivalente à la longueur du réseau, la tension de la corde au coefficient de tension des couplages élastiques. La résonance du système est liée à l’inertie : avec une inertie nulle, le système ne fait qu’amortir les vibrations, et les vibrations de fréquences élevées sont les premières à disparaître. Avec une inertie proche de 1 (mais inférieure à 1) nous obtenons des résonances de durées variables.

 

Figure 4.13 : Signal donné par le 25ème point d’une droite de longueur 50, coefficient de tension : 0.1, inertie : 0.99, durée ≠ 50 ms. L’excitation a été donné par le signal impulsionnel de la figure 4.15.

 

Figure 4.14 : 25ème point d’une droite de longueur 50, coefficient de tension : 0.1, inertie : 0.999, durée ≠ 400 ms.

 

Figure 4.15 : les 20 premières millisecondes environ, du signal d’impulsion.

 

Le signal impulsionnel de la figure 4.15 fut dessiné à l’aide de la souris et n’est pas vraiment une impulsion, et le silence n’est pas non plus totalement un silence. Il est impossible d’obtenir physiquement un signal impulsionnel strict : Il faudrait que la durée de l’impulsion soit infiniment proche de zéro. Pratiquement, un signal tel que celui-ci est de nature impulsionnelle.

 

Figure 4.16 : Détail du signal de la figure 4.14

 

Dans le signal résultant (figure 4.16), les 20 premières millisecondes sont quasiment identiques dans les deux cas de cette expérience, ensuite le premier résultat s’éteint, et le second continue à osciller. Les premières vibrations semblent apparaître avant l’impulsion, c’est en fait parce que le signal d’entrée n’a pas une amplitude nulle au départ.

 

Les points fixes peuvent être supprimés en rendant cyclique le réseau de points, par exemple, une droite peut devenir un anneau, un plan deviendrait torique, etc...

Prenons le cas d'un anneau de n points, chaque point i connecté aux points i + 1 modulo n et i - 1 modulo n. Initialisons toutes les positions à zéro (dans une dimension), sauf pour un point contenant une valeur impulsionnelle initiale arbitraire. Puis appliquons itérativement la procédure de tension en observant l'évolution des positions des points : La propagation de l'impulsion est symétrique, et les coordonnées augmentent indéfiniment dans le sens de l'impulsion initiale. Si nous introduisons une seconde valeur initiale (opposée à la première), les tensions se propagent également symétriquement mais cette fois, le système est globalement stable puisque la somme des positions reste nulle. Certains points particuliers peuvent apparaître (suivant le nombre de points n, et la position des impulsions initiales) : les nœuds du système vibratoire, dont la position est toujours nulle, les autres points oscillent, et finissent par se stabiliser (en fonction des paramètres de tension et d'inertie).

 

Nous avons implanté une règle où les dimensions interagissent : La tension est transformée en déplacement en appliquant une fonction de répartition :

 

Par exemple :

 

 

f ()  = 

 

 

Nommons les coefficients de répartition 1/2 et 1/16 respectivement principal et secondaire. Avec un coefficient secondaire à zéro, les dimensions sont indépendantes. Avec des coefficients trop grands, le système est instable et explose rapidement. Ceci est dû à une augmentation de l'énergie à chaque étape du processus. Les résultats obtenus en réduisant les coefficients (pour avoir une déperdition d’énergie) montrent un comportement chaotique du système. Les signaux résultants sont difficilement exploitables.

 

4.3.      Le carré de la distance

 

Le carré de la distance euclidienne est calculé beaucoup plus vite que la distance elle-même lorsque l’on connaît les coordonnées cartésiennes de deux points. Ceci ressort immédiatement de la formule :

 

     

 

Dans la formule calculant l’effet d’un ressort deux distances apparaissent : la longueur du ressort au repos, et la longueur actuelle du ressort. Dans le calcul des longueurs des ressorts, nous avons substitué la distance par son carré et observé les effet visuels et sonores de cette transformation. Nous voyons immédiatement que les formes des systèmes de ressorts ne sont pas fondamentalement influencées par ce changement. Trois ressorts en triangle vont toujours rester en triangle, et l’effet de couplages élastiques appliqués sur eux les feront tourner, globalement de la même manière.

Le cercle, défini comme étant l’ensemble des points situés à une distance donnée d’un point particulier, garde un aspect circulaire habituel lorsque la distance est définie comme suit :

 

     

 

Alors qu’avec une métrique quelconque, le cercle prend un aspect différent. Par exemple, lorsque la distance est définie par la somme des valeurs absolues des différences des coordonnées, le cercle prend un aspect de losange. Le comportement des réseaux de ressorts serait alors modifié.

 

4.4.     Simulation de ressorts

 

Pour la simulation de ressorts, nous avons typé les liens existants pour la simulation de couplages élastiques, et, dans la fonction de calcul de l’influence des liens sur les nœuds, nous calculons la tension appliquée par le ressort en multipliant la différence entre la longueur actuelle du ressort et sa longueur de repos par un coefficient mémorisé dans la structure représentant le ressort.

Les longueurs actuelles de chacun des ressorts sont calculées avant de traiter les tensions appliquées sur les noeuds.

 

 

      tension = (longueur_actuelle - longueur_au_repos)

            * coefficient_du_ressort

 

 

Si la tension est supérieure à 1, la valeur 1 est forcée[50]. Ceci permet d’éviter les explosions. En effet, lorsque la valeur de la tension est supérieure à l’unité, les déplacements des points influencés par cette tension vont provoquer une élongation du ressort plus grande que l’élongation originale, et dans les cycles suivants, les valeurs obtenues croîtront indéfiniment, provoquant l’explosion du système.

 

La suite du calcul est identique à celui des couplages. Finalement, les couplages sont des ressorts dont la tension est constante, ou plutôt, les ressorts sont des couplages dont la tension varie dynamiquement en fonction de la longueur.

 

Pour la production de signaux à partir de ces réseaux, les variations de tension des couplages élastiques correspondent à des variations de fréquence des sons obtenus. Les ressorts permettent donc d’introduire une variation de la fréquence.

 

Voici des exemples de sons produit par des simulations de ressort. Dans ces expériences, nous avons construit le système le plus simple possible : un seul ressort, attaché à une extrémité par un point fixe et à l’autre à un point mobile.

 

Figure 4.17 : Un réseau avec un ressort et un récepteur.

 

Dans le schéma de la figure 4.17, Le point fixe maintenant le ressort est figuré par un carré, le point mobile par un cercle, et à droite, l’icône représente un récepteur, chargé d’enregistrer les longueurs successives prises par le ressort au cours de la simulation. La ligne pointillée indique la liaison entre le ressort et le récepteur, elle n’apparaît (en plein) que lorsque l’on déplace le récepteur.

Les longueurs sont directement enregistrées en tant qu’amplitudes instantanées du signal produit.

Lorsque l’on déplace un des points, et que l’on lance la simulation, le point mobile se met à osciller. Nous montrons ci-dessous (figure 4.18) le phonogramme résultant de l’analyse par la transformée élastique du signal produit par une grande déformation du ressort (environ le double de la longueur de repos).

 

Figure 4.18 : Phonogramme résultant de la transformée élastique du signal produit par le ressort de la figure 4.17

 

 Le phonogramme montre une baisse d’amplitude régulière[51] du début à la fin et au niveau des fréquences, une descente rapide suivie d’une faible remontée.

La chute initiale de fréquence s’explique intuitivement par la diminution progressive des valeurs de tension : la viscosité fait perdre de la vitesse, donc diminue l’amplitude, et entraîne des élongations du ressort de moins en moins grandes. Le temps mis par le ressort pour effectuer un cycle de variation de longueur augmente, et la fréquence baisse. Mais que ce passe-t-il pour que subitement la fréquence remonte ?

 

Ci-dessous (figure 4.19), un détail du point de rebroussement d’une courbe de fréquence.

 

Figure 4.19 : L’échelle des fréquences est exprimée en Hertz.

 

La figure 4.19 représente la transformée élastique d’un son produit par un ressort de coefficient 0.0001, viscosité 0.99999 avec la règle de calcul de la longueur par la distance euclidienne[52]. Les trois lignes correspondent à des harmoniques. Le phénomène, à cette échelle apparaît pratiquement symétrique dans le temps, mais on peut dire la même chose d’un simple signal sinusoïdal.

Le Point de rebroussement correspond au changement de régime d’oscillation.

Lorsque la déformation initiale est suffisamment grande pour que le ressort soit comprimé jusqu’à une longueur nulle, le point mobile est projeté vers le point fixe, et le dépasse. Il est alors repoussé de l’autre coté du point fixe, et le cycle recommence. Ceci correspond à un premier régime d’oscillation[53]. Le second régime apparaît lorsque la déformation initiale est faible. Le cycle du second régime est une oscillation autour de la longueur de repos, sans franchir le point fixe.

 

En une seule dimension, nous pouvons segmenter la droite en quatre zones séparées par le point fixe et les deux points situés de part et d’autre du point fixe, à la distance correspondant à la longueur de repos (figure 4.20).

 

 

attraction repos répulsion point-fixe répulsion repos attraction

------------->+<----------------+---------------->+<------------

 

Figure 4.20

 

En deux dimensions, la zone de répulsion forme un disque, et la zone d’attraction un anneau sans borne externe.

Le point de rebroussement observé dans la courbe d’évolution de la fréquence correspond au changement de régime d’oscillation (du premier au second régime), dès que la vitesse n’est plus suffisante pour affronter la répulsion avant le point fixe et passer dans la zone de répulsion opposée au point fixe.

 

Avec le même système (les mêmes paramètres pour les coefficients des ressorts et la viscosité), nous obtenons des résultats variant selon les conditions initiales : la position donnant un étirement du ressort, et la vitesse initiale du point (en module[54] et en direction) influençant le régime d’oscillation.

 

Lorsque la déformation initiale du ressort est faible, ou lorsque la viscosité est à 1, la fréquence reste constante.

En appliquant une viscosité différente selon les axes (figure 4.21), par exemple 1 en y et une valeur inférieure à 1 en x, la baisse de fréquence dépend de la direction dans laquelle oscille le ressort :

 

Figure 4.21 : La fréquence (axe vertical) varie d’environ 2000 à 400Hz, la durée totale est de 4 secondes.

 

En faisant un zoom sur la partie du signal effectuant la montée (figure 4.22), nous obtenons ceci :

 

Figure 4.22

 

Des harmoniques apparaissent (figure 4.22), elles étaient masquées dans l’image précédente par l’amplitude importante du début du signal, et la contrainte de l’échelle des gris limitée à 126 niveaux, elles sont accentuées ici par le fait que les valeurs de gris de cette image sont obtenues directement sans diviser le cumul par la fréquence des résonateurs. Les paramètres du ressort étaient de 1.10-6 pour le coefficient du ressort, et 0.9999 pour la viscosité en x et 1 pour la viscosité en y.

Les courbes précédentes montrent des paliers : la baisse de fréquence n’est pas régulière : elle est nulle quand la direction de l’oscillation est parallèle à l’axe des y, et maximale lorsqu’elle est parallèle à l’axe horizontal.

 

4.5.     Imprécision du calcul dans la simulation

 

Dans la simulation, le temps étant discrétisé, la variation de vitesse (supposée continue dans un modèle physique), est ici approximée par une variation par paliers, le calcul est effectué comme si la vitesse restait constante pendant chaque intervalle de temps équivalent à un échantillon. Ceci est valable autant pour la simulation du ressort dont nous analysons le produit, que pour la simulation des couplages élastiques de la transformée qui permet l’analyse elle-même.

Un pas de simulation du mouvement revient à :

   • Calculer l’accélération

   • Augmenter la vitesse de l’accélération (multipliée par l’unité de temps).

   • Augmenter la position de la vitesse (multipliée par l’unité de temps).

Si l’accélération est nulle, le mouvement est calculé correctement.

L’échelle de discrétisation du temps doit donc être choisie assez fine pour que la perte dans la valeur de la vitesse soit faible.

 

4.6.      Résonateurs à couplages élastiques

 

Les graphes de couplages élastiques peuvent produire des sons, mais peuvent également les filtrer, et permettre ainsi de les analyser. Nous exposons ici notre démarche pour la réalisation d'une connexion entre la représentation des sons par les phonogrammes et les capacités des couplages élastiques à produire et analyser les sons. Nous pouvons ainsi utiliser directement les graphes de couplages pour construire les phonogrammes (analyse par transformée élastique), et utiliser les phonogrammes pour commander le déclenchement des résonateurs pour la synthèse.

 

4.6.1.         Expérience avec les graphes de couplages élastiques

 

Nous avons fabriqué deux bancs de 10 oscillateurs, linéaires, formés de 7 points chacun, les extrémités étant fixes (les points fixes sont représentés par des carrés, les points mobiles par des cercles).

Nous avons choisi une règle de tension qui utilise pour chaque point : la position du point, la vitesse du point, et une variable similaire à un indice de frottement, induisant une perte d'énergie (pour se ramener à un système dissipatif).

 

La règle de couplage est la suivante :

 

Pour chaque point (traité en parallèle avec les deux variables de position présente et future) :

• accélération = somme des vecteurs formés par le point et chaque voisin, pondérés par la tension des liens.

• diminuer la vitesse du point de la valeur du frottement du point (incrémenter si la vitesse est négative, décrémenter si elle est positive).

• ajouter l'accélération à la vitesse.

• et enfin, ajouter la vitesse à la position.

 

La procédure calculant cette règle est donnée en annexe.

 

 Chaque lien possède deux valeurs de tensions (une pour chaque sens, mais en fait, dans les expériences suivantes, les valeurs de tension ont toujours été réglées identiques pour tous les liens de chaque résonateur, et identique dans les deux sens). Nous parlerons donc de la tension d'un résonateur.

 

Dans cette expérience (figures 4.23 à 4.29), les tensions vont de 0.01 à 0.1 (de gauche à droite) augmentant par pas de 0.01, et la variable frottement est réglée à 0.001 pour tous les points.

 

Figure 4.23

 

Les symboles en dessous des résonateurs représentent des récepteurs (dont nous avons masqué les liens), ils permettent d'indiquer que l'on veut "écouter" des points et/ou des liens. Chaque récepteur génère un fichier d'échantillons (Nous décrirons l'interface graphique permettant de construire de tels graphes dans paragraphe Interface graphique pour les graphes de couplages élastiques ci-dessous).

Quand on relie un récepteur à un point, le récepteur cumulera à sa valeur de sortie la vitesse de ce point (différence entre sa position présente et future). Quand on relie un récepteur à un lien, c'est le vecteur formé par le lien qui est cumulé. On peut relier autant de points et de liens que l'on veut à chaque récepteur.

 

En déplaçant un point sur chaque résonateur (le premier point mobile en haut), nous déséquilibrons les résonateurs, et en enregistrant les sons ainsi produits (par les derniers points mobiles en bas), nous pouvons analyser les spectres des différents résonateurs : Les fondamentales valent respectivement : 180, 255, 316, 362, 406, 444, 480, 513, 546, et 576 Hertz environ (avec une fréquence d'échantillonnage réglée à 22050 Hertz).

 

Tous les spectres obtenus sont constitués de 5 partiels.

 

Par exemple, le cinquième résonateur vibrant seul donne un spectre contenant les fréquences 406, 787, 1114, 1367, et 1528 Hertz. Les valeurs des fréquences sont approximatives à quelques Hertz près.

Le nombre de partiels doit être en relation avec le nombre de points du résonateur, et leurs amplitudes dépendre du point écouté. Le nombre de partiels dépend des régimes oscillatoires possibles du résonateur, nous verrons apparaître les différents régimes au cours de l'expérience.

 

Connaissant dorénavant les fréquences propres des résonateurs, qui sont maintenant en position de repos, nous émettons un signal sinusoïdal sur chacun d'eux, à l'aide d’un émetteur (symbole en bas du graphe ci-dessous). Les émetteurs peuvent être connectés à un ensemble de points, et leur rôle est de modifier la position de ces points, avec la valeur des échantillons provenant d'un fichier. Ils permettent ainsi d'agiter le système avec un signal extérieur.

Les résonateurs dont un régime oscillatoire possède une fréquence correspondant à la fréquence du signal excitateur oscillent avec la plus grande amplitude. Sur le schéma ci-dessous, nous voyons nettement le cinquième résonateur réagir à sa fréquence fondamentale, en prenant un régime oscillatoire possédant un seul ventre, le point central, les point fixes correspondant aux nœuds.

 

Figure 4.24

 

Tous les résonateurs sont soumis au même signal sinusoïdal à 406.5 Hertz. Les résonateurs 1 et 2 ont une amplitude plus forte que la moyenne, ils possèdent un partiel de fréquence proche. Remarquons également les résonateurs à gauche du cinquième (les 3 et 4) qui montrent un léger ventre (leur fréquence propre n'est pas très éloignée, les filtres que constituent ces résonateurs ne sont peut-être pas extrêmement sélectifs).

 

Figure 4.25

 

Réponse au 786 Hertz : le second partiel du cinquième résonateur, nous observons un nœud (de vibration) au point central qui paraît immobile, et les deux ventres sont constitués de deux points chacun.

 

Figure 4.26

 

Réponse au 1115.4 Hertz : Le troisième partiel du résonateur 5, avec deux nœuds de vibration, et le deuxième partiel du résonateur 10, avec un nœud central. Pendant l’animation, les nœuds de vibration ne bougent pratiquement pas.

 

Figure 4.27

 

Réponse au 1368.6 Hertz : le résonateur 5 est dans son quatrième régime oscillatoire. Le dernier partiel du résonateur 4 : 1364 Hertz, est proche de cette fréquence, mais l'amplitude est moins forte.

 

Figure 4.28

 

Réponse au 1528 Hertz : nous voyons nettement le dernier régime oscillatoire du cinquième résonateur. L'amplitude est plus faible que pour les autres régimes, cela est dû à deux causes combinées : l'amplitude du signal excitateur est plus faible, et l'amplitude de cette fréquence dans le spectre du signal de résonance était déjà plus faible.

 

Figure 4.29

 

Ci-dessus, un nouveau banc de 10 résonateurs, avec des tensions variant de 0,11 à 0,20, et la réponse à un son composé de deux sinus à 650 et 750 hertz.

Les fondamentales des résonateurs sont :

604, 630, 655, 681, 705, 728, 750, 769, 794 et 814.

Les résonateurs 3 et 7 qui ont les fondamentales les plus proches ont pris leur régime fondamental avec la plus grande amplitude.

La hauteur du résonateur (la distance entre les points) n'influence pas sa (ou ses) fréquences propres.

Avec les valeurs des fréquences obtenues en regard des réglages de tensions, nous avons déterminé la formule donnant la tension à appliquer pour obtenir une fréquence particulière :

 

C'est une simple parabole, ayant cette forme, pour tous les partiels :

 

   tension =

 

où f est la fréquence souhaitée, Fe est la fréquence d'échantillonnage, et k une valeur, spécifique de chaque régime d'oscillation.

Dans le cas de cette expérience, les valeurs de k sont approximativement (valeurs moyennes sur les résultats d'analyse des sons produits par les 20 oscillateurs ci-dessus) :

 

              

               k        k.Fe2 avec Fe=22050 Hertz

fondamental : 0,0068   3 308 790,66

2nd partiel : 0,0256   12 480 561,88

3ème "        0,0520   25 292 299,92

4ème "        0,0791   38 472 792,01

5ème "        0,0947   48 366 230,17

 

 

Un fait remarquable est que les partiels ne sont pas harmoniques.

Par exemple pour la valeur de tension 0,11 le fondamental est à 604 Hertz et le 2nd partiel est à 1170 (ce qui fait moins d'une octave, mais plus de onze demi-tons).

 

Nous pouvons maintenant construire automatiquement des systèmes de résonateurs adaptés aux fréquences spécifiques des phonogrammes. Nous pensons détecter simplement les résonateurs excités en faisant la somme des valeurs absolues (ou des carrés) des amplitudes des ventres des régimes fondamentaux, sur chaque tranche d'échantillons correspondant à une colonne de pixels dans le phonogramme.

Nous devons également analyser des systèmes vibratoires plus simples, faire varier le nombre de points et les règles de couplage, pour savoir si la mise en œuvre d'un tel système d'analyse sera moins coûteuse, en temps de calcul, que la transformée de Fourier, qui, quand elle est effectuée pour toutes les fréquences d'un phonogramme, s'avère excessivement lente.

 

Quand à la synthèse, nous pourrons mettre en vibration des résonateurs appariés aux résonateurs écoutés (de mêmes caractéristiques) avec un lien unidirectionnel, pour éviter les bruits d'attaque. En effet, quand on excite un résonateur avec le son qu'il a lui-même produit, le son produit n'est plus un son percussif, comme quand on déséquilibre le système artificiellement, mais un son avec une attaque plus douce et qui peut être entretenue, donnant la même différence que celle existant entre le son produit par les cordes pincées et celui des cordes frottées.

En attaquant au contraire les résonateurs productifs directement, nous devrions obtenir quelque chose similaire aux sons que produisent les Steel bands (Orchestres populaires de percussions faites avec des moyens précaires, boîtes de conserves, fonds de tonneaux martelés, etc... ) Utilisant une succession de sons percussifs très rapprochés et de faible amplitude, pour simuler les sons entretenus, et utilisant la multitude de fréquences des différentes percussions pour reproduire le spectre des instruments classiques, voir, la sonorité d'un orchestre complet.

 

4.7.      Génération de trajectoires à partir de réseaux de couplages.

 

La génération de trajectoires, au sens expliqué dans le chapitre précédent à partir d’un réseau de couplages élastiques peut être vue de plusieurs façons : par exemple, la simple conversion d’un réseau circulaire (c'est-à-dire un réseau où les points sont reliés entre eux pour former un cycle) dans le format de données des trajectoires, ou encore, la génération d’une trajectoire dont l’exécution produira le même son que le son produit par un ou plusieurs points du réseau.

La première solution ne semble pas très intéressante, d’une part parce qu’elle ne pourrait pas s’appliquer à tous les réseaux (les réseaux ne sont pas circulaires a priori), et d’autre part, le nombre de points d’une trajectoire (lié à la fréquence) est beaucoup plus élevé en général que le nombre de points d’un réseau.

La deuxième solution est plus intéressante du point de vue de l’exploration graphique des sons. Reconstituer une trajectoire à partir des caractéristiques du réseau (les points, les liaisons, les paramètres des couplages), nous semblait impossible. Nous avons exploité directement les mouvements des points pendant la simulation pour générer des trajectoires.

Le signal produit par une trajectoire n’est qu’une projection sur une dimension de la position du mobile. Pour reconstituer une trajectoire intéressante, c'est-à-dire à deux dimensions, et non une trajectoire linéaire, il nous fallait une seconde dimension. Nous avons utilisé la vitesse instantanée des points comme seconde dimension.

 

La trajectoire ci-dessous est construite dans l’espace position/vitesse (ou espace des phases) à partir du déplacement d’un nœud couplé par un ressort à un nœud fixe.

La position est l’abscisse du nœud (en abscisse également dans la trajectoire), la vitesse enregistrée est la différence entre deux positions successives au cours de la simulation (représentée en ordonnée). Des intersections peuvent apparaître dans les trajectoires car elles ne sont qu’une projection bidimensionnelle des trajectoires de l’espace des phases qui possède quatre dimensions.

 

Figure 4.30

 

La trajectoire (figure 4.30) débute à l’extérieur et son amplitude diminue à cause de la viscosité.

Sans viscosité, la trajectoire est fermée ou ne perd pas d’amplitude comme dans les exemples suivants (figures 4.31 et 4.32) :

 

           

Figure 4.31                                                                           Figure 4.32

 

Suivant les vitesses initiales, les trajectoires obtenues avec des systèmes équivalents sont très variables :

 

         

Figure 4.33                                                                           Figure 4.34

 

            

Figure 4.35                                                                           Figure 4.36

 

En augmentant la viscosité la trajectoire semble s’enrouler autour d’un point :

 

         

Figure 4.37                                                                           Figure 4.38

 

Toutes les trajectoires ont été générées pour une période choisie arbitrairement de 1000 échantillons.

 

4.8.     Conversion des trajectoires en réseaux élastiques circulaires

 

Une trajectoire est constituée d’une suite de points reliés deux à deux par des couplages élastiques. Chaque point est relié au suivant et au précédent, et le dernier point est relié au premier pour former un cycle. Ces liaisons sont représentées de deux façons : Par des structures et des chaînages comme dans les couplage élastiques utilisés dans la partie graphique, et par un réseau à maillage linéaire en mode torique. La conversion vers un réseau élastique est donc triviale. Le seul problème est le nombre de points des trajectoires, beaucoup plus important que celui des réseaux. Cette conversion est techniquement possible mais ne présente pas d’intérêt particulier.

 

4.9.     Interface graphique pour les graphes de couplages élastiques

 

Le but de l'interface est de permettre la construction rapide de graphes : des points, reliés par des liens orientés, des émetteurs et des récepteurs, reliés aux points et aux liens. Pour limiter les manipulations avec la souris nous avons choisi d'interpréter les coups de souris en fonction de leurs caractéristiques : la forme, la taille, la position et l'instant de départ, sans avoir à sélectionner un outil particulier à chaque type d'action.

Nous distinguons les coups de souris formant une boucle, des autres, ouverts : les boucles ont leurs points extrêmes proches (valeur absolue des différences des coordonnées inférieure à un seuil).

Quand un clic débute dans une surface vide, nous enregistrons la liste des positions du curseur tant que le bouton reste appuyé (procédure mise au point pour la création des schémas de couplages). Puis nous calculons le cadre de cette trace (le plus petit rectangle aux côtés parallèles aux axes englobant entièrement la trace). Si le cadre est petit  (hauteur et largeur inférieures à une taille donnée), nous créons un point, le point sera mobile si la trace forme une boucle (comme les cercles représentant les points mobiles), sinon le point sera fixe. Si le cadre est plus grand (environ de la taille des émetteurs et récepteurs), nous créons un émetteur pour les boucles et sinon un récepteur.

Si la trace est très dense (gribouillage, mesuré en fonction du rapport entre la longueur de la trace et le périmètre du cadre de la trace), nous effaçons les éléments dont le cadre est entièrement inclus dans le cadre de la trace.

Nous pouvons ainsi créer et détruire les points, de différents types, en utilisant un seul (l'unique) bouton de la souris. Maintenant, pour relier les points entre eux, il suffit de commencer la trace à l'intérieur du cadre d'un point, mais cette action peut avoir plusieurs interprétations :

Si la trace commence par un mouvement vers le bas, nous débutons le processus de liaisons des points, qui aboutit si le bouton est relâché avec le curseur dans le cadre d'un point connectable au point initial (ou sur une poignée  (cf. ci-après) d'un lien, dans le cas où on relie un récepteur à un lien), et qui est interrompu si le bouton est relâché en dehors de tout point. Les points et les liens montrent leur sélection respectivement en inversant leur cadre et en augmentant la taille des poignées, ceci pour donner un feed-back à l'utilisateur lors de l'établissement d'une connexion.

Si la trace commence par un mouvement vers le haut, le point est déplacé (comme si on devait le décrocher), et suit les mouvements du curseur. Si ces mouvements sont trop brusques, le point est agité, secoué (mesure du rapport entre le nombre de changements de direction du curseur et la longueur courante de la trace), les liens de ce point sont alors détruits.

Enfin, si la trace commençant sur un point reste immobile un certain temps, sans mouvements ni vers le bas, ni vers le haut, le processus de couplage élastique est appliqué au graphe complet.

 

Pour faciliter encore la construction des graphes, nous relions automatiquement le point en cours de création au point créé précédemment si l'intervalle de temps entre les créations est réduit (en dessous d'une seconde environ). Ceci permet de créer des chaînes en cliquant une seule fois par point, et n'entrave pas la construction d'autres formes de graphes.

Lorsqu'un point est effacé (gribouillé), tous ses liens sont supprimés. Pour effacer, nous avons également donné la possibilité de cliquer sur un point en tenant la touche majuscule (équivalent d'un second bouton hypothétique), ceci permet en particulier d'avoir une commande pour effacer un lien particulier. Les liens sont désignés par leurs poignées. Les poignées sont visualisées par deux petits disques sur le trajet du lien, l'un est au centre du trajet, et l'autre marque le premier quart du trajet, leurs positions dissymétriques permettent de visualiser le sens du lien (significatif dans le cas de tensions distinctes selon le sens). Idéalement, les poignées devrait être placées symétriquement dans le cas où les tensions sont égales (ce qui n'est pas encore respecté). Les liens dont une des valeurs de tension est nulle voient leur trajet interrompu à la poignée située du côté du point ne subissant pas d'influence (sauf pendant l'animation, où pour accélérer l'affichage, nous limitons les calculs en utilisant une autre procédure).

Il reste toutefois à améliorer la façon dont les valeurs numériques sont saisies et affectées aux points et aux liens. Pour l'instant, une fenêtre indépendante, (non modale), affiche ces valeurs qui sont recopiées au moment de la création d'un élément, ou lors de la pression de la touche de validation (les valeurs sont recopiées dans le point sélectionné). La sélection est toujours le dernier point créé, déplacé ou désigné par le début d'une procédure de liaison. La touche de tabulation permet également de changer la sélection. Il devrait être possible de sélectionner des ensembles de points et de liens, pour leur réattribuer globalement de nouvelles valeurs.


 

5.         Transformée élastique

 

L'utilisation de la transformée de Fourier pour l'analyse des sons en vue de produire des phonogrammes s'avère inexploitable à cause du temps de calcul. Nous décrivons ici les expériences et mises au point effectuées pour la réalisation d'un banc de résonateurs à couplages élastiques permettant de produire des phonogrammes à partir de sons échantillonnés.

 

5.1.     Analyse acoustique directe

 

Des physiciens du siècle dernier ont réalisé des appareils, constitués de résonnateurs (sic) de fréquences différentes pour analyser la composition des sons complexes (cf. Extrait sur les phénomènes physiques en acoustique, étude expérimentale du timbre des sons, en annexe).

Nous avons pensé utiliser la propriété physique du son qu’est la réfraction des rayons sonores pour bâtir un appareil permettant la décomposition spectrale immédiate des sons. En effet, on peut construire des lentilles convergeantes (en collodion empli d’hydrogène) pour concentrer les ondes sonores. Pourquoi ne pas construire un prisme sonore ? Les prismes de verre décomposent les rayons lumineux à cause de la différence de vitesse de propagation des différentes longueurs d’ondes, induisant une variation des angles de réfraction. Pour le son, le phénomène est similaire.

Le problème, est que les indices de réfraction, pour les ondes sonores, calculés entre des milieux tels que l’air et le verre, prennent des valeurs telles que le phénomène de réfraction disparaît presque totalement au profit de la réflexion. D’autre part, pour mener des expériences de ce type, un laboratoire spécialisé serait nécessaire. Ces éléments et aussi le manque de données sur les différentes vitesses de propagation du son (et des ultrasons) dans divers milieux nous ont fait abandonner cette piste.

 

Nous nous sommes donc orientés vers une simulation de résonateurs basés sur les couplages élastiques.

 

5.2.      Procédé d'analyse

 

Voici la formule que nous avons testée en premier, elle est directement issue des règles de couplages des réseaux de couplages décrits dans le chapitre précédent, mais elle est simplifiée pour optimiser les calculs et convenir à une forme unique de résonateurs (les liens de couplage sont implicites).

 

accélération = (amplitude - 2 * position) * tension

vitesse += accélération

position += vitesse

si vitesse < 0

            vitesse += frottement

sinon

            vitesse -= frottement

 

si position > 0

            cumul += position

sinon

            cumul -= position

 

• amplitude est la valeur de l’amplitude instantanée provenant du signal à analyser.

position, vitesse, tension et cumul sont des valeurs propres à chaque résonateur, le cumul est initialisé à 0 à chaque fenêtre du signal.

frottement est une variable globale pour tous les résonateurs. Elle est contrôlable dans l’interface.

• Et enfin accélération est une variable locale temporaire.

 

Cette séquence est appliquée pour chaque échantillon provenant du signal à analyser (valeur de l'amplitude), et pour chaque résonateur.

Cette formule décrit le passage d'un instant t à l'instant t+1, par exemple la ligne :

 

            position += vitesse

 

Est une simplification de :

     

            position += vitesse * 1

 

où 1 représente l'unité de temps, ceci est l'intégration de la vitesse par rapport au temps. De même la vitesse est calculée par l'intégration de l'accélération par rapport au temps.

 

Les résonateurs sont constitués de trois points dans un espace à une dimension, Le point central (celui dont on calcule et conserve la position et la vitesse) est relié d'une part à un point dont la position est directement donnée par l'amplitude instantanée du signal, et d'autre part à un point fixé à l'origine.

la valeur de l'accélération est donnée par la somme des vecteurs partant du point central :

 

(amplitude - position) + (0 - position)

 

Puis la tension est appliquée par une multiplication par un coefficient de tension compris entre 0 et 1.

 

Les valeurs de position, vitesse et cumul sont conservées, pour chaque résonateur d'une itération à l'autre.

C'est la valeur du cumul qui est utilisée pour donner la valeur de gris d'un point de l'image résultant de l'analyse : Chaque ligne de l'image correspond à un résonateur dont la tension est réglée sur la fréquence correspondant à la fréquence de la ligne du sonogramme. Et pour la dimension horizontale, l'utilisateur spécifie un pas d'analyse en millisecondes par pixel. En fonction de la fréquence d'échantillonnage, nous déterminons le nombre d'échantillons par pixel. À chaque nouvelle colonne de pixels produite (par la transformation des valeurs des cumuls en niveaux de gris), nous réinitialisons les valeurs des cumuls à zéro.

 

Pour effectuer les tests, nous dessinons un sonogramme, nous générons le fichier du son correspondant par synthèse additive, puis nous analysons le son : Nous devons obtenir, comme résultat d'analyse, une image qui soit la plus proche possible de l'image initiale.

 

Les images obtenues par analyse avec cette règle ressemblent aux images initiales, la réponse en fréquence parait satisfaisante, mais elles sont floues, et brouillées par des bandes horizontales : les résonateurs résonnent trop longtemps.

C'est donc la partie de la formule qui gère la déperdition d'énergie qu'il faut modifier.

Les sons produits par la résonance propre[55] de tels systèmes ont une enveloppe[56] triangulaire (décroissance linéaire de l'amplitude).

 

5.3.      Contrôle de la résonance

 

S'il n'y a pas de perte d'énergie, l'enveloppe est rectangulaire (amplitude constante).

En présence d’une augmentation d'énergie, les sons sont rarement exploitables, car cette augmentation de l’énergie entraîne l’explosion, les points oscillants sont éjectés de plus en plus loin de l'origine.

Les systèmes les plus intéressants sont donc ceux qui dissipent l'énergie, et la dissipation est exprimée dans notre règle par une modification de la vitesse.

 

 

si vitesse < 0

            vitesse += frottement

sinon

            vitesse -= frottement

 

 

Ce que nous avons baptisé frottement est une force constante en module et toujours orientée dans le sens opposé à la vitesse.

Le résultat est une amplitude décroissant linéairement (s'il n'y a pas d'apport extérieur d'énergie), donc une enveloppe triangulaire. La vitesse est diminuée d'une constante à chaque unité de temps. Ce frottement est une accélération (dérivée de la vitesse).

Un autre moyen simple de réduire la vitesse est de lui appliquer un coefficient : la multiplier par une valeur comprise entre 0 et 1, à chaque unité de temps. Appelons ce coefficient la viscosité.

 

 

vitesse *= viscosité

 

 

Toujours sans autre apport énergétique qu'un déséquilibre initial, notre point subit une résistance à l'avancement suivant une progression géométrique. L'amplitude résultante décroît de moins en moins rapidement, donnant une enveloppe courbe, avec l'axe du temps en asymptote.

 

Le son produit par cette résonance propre est perçu comme ayant un aspect plus naturel que les sons ayant une enveloppe triangulaire. Son enveloppe ressemble plus aux enveloppes obtenues par des oscillateurs physiques (cordes pincées).

Un autre avantage de cette forme est que le réglage du coefficient est moins dépendant de l'amplitude initiale que ne l'est le réglage de la constante frottement. En effet, si nous voulons obtenir une durée de résonance particulière (ou d'un ordre de grandeur déterminé) pour une amplitude donnée, nous pouvons dans les deux cas trouver une valeur de viscosité ou de frottement. Mais si ensuite, nous faisons varier l'amplitude, le frottement devra varier beaucoup plus que la viscosité pour retrouver la même durée de résonance.

 

Le résultat des transformations obtenues par cette règle est considérablement amélioré. Les images ne présentent plus les lignes horizontales (dues au résonances perturbantes). Elles sont beaucoup plus proches des images initiales. En enregistrant de la voix, et en resynthétisant, après cette transformation, la parole est tout à fait compréhensible, le timbre de la voix également (on reconnaît le locuteur). La voix est toutefois transformée, ceci peut être dû aux battements produits par la somme de fréquences proches les unes des autres : Les résonateurs ayant une fréquence proche de celle contenue dans le signal vibrent, avec une amplitude s'amoindrissant avec la distance, mais leur signal doit perturber le résultat.

 

5.4.      Optimisation

 

Les images résultant d'une analyse montrent quelques caractéristiques communes, que nous avons pu exploiter pour limiter la quantité de calculs nécessaire à leur production.

• Les sons couvrent rarement tout le spectre, on voit des zones denses et des zones vides.

• Les variations de valeurs présentent une certaine continuité.

• Autour d'un partiel, les résonateurs proches présentent une activité corrélée d'une part à la proximité en fréquence, et d'autre part, à l'amplitude de ce partiel.

• L'image résultante contient beaucoup moins d’informations que celle calculée par le banc de résonateurs. En effets, nos 2047 résonateurs produisent 2047 signaux amplitude/temps, avec une précision importante (calcul en double précision sur 12 octets), alors que l'image, finalement, ne représente que la somme des valeurs absolues des amplitudes sur une certaine durée (la durée correspondant à un pixel), et réduite à une valeur entière sur 7 bits.

 

Pour éviter les calculs inutiles, nous endormons des résonateurs qui n'ont pas produit pendant un certain temps (une durée équivalent à un nombre de pixels déterminé dans le programme). Mais les résonateurs doivent pouvoir se réveiller si le son analysé contient à nouveau leur fréquence.

Nous avons donc deux types de résonateurs : les insomniaques, un résonateur sur 16 répartis régulièrement sur tout le spectre, restent toujours éveillés et les autres, capables d'être endormis ou réveillés (figure 1.10).

Quand un résonateur insomniaque produit une valeur (non nulle), il réveille tous ses voisins (8 au dessus et 7 en dessous).

Ce procédé permet d'une part de rester sensible à toute la gamme de fréquences, et d'autre part, de concentrer les calculs uniquement sur les zones de fréquences présentes dans le signal[57].

L'analyse d'un son simple (sinus) est dorénavant jusqu’à 16 fois plus rapide que l'analyse d'un son complexe (avec de nombreux partiels).

Pour bien contrôler l'activité des résonateurs, nous utilisons deux seuils distincts sur les valeurs des cumuls ramenés à des valeurs de gris de l'image : le premier seuil est le seuil d'activité : au dessous de ce seuil pendant un certain temps (4 pas d'analyse actuellement) le résonateur s'endort. Le second seuil est celui à partir duquel les valeurs sont réellement intégrées à l'image.

 

5.5.      Algorithme des résonateurs

 

La valeur de la tension est limitée, et en fonction des fréquences auxquelles le résonateur doit être sensible, la valeur de tension obtenue peut dépasser ces limites. En effet si la tension est trop forte, l’accélération devient telle que la position s’écarte de plus en plus de la position d’origine, alternativement positive et négative. Ce phénomène est dû à un sous-échantillonnage du mouvement de l’oscillateur. Pour résoudre ce problème, et obtenir des résonateurs sensibles à des fréquences aiguës, nous devons décomposer le mouvement de notre résonateur en plusieurs périodes à l’intérieur de l’intervalle de temps correspondant à un échantillon du signal.

Nous nommons cycle le nombre de périodes à effectuer pour un échantillon.

L’algorithme devient finalement le suivant :

 

Pour chaque période du cycle :

      accélération = amplitude

      accélération -= position

      accélération -= position

      accélération *= tension

      vitesse += accélération

      position += vitesse

fin

vitesse *= viscosité

si position > 0

      cumul += position

sinon

      cumul -= position

 

La règle de déperdition d’énergie (viscosité) peut n’être appliquée qu’une seule fois.

En augmentant la valeur du cycle, la tension peut être diminuée, et les résonateurs deviennent sensibles à une nouvelle gamme de fréquences.

 

5.6.      Étalonnage des fréquences des résonateurs

 

Nous avons besoin de calculer les valeurs des cycles et des tensions des résonateurs en fonction des fréquences cibles.

Nous avons établi dans le chapitre précédent la relation

 

           

                  tension =

 

 

Fe est la fréquence d’échantillonnage.

 

Ceci reste valable quand la valeur du cycle est 1. Doubler le cycle est équivalent à multiplier par deux la fréquence d’échantillonnage.

 

La valeur limite de la tension est de 1. Nous calculons la fréquence maximale obtenue avec une valeur de tension < 1, par exemple 0.9.

  

 

tensionMax = 0.9

frequenceMax =

 

 

La valeur de k est obtenue par moyenne sur un ensemble d’expériences préliminaires où l’on connaît les valeurs des tensions et où l’on analyse les fréquences propres des résonateurs. La fréquence d’échantillonnage lors des expériences n’est pas nécessairement la même que la fréquence d’échantillonnage du signal à analyser.

 

La valeur du cycle est donnée par :

 

     

      cycle = (frequenceCible / frequenceMax) + 1

                  calculé en entier

 

             

et la tension par :

 

 

tension = (frequenceCible/cycle)2 / (k * Fe2)

 

 

5.7.      Étalonnage des niveaux des résonateurs

 

Il s’agit de transformer les valeurs obtenues dans le cumul de chaque résonateur, pour chaque fenêtre d’analyse (une fenêtre correspondant à la durée d’un pixel) en une valeur de gris pour un segment de phonogramme.

Les valeurs gris varient de 0 (absence de son) à 126 (amplitude maximale).

Le domaine des valeurs prises par les cumuls n’étant pas connu a priori, nous l’évaluons expérimentalement en agitant les résonateurs avec un signal aléatoire avant le traitement des échantillons à analyser.

Beaucoup de facteurs entrent en jeu dans le domaine des valeurs de cumul :

• Le contenu du signal lui-même, un bruit blanc ne donnera pas la même énergie qu’un son pur.

• La longueur de la fenêtre d’analyse.

• Le facteur de viscosité.

• La fréquence des partiels des signaux.

 

Dans notre première approche, un coefficient est déterminé d’après les résultats obtenus lors de l’agitation aléatoire préliminaire. En divisant le cumul maximal pour obtenir la valeur de gris maximale. Puis, le coefficient est réadapté, si nécessaire, pendant l’analyse. Ceci présente l’inconvénient majeur de changer la signification des valeurs de gris en cours d’analyse. Nous avons donc fourni la possibilité dans l’interface de régler un coefficient supplémentaire, permettant de forcer un diviseur de ce coefficient.

L’analyse de différents sons fournissait alors des images dont la forme correspondait au contenu spectral. Mais les amplitudes, c’est-à-dire les valeurs de gris de l’image, tout en étant cohérentes globalement, semblaient mal équilibrées par rapport aux fréquences. Les sons aigus avaient des valeurs de gris très fortes (sombres) et les sons grave des valeurs de gris très faibles. Les sons reconstitués par la synthèse additive du phonogramme résultant semblaient pourtant très proches des sons initiaux.

 

Nous avons donc cherché si une loi existait entre les valeurs obtenues et les fréquences des partiels. Pour cela, nous avons constitué des phonogrammes contenant des segments horizontaux (partiels de fréquence constante) de valeur constante (amplitude constante). Puis nous avons synthétisé le signal correspondant, et analysé ce signal par la transformée élastique.

 

Voici des exemples de résultat :

 

 

Avec un son harmonique :

 

fréquence   niveau de gris

 880.0            50

 440.0            25

 220.0            12

 

Avec un son inharmonique :

 

fréquence   niveau de gris

 839.654          24

 984.207          29

1427.5            43

1884.96           58

 

 

Il apparaît clairement le rapport suivant : les niveaux de gris obtenus sont directement proportionnels aux fréquences. Dans le second exemple, le rapport fréquence/niveau de gris est environ 34. Nous devons donc diviser les valeurs des cumuls par la fréquence avant de produire les niveaux de gris. Les résultats obtenus après l’implémentation confirment ce point. Nous avons maintenant un équilibre entre les amplitudes relatives des différentes fréquences.

 

Nous devons vérifier à présent que pour une fréquence donnée, avec différentes amplitudes, le résultat donne bien les niveaux correspondants.

 

Figure 5.1

 

Pour cette vérification, nous construisons une image telle que celle présentée ci-dessus (grossissement X 2), contenant des segments horizontaux dont la valeur baisse régulièrement. Les trois premiers segments ont une valeur de 120 et les suivants baissent de 10 en 10 jusqu’à 30.

Puis nous synthétisons le son correspondant à l’image initiale, et nous appliquons la transformée élastique sur le résultat.

 

Figure 5.2

 

Ci-dessus (figure 5.2), le résultat de la transformée élastique du son synthétisé d’après l’image initiale (grossissement X 2). Les niveaux obtenus sont en rapport linéaire avec les niveaux de l’image initiale.

 

L’image initiale est nette, les segments ont une épaisseur de 1 pixel (sauf le premier segment d’épaisseur 3), la synthèse correspondante donnera donc des signaux sinusoïdaux purs.

Par contre, l’image résultant de l’analyse est floue, non pas dans la direction horizontale (temporelle) mais dans la direction verticale (fréquencielle). La fréquence du signal était de 2000Hz environ, la fréquence d’échantillonnage de 22000Hz et le pas de déplacement de la fenêtre de 20 millisecondes. Le flou vertical est lié à la mise en résonance des résonateurs par des fréquences proches de leur fréquence propre.

 

Figure 5.3

 

Ci-dessus (figure 5.3), le signal amplitude/temps correspondant à l’image initiale, et ci-dessous, le signal amplitude temps produit par synthèse du résultat de la transformée. Dans l’image du haut, nous observons une différence nette de l’enveloppe du premier segment par rapport aux suivants : l’épaisseur du segment provoque l’addition de fréquences proches induisant ainsi un battement. Dans l’image du bas, tous les segments ont une épaisseur supérieure à 1, et les battements sont beaucoup plus importants : ils modifient sensiblement l’amplitude.

 

Figure 5.4

 

Voici, pour comparer, un détail du second segment du son provenant de l’image initiale :

 

Figure 5.5

 

L’enveloppe est très régulière. Et, ci-dessous, le détail correspondant dans le son transformé :

 

Figure 5.6

 

Les battements provoquent des modulations d’amplitude.

 

5.8.      Production de signal par bancs de résonateurs

 

Actuellement, seuls les réseaux élastiques et les réseaux à maillages cubiques sont utilisés pour la synthèse.

Les bancs de résonateurs sont une version simplifiée des réseaux élastiques, de manière à optimiser le procédé de transformée élastique. Les résonateurs sont dans une table, et le nombre de points mobiles par résonateur est fixé à un. Un point fictif fixé à l’origine et un point mobile fictif mû par le signal d’entrée sont intégrés directement dans la formule du calcul de l’accélération de l’unique point mobile.

Nous pourrions produire un signal en effectuant la somme des positions instantanées des points mobiles des résonateurs. Mais cela nécessite soit une source d’énergie externe, soit une déformation initiale du banc de résonateurs pour qu’une oscillation se produise.

 

5.9.      Stimulation des bancs de résonateurs par des flux MIDI

 

La source d’énergie permettant d’exciter le banc de résonateurs pourrait être un flux MIDI. Mais le temps de calcul nécessaire à la simulation de la résonance est beaucoup trop long[58], par rapport au débit temps réel du flux MIDI. Toutefois, les flux MIDI peuvent être conservés dans des fichiers (fichiers MIDI) et dans ce cas, être traités en temps différé. Les produits de cette opération serait des signaux échantillonnés.

 

 

5.10.     Filtrage d'un signal par bancs de résonateurs

 

Le procédé d’analyse (transformée élastique) peut rapidement être transformé en filtre. Il suffit de constituer le signal formé par la somme des valeurs instantanées des positions de chaque résonateur. Ceci serait intéressant pour savoir ce que notre banc de résonateurs entend. L’expérience reste à réaliser.

 

5.11.     Génération d’un réseau élastique à partir d’un signal

 

Cette conversion serait intéressante, mais a priori délicate : la conversion d’un signal en un résonateur ou un réseau élastique capable de le générer. L’avantage immédiat d’une telle représentation serait sa compacité, mais les bénéfices viendraient surtout du moyen d’obtenir des sons de la même famille en modifiant les caractéristiques du résonateur résultant.

Tous les sons peuvent être représentés (avec plus ou moins de fidélité) par leur image dans l’espace temps/fréquence des phonogrammes. Mais seul, certains sons peuvent être générés par un réseau élastique excité par une impulsion initiale. Ces sons ont les caractéristiques suivantes : L’enveloppe d’amplitude décroît au cours du temps, les modulations de fréquence décroissent également, et, suivant la matière des objets percutés, les partiels harmoniques aigus voient leur amplitude augmenter ou diminuer. D’autres caractéristiques nous échappent probablement, mais ce sont les principales.

Nous avons pensé à des processus évolutifs, guidés par des mécanismes de feed-back pour d’une part augmenter la fiabilité du système actuel d’analyse par transformée élastique, et d’autre part pour tenter la génération de modèles de résonateurs à partir de sons échantillonnés.

 

Figure 5.7

 

Dans ce schéma (figure 5.7), nous montrons deux cycles possibles, à partir d’une image existant sous la forme de phonogramme, soit le passage par les modules de synthèse externes, soit le passage par la synthèse additive interne. La première offrirait la possibilité de faire varier les timbres des modules externes, et d’utiliser la modulation de fréquence par exemple. Ceci permettant éventuellement d’obtenir des modèles élastiques de tels timbres. Il est en effet possible d’utiliser une modification d’une méthode d’analyse du son pour obtenir la synthèse de familles de timbres (LANSKY, STEIGLITZ 1981)

La seconde possibilité est préférable du point de vue de l’implémentation. Toutefois, la mise en œuvre d’un tel système demanderait un temps de développement hors de portée dans ce cadre.

Le contrôle s’effectuerait à partir du calcul du delta séparant le phonogramme initial et le phonogramme résultant de l’analyse du signal produit par les résonateurs. Le module de contrôle interviendrait alors sur l’évolution des résonateurs.

Ceci est à rapprocher des expériences faites sur l’utilisation de techniques d’évolution génétique pour réaliser le paramétrage de système utilisant la synthèse par modulation de fréquence (HORNER 1993).

 

Les trajectoires et les réseaux de couplages permettent de créer des fichiers de sons échantillonnés. Ces derniers peuvent être filtrés par les réseaux de couplages, analysés par la transformée élastique pour être intégrés dans des phonogrammes. Les phonogrammes sont une représentation graphique des sons et des séquences musicales permettant une vision tant locale, microscopique, que globale, macroscopique, grâce au possibilités du zoom. Ils établissent un lien entre la lutherie, la microstructure, et la composition, voire l’orchestration, la macrostructure.

Ces possibilités graphiques de l’atelier sont complétées par des applications dont la vocation est algorithmique. La production de ces générateurs et séquenceurs étant intégrable dans les phonogrammes, ou directement utilisable en temps réel, ou encore combinable avec l’exécution temps réel des phonogrammes. Nous présentons Métronome, le cœur de ces applications, dans le chapitre suivant.


6.         Métronome : noyau d’applications pour la composition algorithmique en temps réel

 

L’activité de composition musicale est très proche de l’activité de programmation, les compositeurs comme les programmeurs manipulent des abstractions, conçoivent des structures, établissent des relations entre ces structures, et produisent généralement un canevas décrivant le déroulement futur d’une succession d’événements. Dans (ENGLERT 1981), Giuseppe ENGLERT conclue : Mon but est de synthétiser quelque chose d’entièrement artificiel mais profondément cohérent. Le langage musical est pourtant loin des langages de programmation et les domaines musical et informatique semblent a priori distants : on associe l’informatique aux sciences exactes et la musique à l’art. Pourtant la liaison entre la physique et la musique date de Pythagore et les liens entre les mathématiques et la musique sont nombreux : Par exemple la musique de Y. XENAKIS, les systèmes d’analyses et de composition d’André RIOTTE, la musique fractale d’Horacio VAGGIONE, etc...

 

Nous présentons tout d’abord le cœur des applications génératrices de flux MIDI en temps réel. Puis nous verrons différents exemples d’applications basées sur ce noyau modèle. En particulier l’application Métro3 développée en collaboration avec Giuseppe ENGLERT (ENGLERT 1993), un séquenceur algorithmique interactif.

 

6.1.     Infrastructure

 

Avant tout, nous voulons situer ce module dans son contexte, et pour cela, nous devons décrire brièvement l’infrastructure des applications telles que nous les concevons pour les intégrer au système.

 

6.1.1.         Le système hôte

 

Le système hôte[59] est structuré en différentes couches, comprenant des drivers (modules de bas niveau) et des managers  (modules de plus haut niveau). Par exemple, la couche graphique de base, nommée QuickDraw, permet toutes les opérations graphiques courantes (tracé de droites, de rectangles, etc....). Sur cette couche, s’appuie le gestionnaire de fenêtres (WindowManager) qui lui-même sert de support au gestionnaire de dialogues (DialogManager) (cf : figure 6.9).

Une application standard fait appel au gestionnaire de fenêtres pour ouvrir une fenêtre, puis utilise des routines de QuickDraw pour en tracer le contenu.

Le programme principal, comme sous X Window ou encore sous Windows, n’est qu’une boucle infinie faisant appel à une fonction pour savoir si un événement s’est produit, puis réagit le cas échéant suivant le type d’événement, entre autres :

   • Retracer le contenu d’une fenêtre

   • Réagir à un déplacement du curseur de la souris

   • Réagir à un clic de la souris

   • Être prévenu d’une prise ou d’une perte de contrôle par l’application (dans le cas de plusieurs applications lancées simultanément).

   • Être prévenu d’un changement de l’activité d’une fenêtre (la fenêtre passe sous une autre fenêtre, ou au contraire, devient la fenêtre active).

   • Effectuer la fermeture d’une fenêtre.

 

6.1.2.         Un squelette d’application

 

Pour gérer de façon transparente ces événements du système, nous avons utilisé un squelette d’application nommé TransSkel (DUBOIS 1986) auquel nous avons adjoint des fonctionnalités[60]. Ce premier squelette d’application permet, lors de la création d’une fenêtre, de lui adjoindre les références aux fonctions qui seront automatiquement appelées lors d’un événement la concernant.

Une fonction différente traite chaque type d’événement (voir la liste ci-dessus). Ceci permet de gérer indépendamment, dans une même application, différents types de documents ainsi que de multiples fenêtres de chaque type, tout en gardant une certaine indépendance vis à vis du système hôte.

 

6.1.3.         Boîte à fenêtres

 

Nous avons enrichi ce squelette d’une librairie de fonctions utiles à la gestion de documents associés aux fenêtres. Les documents sont maintenus sous deux formes possibles : sous une forme volatile, modifiable, dans des structures de données en mémoire, et sous une forme plus stable, figée dans un fichier.

Un module de cette bibliothèque tel que le module Enregistreur, décrit les comportements standards des documents dans leurs relations avec les fenêtres de visualisation. Lors de la création d’une fenêtre, un document vierge est créé en mémoire, sans être associé à un fichier. Lors de l’ouverture d’un fichier, l’enregistreur lit ce fichier, et reconstruit en mémoire une structure identique à celle qui avait été sauvegardée. Lors de la fermeture d’une fenêtre, si le document a été modifié en mémoire, l’enregistreur propose la sauvegarde avant la fermeture, l’oubli des modifications, ou encore l’annulation de la commande. Évidemment, l’enregistreur ne connaît pas la structure interne du document, car il doit être utilisable pour tout type de document, et n’implémenter que les réflexes attendus dans une ergonomie standard. L’enregistreur connaît les pointeurs vers les fonctions à appeler pour la lecture et pour l’écriture de la structure de donnée associée à une fenêtre. Il doit simplement être renseigné lors d’une modification apportée à un document, et il gère les appels à toutes les routines standard des dialogues, d’ouverture, de création et de fermeture des fichiers.

Cette bibliothèque, la Boîte à fenêtres, s’appuie également sur une autre bibliothèque, la Boîte à outils, qui elle est écrite en C pur, mis à part un appel à la fonction d’allocation et de libération de mémoire du système.

 

6.1.4.         Boîte à outils

 

La boîte à outils contient un ensemble de modules permettant une gestion pratique de listes monodirectionelles, de doubles chaînages (listes bilatères, bidirectionnelles), de parcours de chaînages[61], de piles, de cycles (ou listes circulaires), d’associations clef-valeur (ou espaces d’adressages virtuels), de dictionnaires, d’ensembles, de bijections, de graphes, et d’éléments que nous appelons déclencheurs et surfaces sensibles. Les déclencheurs permettent d’associer des données et des fonctions, et les surfaces sensibles permettent d’associer des listes ordonnées de déclencheurs à des points d’un plan[62].

Chaque module est constitué d’une description de structures et de fonctions de manipulation de ces structures. A priori, les couches utilisant ces modules n’ont pas à en connaître l’implémentation (les champs des structures par exemple). Cette encapsulation est évidemment à rapprocher de celle des langages à objets (KRIEF 1990) (GOLDBERG, ROBSON 1989) (LESBROS 1989), mais n’intègre pas de notion d’héritage, ni de calcul dynamique de fonctions. La simple encapsulation des données, et la description de différents types de collections homogènes suffit à résoudre la plupart des problèmes rencontrés sans avoir à subir une doctrine de programmation tyrannique.

Des entorses à l’encapsulation peuvent être faites, en connaissance de cause (ou plutôt d’effet), pour optimiser des traitements intensifs, ou simplement pour adjoindre un traitement particulier dans une couche de niveau supérieur. Ceci n’est fait que si la généralisation de cette action paraît dénuée d’intérêt[63].

Dans la plupart des cas, un nouveau traitement peut être généralisé, et vient enrichir la bibliothèque. La fréquence d’ajout de nouvelle fonctionnalité dans un module diminue au cours de son utilisation : la bibliothèque se stabilise. D’autre part, pour les éléments de base, l’implémentation originale n’a jamais été remise en question : les listes possèdent toujours un champ car et un champ cdr.

Le module d’allocation de mémoire a été particulièrement conçu pour l’allocation et la libération intensive de blocs de mémoire dont la taille n’excède pas 64 octets. Tous les autres modules de la boîte à outil, ainsi que tous les modules externes gérant des structures de données font accès à ce module.

Notre boîte à outils est strictement portable.

 

6.1.4.1.      Visualisation automatique d’allocations dynamiques

 

Dans cette section nous présentons un système permettant de visualiser les structures de données allouées dynamiquement par les programmes écrits en langage C, ainsi que les chaînages entre ces structures. Ce système est un outil de développement et d’observation complémentaire de la boîte à outils et de la boîte à fenêtres.

Notre système n'implique aucune modification du programme qui doit être observé. Aucune description des structures de données à visualiser n'est nécessaire. Le système redéfinit uniquement la fonction d'allocation dynamique et la fonction de libération associée[64].

Enfin, la simplicité de son principe de fonctionnement doit permettre un portage rapide sous d'autres environnements que celui de son implémentation actuelle sur Macintosh.

 

Figure 6.1 : Représentation par notre système d’une arborescence binaire : les structures de données allouées pour les arbres de pondération des tirages aléatoires (cf. § Arbres d’appels de fonction pseudo-aléatoire).

 

Figure 6.2 : L’arbre d’appels de fonction pseudo-aléatoire dont les structures internes sont visualisées par la figure 6.1.

 

6.1.4.1.1.               Points d'entrée

 

Notre système se base sur les données suivantes : la fonction d'allocation, telle que malloc par exemple, reçoit la taille (en octets) du bloc mémoire à allouer, et délivre une adresse en retour :

 

 

void *malloc(long size);

 

 

 La fonction de libération reçoit l'adresse d'un bloc précédemment alloué et doit rendre disponible ce bloc pour une allocation ultérieure éventuelle[65] :

 

 

void free(void *ptr);

 

 

Aucune information concernant le type des données dans les structures allouées n'est fournie au système de visualisation.

Nous associons à l'adresse de chaque bloc alloué une structure portant l’information sur sa représentation graphique (la couleur et la position) et sur l'objet représenté, sa taille et son adresse.

 

 

typedef struct rep2D

{

            RGBColor couleurFond, couleurCadre;

            Rect cadre;

            long taille;

            void *objet;

} rep2D;

 

 

L'association entre les objets et leur représentation est effectuée dans un arbre binaire (structure assoc [66]de la boîte à outils) permettant une recherche dichotomique basée sur les bits formant l'adresse de l'objet : connaissant l'adresse d'un objet on obtient (au bout de 32 indirections au maximum[67]) sa représentation graphique. Connaissant une représentation, l'accès à l'objet est direct. L'arbre d'association permet également d'énumérer tous les couples (objet, représentation). Le second appel de la fonction récursive de parcours de l’arbre est remplacé par une affectation des paramètres (avec les valeurs des arguments) suivie d’un branchement au début de la fonction, ceci étant directement inspiré du système d’interprétation itératif des fonctions récursives décrit par Patrick GREUSSAY (GREUSSAY 1977).

 

L’information graphique pourrait se limiter à un point donnant la position de la représentation, de même, l’information concernant l'objet pourrait ne décrire que sa taille, puisque d'une part, la couleur et la taille du cadre sont calculées à partir de la taille de l'objet (cf. § Représentation graphique des blocs de mémoire ci-dessous), et d'autre part, chaque fois que l'on manipule une représentation, nous avons obtenu l'adresse de celle-ci à partir de l'adresse de l'objet qui est alors connue. Nous avons mémorisé la couleur et le cadre dans la structure pour optimiser la vitesse d'affichage.

 

La structure de représentation graphique minimale (occupant 64 bits) pourrait être :

 

 

typedef struct rep2Dminimale

{

            Point position;

            long taille;

} rep2Dminimale;

 

 

6.1.4.1.2.               Détection des pointeurs

 

Quand nous affichons un objet, nous affichons également les liens partant vers d'autres objets. Heureusement, tous les pointeurs ont la même taille, ainsi nous pouvons scruter la structure en se déplaçant de x octets en x octets[68], à la recherche d'une adresse que l'on a déjà associée à une représentation.

 

Seuls les pointeurs vers des structures allouées par notre système sont visualisés[69]. Il est peu probable d'autre part de confondre des données brutes avec des pointeurs[70].

 

6.1.4.1.3.               Représentation graphique des blocs de mémoire

 

Chaque bloc alloué est représenté par un rectangle affiché initialement[71] dans une position aléatoire à l'intérieur de la partie visible de la fenêtre de visualisation. La largeur du rectangle est fixe, et la hauteur est variable selon la taille du bloc et limitée à un maximum. Sur les écrans en couleur, le rectangle est rempli avec une couleur liée à la taille, et détouré par un cadre plus sombre. Notre système est indépendant des structures de données visualisées et de leur format, la couleur et la taille des rectangles aident toutefois au repérage des types des structures[72] allouées par le programme à visualiser.

Les pointeurs contenus dans une structure et désignant une autre structure sont représentés par des flèches[73]. Le point d'origine de la flèche, renforcé par un ovale, est calculé proportionnellement à l'offset du pointeur dans la structure de départ, et le point d'arrivée est le milieu du sommet du rectangle représentant la structure désignée.

 

Figure 6.3 : Un exemple de visualisation des structures allouées par le programme de dessin de schémas (figure 6.4). Le rectangle de droite (blanc) represente le schéma, il pointe vers une des trois cellules (gris sombre). à gauche , la structure représentant la flèche (figurée par le rectangle plus clair d’où partent trois flèches) pointe vers le début de son trajet, et vers les cellules de départ et d’arrivée. La cellule représentée à gauche pointe vers la cellule du centre car elle est englobée par celle-ci. La cellule centrale pointe vers une chaîne de caractères (en bas à gauche).

 

Les pointes des flèches sont formées d'un triangle orienté selon une des huit directions[74] possibles en fonction du trajet de la flèche.

 

Figure 6.4 : Le schéma dont on a visualisé les structures internes figure 6.3.

 

6.1.4.1.4.               Actualisation dynamique et élastique

 

A des intervalles réguliers définis par l’utilisateur, par exemple toutes les secondes, si le système n'est pas occupé[75], la visualisation des liens entre les structures est mise à jour. Cette mise à jour est lancée par la fonction de traitement des événements systèmes associés à la fenêtre.

Les liens sont également mis à jour lors d'une allocation ou d'une libération[76].

 

Le placement aléatoire des représentations des blocs aboutit rapidement à un fouillis inextricable ! Pour lutter contre le désordre, nous offrons d'abord la possibilité de déplacer (avec la souris) les rectangles représentant les blocs (cf § Manipulation des représentations). Puis nous permettons aux flèches représentant les pointeurs d'effectuer une traction sur les rectangles représentant les structures, comme si les flèches étaient des élastiques, cherchant en permanence à minimiser leur longueur.

 

Mais si toutes les structures d'une liste chaînée (ou de tout autre graphe) étaient ainsi soumises aux forces élastiques, elles s'effondreraient les unes sur les autres. Pour éviter l'effondrement, certaines structures sont fixées à la fenêtre et résistent aux couplages élastiques : Nous fixons les structures ayant moins de deux voisines, ainsi que les structures n'ayant soit aucune flèche partante, soit aucune flèche incidente.

 

Figure 6.5 : Visualisation d’une liste chaînée de quatre structures. Les éléments n’ont pas été déplacés manuellement : la position est déterminée au hasard, et les tensions élastiques ont déplacé les doublets. Le rectangle du bas représente un pointeur nul. Nous allons appliquer la fonction reverse sur la liste et extraire quelques étapes.

 

Figure 6.6 : Après le premier changement.

 

Figure 6.7 : deux éléments sont traités.

 

Figure 6.8 : La liste est renversée complètement.

 

6.1.4.1.5.               Calcul des tensions élastiques

 

Pour effectuer un pas de calcul, nous parcourons l'ensemble des couples (objet, représentation), et pour chaque couple nous calculons l'ensemble des liens partants de cet objet et l'ensemble des liens incidents. Le calcul des liens partant est proportionnel à la taille de l'objet, alors que le calcul des liens incidents est proportionnel au produit du nombre d'objets par leur taille. Lorsque l'objet est considéré mobile (s'il possède au moins un lien partant et au moins un lien incident), nous calculons la somme des vecteurs formés par les liens (en considérant l'objet observé comme origine des vecteurs). Cette somme est divisée par le nombre de liens, et, dans chacune des dimensions (horizontale et verticale), si la valeur absolue est non nulle, un déplacement de la moitié de cette tension est appliqué à l'objet[77].

 

Le calcul de la tension élastique est désactivable, de manière à permettre éventuellement de contrôler manuellement la place des éléments.

 

6.1.4.1.6.               Manipulation des représentations

 

Pour manipuler les représentations à la souris, nous calculons différents sous-ensembles à partir de la structure dans laquelle l’utilisateur clique :

• Le nœud lui-même

• L’ensemble des nœuds connexes (liens partants et incidents)

• L’ensemble des fils (nœuds connexes par les liens partants uniquement).

• L’ensemble des feuilles des fils (les nœuds terminaux).

 

A ces différents sous-ensembles, nous pouvons appliquer le déplacement ou l’effacement.

L’effacement consiste à transférer la représentation graphique d’un objet dans un second arbre d’association qui n’est pas visualisé. Nous pouvons réafficher l’ensemble des représentations par l’opération inverse (la position des représentations étant conservée ou recréée dynamiquement, au choix de l’utilisateur).

Nous pouvons également[78] effacer toutes les représentations sauf celle désignée, puis, réafficher progressivement les représentations des fils (de premier degré) des structures désignées. Ceci s’avère très pratique pour l’observation sélective d’un sous-ensemble d’objets dès que le nombre des représentations grandit.

 

Enfin, nous avons ajouté un champ dans la structure des représentations pour mémoriser un numéro d’ordre de création (équivalent à une date). Ce champ nous permet d’avoir une visualisation chronologique des allocations de mémoire.

 

6.1.4.1.7.               Vent (ou placement semi-automatique)

 

à partir d’un nœud quelconque, nous pouvons calculer l’ensemble des feuilles accessibles par les liens partants. Les feuilles sont parmi les éléments ne subissant pas la force élastique, et constituent des points d’accroche. En itérant sur toutes les représentations visualisées, et en appliquant un déplacement (x, y) (par exemple (1, 3)) à chaque feuille atteinte par chaque représentation, les feuilles de la fin d’une liste subissent une translation totale plus importante que celles du début de la liste. Ceci a pour effet d’ordonner graphiquement la liste. Les racines des arbres ne subissent pas de translation, et les feuilles de niveau n subissent n fois la translation. Les arborescences sont elles aussi ordonnées, mais les branches gauche et droite des arbres binaires restent superposées. Ceci permet toutefois le repérage rapide des racines.

 

Ce système de visualisation possède indubitablement un intérêt pédagogique : la matérialisation des structures et leur mise à jour concrétise immédiatement les manipulations des structures paraissant terriblement abstraites lorqu'elles ne sont vues que sous leur forme littérale.

Nos choix arbitraires, concernant la forme de représentation, ont surtout été guidés par nos habitudes personnelles dans la schématisation les structures et les chaînages.

 

6.1.4.2.      Descriptions de contrôles

 

Notre boîte à fenêtres gère les documents et inclue TransSkel ainsi que TransEdit (DUBOIS 1986) (un module spécialisé dans la gestion des documents textuels). Nous avons adjoint à cela un module permettant la gestion des interfaces non modales pour la saisie de paramètres : Descriptions de Contrôles.

 

Les boîtes de dialogue non modales sont nécessaires à l’affichage et à la saisie de valeurs numériques ou de textes, de drapeaux ou encore d’alternatives, par l’intermédiaire d’affichages statiques, de champs de saisie, de champs associés à des ascenseurs, de cases à cocher et de boutons de radio (sélection disjonctive exclusive d’alternatives). Ces dialogues et leurs contrôles, sont créés dans un éditeur de ressources, puis, habituellement, la mise en œuvre s’effectue par des appels à des fonctions du système (DialogManager, ResourceManager), pour charger les ressources, les afficher, obtenir ou modifier le contenu des champs, convertir les champs numériques, etc...

Notre module permet une gestion simplifiée de toutes ces opérations : en effet, il nous suffit, pour lier une variable à un champ de saisie, d’appeler depuis une routine d’initialisation, une fonction correspondant au type de contrôle souhaité avec en paramètre un identificateur du dialogue et du contrôle, et l’adresse de la variable à lier. Éventuellement, nous pouvons fournir un pointeur vers une fonction à appeler en cas de modification par l’utilisateur de la valeur du contrôle. Dès lors, toute l’interface est gérée : si l’utilisateur modifie le champ, la variable est mise à jour, et inversement, nous disposons d’une unique fonction (quelque soit le type de variable) pour mettre à jour l’affichage concernant une variable donnée.

Les boîtes de dialogue peuvent également contenir des boutons que l’on associe à des fonctions.

Nous n’avons pas utilisé de générateurs d’interfaces, car ceux-ci produisaient un code redondant et spécifique du système. En outre, la personnalisation du code produit était à refaire à chaque modification des contrôles. Les générateurs actuels, tel VisualC++[79], sont plus souples, mais le code produit est très important[80].

 

Finalement, pour construire une application multifenêtre, multidocument, il nous suffit de copier le modèle de programme principal, de changer les noms des fonctions associées aux événements de fenêtre, et de lecture et écriture de documents, et enfin de connecter les paramètres globaux aux contrôles. Notre squelette est prêt à être spécialisé.

 

Figure 6.9

 

Ce schéma (figure 6.9) résume les différents niveaux décrits ci-dessus. Il n’est pas exhaustif, mais donne les relations principales. Par exemple, l’application peut directement faire appel à des routines de QuickDraw ou à différents modules du système non figurés ici, mais nous avons tenté de limiter les appels aux éléments spécifiques, en encapsulant ces appels dans des bibliothèques qui seront en principe les seules à être modifiées lors d’un éventuel portage.

 

6.2.     Le module Métronome

 

Le module Métronome n’est pas sous forme de bibliothèque, mais c’est également un squelette à recopier et à modifier.

Il permet principalement la gestion des entrées et sorties MIDI.

 

Son principe est le suivant :

Pour la réception :

Lors de la réception d’un message MIDI, le message est décodé, et une sélection est appliquée suivant le type du message et l’intérêt que l’on porte à ce type de message dans l’application. Par exemple une application réalisant un enregistrement du flux MIDI conservera dans une liste la totalité des événements reçus. Une application réagissant aux hauteurs des notes ignorera tous les messages concernant les changements de timbre, etc.

La réception du message est faite sous interruption, et certaines précautions sont à prendre dans l’écriture de la fonction de réception. Par exemple l’impossibilité de faire appel à des routines graphiques ou à des routines allouant de la mémoire.

 

Pour l’émission :

Une fonction nommée Métronome est appelée par interruption (avec les mêmes contraintes que précédemment). Elle déploie l’algorithme de production du flux MIDI pour une petite période de temps. Cette période de temps est déterminée par la fonction Métronome elle-même, en effet la valeur de retour de la fonction (un entier long), correspond au nombre de millisecondes séparant la terminaison de l’appel courant d’avec l’appel suivant de la fonction Métronome.

Dans la fonction Métronome, des événements MIDI (structures décrivant des messages MIDI) sont préparés pour couvrir la période à venir.

 

6.3.     Interface MIDI, le Système MIDIShare

 

Nous nous appuyons sur le système MIDIShare (ORLAREY 1989) (FOBER 1995) qui permet la gestion des messages MIDI sous la forme d’événements. Ce système permet en outre la gestion différée des événements et des appels de fonction. On peut, par exemple demander l’exécution de telle fonction, avec tels paramètres, à telle date. Le temps dans ce système est compté en nombre entier de millisecondes, avec un repère global à toutes les applications utilisant ce système.

 

Un autre avantage de ce système est la connectivité des applications l’utilisant : chaque application peut émettre les messages MIDI vers toutes les autres. Une application (msConnect, développée par le GRAME) permet de connecter les applications entre elles ou avec les entrées/sorties matérielles.

 

Ceci nous permet, d’utiliser un ensemble d’applications effectuant des générations ou des filtrages de flux MIDI, et de connecter par exemple la sortie de Métro3 sur l’entrée de Phonogramme, pour enregistrer sous forme de phonogramme une séquence musicale élaborée dans le séquenceur algorithmique.

 

6.3.1.             Enregistrement de flux MIDI dans les phonogrammes

 

Comme pour la conversion inverse (depuis les phonogrammes vers la norme MIDI), nous proposons deux méthodes : une en temps réel (l’enregistrement) et l’autre en temps différé, à partir d’un fichier MIDI. Cette fois, la conversion temps réel peut être plus longue que celle en temps différé. La conversion est immédiate, en effet, chaque note reçue ou lue est transformée en un segment du phonogramme, ou, plus exactement, en un coup de pinceau appliqué dans le phonogramme. Cela permet par exemple de donner une épaisseur à chaque trait, ou encore d’ajouter automatiquement des harmoniques aux notes provenant du flux MIDI en activant le pinceau à harmoniques.

Une amélioration envisagée mais non implémentée serait de lier les messages MIDI de changement de timbre (program change) au changement de pinceau, et de permettre d’utiliser les pinceaux à timbres lors de cette opération.

 

6.3.2.             Traitement MIDI

 

Les modules de traitement MIDI reçoivent un flux MIDI entrant, l’interprètent, et réémettent un flux MIDI transformé. L’interprétation peut être simple ou sophistiquée, suivant le type de transformation effectuée. Un exemple simple est le changement des numéros de canaux des messages, ou encore la génération d’un écho ou encore la transposition des notes du flux. Un exemple sophistiqué est l’interprétation des structures rythmiques et/ou harmoniques du flux entrant, associée au paramétrage d’un générateur rythmique et mélodique tel que le module Alpha présenté dans le paragraphe Le module Alpha.

Les modules de traitement MIDI peuvent être matériels ou logiciels, nous n’avons cependant développé que des modules logiciels.

Les traitements effectués dans l’application Métro3 ne le sont pas au niveau des flux MIDI, mais directement sur les séquences numériques représentant les mélodies ou patterns mélodiques. Nous avons développé le séquenceur algorithmique interactif Métro3 en collaboration avec Giuseppe ENGLERT (ENGLERT 1993).

Nous décrivons à présent les algorithmes que nous avons développé pour générer automatiquement les rythmes et la dynamique des patterns mélodiques.

 

6.4.     Algorithme rythmique & dynamique de Métro3

 

L’unité indivisible du temps est spécifiée en un nombre entier de millisecondes et nommée le tempo. Les tempi de chaque voix sont indépendants et varient entre 60 et 500 millisecondes par pulsation.

Nous étudierons le procédé pour une seule voix, sachant qu’il doit être réitéré pour chacune d’elles et que les paramètres de l’algorithme sont propres à chaque voix.

 

6.4.1.         Les durées

 

Les unités de temps sont regroupées en cellules rythmiques appelées mesures. Le nombre d’unités par mesure varie de 1 à 24.

La mesure sera décomposée en sections de longueurs variables dont la somme des longueurs doit être égale au nombre d’unités par mesure. Chaque section représentera un événement sonore, une note dont la hauteur est déterminée par la séquence en cours d’exécution.

 

La méthode de décomposition utilisée est très simple mais elle garantit le respect de la durée des mesures et fournit des cellules rythmiques intéressantes :

• Pour diviser une longueur, nous choisissons une valeur aléatoire entière comprise entre 1 et la longueur - 1, cette valeur donne la longueur d’une première section, la seconde section aura pour longueur la longueur totale moins la longueur de la première section. La longueur totale est ainsi divisée en deux parties égales ou inégales ; puis, nous décomposons récursivement chaque section avec le même procédé.

• L’algorithme se termine dans deux cas : soit la longueur à décomposer est unitaire, soit une profondeur de décomposition maximale, déterminée par un paramètre est atteinte.

 

Le paramètre de profondeur est accessible dans l’interface, et varie de 0 à 6.

 

Figure 6.10

 

Par exemple (figure 6.10), dans une mesure de 9 unités décomposée jusqu’à la profondeur 4, nous observons que les durées des sections sont toutes unitaires. En choisissant d’autres points de décomposition, comme dans la figure ci-dessous, ou en limitant la décomposition à une profondeur moindre, des cellules rythmiques diverses sont formées. à la profondeur deux, la décomposition est 1 3 2 3 alors que dans la figure suivante on obtient 2 5 1 1.

 

Figure 6.11

 

Avec une profondeur nulle, les mesures ne sont pas décomposées, et toutes les notes ont la durée d’une mesure. Avec une profondeur trop importante (en fonction de la durée de la mesure) la décomposition est complète et toutes les notes ont une durée unitaire. Les valeurs intermédiaires de la profondeur offrent une grande variété de possibilités. Le réglage de ses paramètres en temps réel au cours de l’exécution est simple.

 

JONES (JONES 1981) utilise un système proche de celui-ci : une grammaire avec deux règles de générations :

              A -> AA

              A -> a

Associée à des probabilités d’application des règles (grammaire stochastique), pour générer un arbre binaire. La racine de l’arbre représentant la durée totale à décomposer, et les nœuds fils chacun la moitié de la durée du nœud père. L’inconvénient est que les durées exprimables sont toutes des puissances de deux, elles sont adaptées aux mesures à 4/4 (cf. Structures des pages) par exemple mais pour d’autres décompositions, il faudrait adapter la grammaire.

 

6.4.2.         La dynamique

 

La dynamique peut être générée de deux façons dans le séquenceur : soit en utilisant une répartition des pourcentages de chance d’obtenir un silence, une note faible, une intensité moyenne ou une note forte : l’accentuation dynamique aléatoire. Soit en utilisant un algorithme de calcul basé sur une décomposition binaire : l’accentuation dynamique arborescente.

 

6.4.2.1.      Accentuation dynamique aléatoire

 

Trois limites sont accessibles pour former la répartition des pourcentages respectifs de chacune des quatre catégories d’amplitude. Chaque limite varie de 0 à 99 mais la première est inférieure ou égale à la seconde qui est inférieure ou égale à la troisième. Dans l’interface, les valeurs sont contraintes par ses règles.

Pour sélectionner une catégorie, nous prenons une valeur aléatoire entre 0 et 99. La position de la valeur entre les limites détermine une catégorie. Ensuite, la valeur réelle de l’amplitude est choisie aléatoirement entre des limites fixées selon la catégorie.

 

6.4.2.2.      Accentuation dynamique arborescente

 

Le principe de l’accentuation dynamique arborescente est le suivant : nous partons de la racine avec une valeur donnée i et nous formons deux branches auxquelles nous attribuons respectivement les valeurs i*2 et i+1.

 

Figure 6.12

 

Par exemple en partant de la valeur 2, nous obtenons l’arborescence suivante :

 

Figure 6.13

 

Une infinité de sous-arbres sont équivalents, par exemple :

2 + 1 + 1 = 2 * 2, ou encore 2 * 2 + 1 + 1 = 2 + 1 * 2.

Ce qui nous intéresse, c’est la succession des valeurs obtenues à une profondeur donnée, par exemple à la profondeur 2, nous avons la séquence 8 5 6 4, en faisant correspondre des intensités à ces valeurs, nous retrouvons une relation avec l’importance rythmique relative des quatre temps d’une mesure à 4/4. Le premier temps est le plus fort, le second est relativement faible, le troisième temps est le second en importance et le dernier est le plus faible. Par construction, l’étage suivant possède la même structure et peut s’appliquer sur les 8 croches d’une mesure 4/4 pour en calculer l’intensité ou la force relative.

Le procédé peut également être inversé pour syncoper le résultat.

Ou encore être appliqué en dehors des temps, en suivant la décomposition récursive des durées, décrite dans le paragraphe précédent.

 

6.5.      Harmonies

 

Ce paragraphe[81] présente quelques notions élémentaires d’harmonie nécessaires à la compréhension du paragraphe suivant portant sur la composition algorithmique. Nous utilisons la représentation graphique de la gamme et des accords que nous a transmis André RIOTTE[82].

 

Divisons l'octave en douze parties égales (le demi-ton).

 

Figure 6.14 : la gamme chromatique

 

Cette horloge (figure 6.14) représente la gamme chromatique[83], allant de demi-ton en demi-ton. Il n'y a évidemment qu'une seule gamme chromatique, identique quelque soit la note de départ. Par contre, en sautant une note sur deux, c'est-à-dire en allant de ton en ton, nous pouvons former deux gammes par ton distinctes et complémentaires.

 

Figure 6.15 : la gamme par ton

 

Ci-dessus (figure 6.15), l'hexagone de la gamme par ton, il est exactement similaire à la figure que l'on obtient en allant de 10 en 10.

 

Douze est divisible par 3, le résultat est 4, ainsi, en allant maintenant de trois en trois demi-tons, nous formons un carré.

 

Figure 6.16

 

Nous pouvons former ainsi trois carrés distincts, chacun de 2 façons : en allant de trois en trois ou de neuf en neuf.

 

Figure 6.17

 

Tout ceci est très régulier : maintenant nous avons un des quatre triangles équilatéraux possibles (figure 6.17), en avançant de 4 en 4 ou de 8 en 8. Mais la régularité change, lorsque le pas est de 7 ou de 5 :

 

Figure 6.18

 

Nous obtenons une figure (figure 6.18), unique, qui passe par toutes les notes de la gamme chromatique, mais dans un ordre différent.

 

Figure 6.19

 

De 6 en 6, nous avons 6 diamètres, simplement.

 

6.5.1.         Gammes

 

La gamme majeure peut être formée en allant de 7 en 7, mais en s'arrêtant dès que l'on a obtenu les sept notes.

 

Figure 6.20 : la gamme majeure.

 

Sur la figure 6.20, nous avons numéroté l'ordre d'apparition des notes de la gamme : fa, do, sol, ré, la, mi, si. En comparant cette horloge à un clavier de piano, nous retrouvons les mêmes espaces entre les notes : un ton entre deux notes consécutives, sauf entre mi et fa et si et do.

En continuant à tourner, de 7 en 7 après le si, on trouverait les notes fa dièse, do#, ré#, etc... dans le même ordre. Et en tournant à l'envers, comme si on cherchait la note précédant le fa, on trouverait, si bémol, mib, lab, etc... dans l'ordre inverse.

Figure 6.21 : les degrés de la gamme

 

Construire une gamme majeure, c'est simplement prendre sept notes consécutives dans la suite :

 

... solb réb lab mib sib fa do sol ré la mi si fa# do# sol# ré# la# mi#...

 

Où toutes les notes sont espacées de 7 demi-tons, puis les remettre dans l'ordre suivant leur hauteur.

 

En commençant par le fa, on obtient la gamme de do majeur (la note suivante dans la série). En commençant par le do, on obtient la gamme de sol majeur, qui inclue le fa#, etc... On peut construire ainsi une "infinité" de gammes, quand les dièses sont épuisés, on utilise des doubles dièses, de même pour les bémols.

 

Figure 6.22

 

Il est important de remarquer que tous les noms des notes apparaissent une seule fois, voilà pourquoi, en construisant la gamme de fa majeur, nous dénommons sib, la note entre si et la et non la#, puisque le la naturel est déjà dans la gamme.

 

Dans l'horloge ci-dessus (figure 6.21), nous avons numéroté en chiffres romains (comme il est d'usage) les degrés de la gamme. Chaque degré porte un nom. Cette abstraction permet de raisonner sur les notes et les harmonies, sans être obligé de tenir compte de la tonalité réelle dans laquelle on se trouve.

  

   I - tonique

   II - sus-tonique

   III - médiante

   IV - sous-dominante

   V - dominante

   VI - sus-dominante

   VII - note sensible[84]

 

Jusqu'à présent, nous n’avons mentionné que la gamme majeure, l'harmonie utilise également les gammes mineures. Majeur et mineur sont des modes, comme on peut en former des multitudes, en sélectionnant des points dans cette horloge. Il existe plusieurs modes mineurs, nous ne décrivons ici que le mode mineur harmonique qui nous permettra de construire des accords.

 

La gamme harmonique mineure est construite en utilisant le même schéma que pour le mode majeur, mais la numérotation des degrés débute à neuf heures au lieu de midi.

 

Figure 6.23

 

Les carrés indiquant les notes appartenant au mode n'ont pas changé, sauf le degré VII, la sensible, montée d'un demi-ton pour être juste avant la tonique.

Chaque ton majeur possède ainsi son ton relatif mineur, dont la tonique est une tierce[85] au dessous (de la tonique du ton majeur).

Par exemple, la mineur est le relatif de do majeur, seule la sensible, sol est modifiée par un dièse. Le passage d'un ton à un autre est favorisé par le nombre de notes communes aux deux tons. Comme il y a six notes communes entre un ton et son relatif, ces modulations[86] sont simples.

 

6.5.2.         Intervalles

 

Les intervalles entres les notes sont nommés en fonction du nombre de notes consécutives formant l'espace entre les notes (extrémités comprises). Par exemple entre mi et sol, il y a une tierce, car on compte trois notes consécutives de mi à sol : mi, fa, sol.

Les noms sont : unisson (pour une note), seconde pour l'intervalle formé par deux notes consécutives, puis tierce, quarte, quinte, sixte, septième, octave. Les intervalles plus grands ont des noms régulièrement formés : neuvième, dixième, etc...

L'ordre des dièses : fa, do, sol, ré, la, mi, si, obtenu précédemment en comptant par 7 demi-tons est formé d'une succession de quintes.

 

Les intervalles sont ensuite qualifiés pour rendre compte des différences en nombre de demi-tons. Par exemple, la seconde do-ré comporte un ton alors que la seconde do-ré# comporte trois demi-tons, la première est majeure et la deuxième est augmentée.

 

 

La table ci-dessus donne la correspondance pour chaque nom d'intervalle, entre les qualificatifs et le nombre de demi-tons.

 

6.5.3.         Accords

 

Pour lire les accords sur la figure 6.24, il suffit de choisir un degré de départ, puis de suivre les lignes (dans le sens des aiguilles). Les lignes ont été tracées en sautant un degré sur deux, c'est-à-dire, en allant de tierce en tierce.

 

Figure 6.24 : Tous les accords du mode majeur.

 

Les accords de trois sons sont formés d'une note fondamentale (celle sur laquelle on construit l'accord), d'une tierce et d'une quinte (par rapport à la fondamentale). Le quatrième son est la septième, etc...

On peut remarquer que les accords de trois sons (deux lignes consécutives) sont de trois types différents : on trouve le premier type, accord parfait majeur, sur les degrés I, IV, et V (tierce majeure et quinte juste), le second type, accord parfait mineur, sur les degrés II, III, et VI, et enfin le troisième type, rencontré uniquement sur le degré VII est l'accord de quinte diminuée (c'est le seul formé de deux segments courts (deux tierces mineures), tous les autres sont formés d'un segment de chaque longueur).

 

Figure 6.25

 

Observons maintenant (figure 6.25), les accords à trois sons du mode mineur :

Degré I, accord parfait mineur ; degré II, accord de quinte diminuée ; sur le degré III, nous avons un nouveau type d'accord, de quinte augmentée, formant le triangle équilatéral. Le degré quatre est mineur, le V et le VI sont majeurs ; et sur le septième degré, se forme à nouveau l'accord de quinte diminuée, de plus, si on ajoute le quatrième son, cela forme un carré (composé uniquement de tierces mineures).

Comment voulez-vous faire de la musique avec des formes si biscornues ?

 

Figure 6.26 : Cette table donne pour chaque intervalle, la valeur en demi-tons correspondante suivant le degré sur lequel il est construit. Par exemple, si on bâtit une quinte sur le degré VII, la valeur 6 indique que c'est une quinte diminuée.

 

La première ligne indique donc les distances dans ce mode entre les notes consécutives. Les cases de la seconde ligne sont calculées en additionnant la valeur de la case supérieure et de sa voisine : il faut deux secondes consécutives pour former une tierce. Il existe de nombreuses façons de construire cette table, puisque toutes les valeurs peuvent se déduire de la première ligne. C'est simplement un point de vue sur le mode, différent de l'horloge et des segments.

 

Figure 6.27 : La table représentant le mode mineur.

 

En isolant les lignes correspondant à la tierce et à la quinte, nous voyons nettement les différents types d'accords de 3 sons.

3-7 accord parfait mineur[87] sur I et IV

3-6 accord de quinte diminuée sur II et VII

4-8 quinte augmentée sur III

4-7 accord parfait majeur sur les degrés V et VI.

 

En ajoutant un son dans l'accord (la 7ème), les degrés se distinguent davantage, par exemple les degrés V et VI portant des accords parfaits majeurs se distinguent maintenant par la septième qui est mineure pour le cinquième degré et majeure pour le degré VI. Par ailleurs, en regardant la table du mode majeur, on voit que le degré V porte le même accord de quatre sons 4-7-10.

Cet accord 4-7-10 n’apparaît que sur le degré V, mais dans les deux modes, il a donc une grande force tonale, et une faible force modale.

 L'accord 3-6-9 n'apparaît que sur le degré VII du mode mineur. Il a donc une grande force modale. Mais sa forme carrée lui permet d'appartenir à quatre tonalités différentes, sa force tonale est donc moindre.

 

Toutes ces similitudes, oppositions, unicités ou au contraire multiplicités contribuent ou fondent les éléments de langages musicaux. Je trouve toujours étonnant les ressources inépuisables enfouies, contenues dans la simplicité des éléments de base.

Jusqu'ici, nous n’avons qu’à peine entrebâillé la première page d'un traité d'harmonie, ceci n'est qu'une première partie statique de l'harmonie, mais il existe des énergies, du mouvement, des dynamiques à découvrir. L'harmonie est la science de l'enchaînement des accords. Avant de pouvoir décrire leurs enchaînements, nous devons encore mieux connaître leur structure.

Ce que nous avons vu, des accords, et des notes, n'est qu'un reflet. Les horloges enroulent les notes de façon à superposer toutes les notes de même nom, et d'ignorer les octaves. Ceci permet de visualiser directement les opérations en arithmétique modulo 12. Mais les notes réelles doivent être déployées sur plusieurs octaves.

L'harmonie traditionnelle est écrite à quatre voix, les voix extrêmes : basse et soprano, encadrant les voix intermédiaires : ténor et contralto.

 

Figure 6.28

 

Comme décrit sur la figure 6.28 ci-dessus[88] (à gauche), chaque voix peut chanter dans un ambitus particulier, c'est-à-dire dans certaines limites. L'échelle est en demi-tons, les traits de repères, tous les douze demi-tons, indiquent les do, (graves en bas et aigus en haut). Ils sont repérés par leur écriture traditionnelle en pentagramme à droite.

La partie droite de la figure montre douze façons de former le même accord parfait majeur do-mi-sol (douze positions de l'accord), en respectant les ambitus des différentes voix, et en conservant la note fondamentale (do) à la basse, ce que l'on nomme l'état fondamental de l'accord. Lorsqu'une autre note que la note fondamentale est jouée par la basse, l'accord est dit renversé. Pour un accord de trois sons, on distingue deux renversements, à quatre sons, il y a un état fondamental et trois renversements.

Les six premières positions doublent la note fondamentale (il y a trois notes pour quatre voix, il est donc nécessaire qu'au moins une note soit doublée). Les trois positions suivantes doublent la tierce, et les trois dernières doublent la quinte. La position de l'accord étant connue, c'est-à-dire quelle note est doublée, et quel est leur ordre d'apparition, les notes sont placées en respectant l'ambitus des différentes voix, et en essayant de répartir les notes dans l'étendue (la même position do-mi-do-sol, peut être répartie de différentes façons, sur des octaves différentes).

 

Les renversements forment de nouvelles combinaisons d'intervalles.

Par exemple, l'accord parfait majeur que je note 3-7, est renversé une première fois en ajoutant 12 à la note de basse 0 (pour monter d'une octave), puis en recalculant les écarts à partir de la tierce. 7-3 = 4, 12-3 = 9, ce qui donne l'accord 4-9, formé d'une tierce majeure et d'une sixte majeure.

Le second renversement s'obtient de la même façon : 9-4 = 5, 12-4 = 8, ce qui donne 5-8, un accord formé d'une quarte juste et d'une sixte mineure.

Si on renverse encore l'accord 5-8, 8-5 = 3, 12-5 = 7, on obtient à nouveau l'état fondamental 3-7.

 

Figure 6.29


La figure 6.29 donne tous les accords de neuvième majeurs et mineurs ainsi que tous leurs renversements. Les accords sont notés en nombre de demi-tons depuis la note la plus basse, pour chaque note composant l’accord, et placés dans la grille. Par exemple l’accord 11-3-6-9 est dans la grande case repérée ligne 11 colonne 3 et sur le point de cette case repéré ligne 6 colonne 9. Les symboles indiquent les renversements.

 

6.5.4.         Composition algorithmique

 

Nous présentons maintenant plusieurs modules de composition algorithmique indépendants utilisant les définitions que nous venons de voir. Le premier module nommé Intervalle est basé sur les intervalles harmoniques[89] et le réglage de la possibilité ou non d'enchaîner ces intervalles.

Les différents modules peuvent être exécutés simultanément, et éventuellement connectés les uns aux autres. Certains modules sont des générateurs et produisent un flux de notes MIDI, d'autres sont des filtres, qui transforment un flux, d'autres encore modifient leur façon de générer en fonction de ce qu'ils reçoivent. Tous travaillent en temps réel.

 

6.5.4.1.      Module Intervalle

 

Ce module fonctionne dans le mode chromatique, a priori, toutes les notes peuvent être générées (il n'y a pas de sélection de note par le choix d’une gamme ou d’un mode).

Trois voix sont générées. Nous commencerons par décrire les deux premières voix, qui sont indépendantes de la troisième.

Le but du contrôle des intervalles harmoniques est de contraindre la formation mélodique.

 

Le déroulement global du programme est géré par des interruptions provoqués par une horloge. Une variable globale tempo contient un nombre de millisecondes séparant chaque appel de la fonction nommée Métronome. Cette variable tempo est réglable par l'utilisateur. Dans la fonction Métronome, l'émission d'une note pour chacune des deux premières voix est déclenchée simultanément.

 

La hauteur des notes est mémorisée dans deux variables (statiques) hauteur1 et hauteur2. Ces variables sont initialisées respectivement à 60 et 64. Ces valeurs correspondent à des hauteurs MIDI (en nombre de demi-tons, le 60 correspondant au do du milieu du clavier). L'intervalle harmonique entre les notes est calculé par la simple différence entre les hauteurs.

 

intervalle = hauteur2 - hauteur1

 

Au départ, l'intervalle est de 4 (64 - 60), ce qui correspond à une tierce majeure.

Une table de 12 par 12 cellules, contrôlable dans l'interface utilisateur, indique les successions d'intervalles autorisées (cellule à 1) ou interdites (cellule à 0). Par exemple, la cellule (4, 7) (ligne 4, colonne 7) contient le drapeau indiquant si une tierce majeure peut être suivie d'une quinte juste.

Les intervalles harmoniques générés sont bornés entre 0 et 11 demi-tons. La moyenne des hauteurs des notes est comprise en les notes 50 et 70.

 

Voici maintenant comment se déroule un pas de l'algorithme (un appel de la fonction Métronome) :

 

• On tire un intervalle cible au hasard (entre 0 et 11 inclus).

• Si la succession de l'intervalle actuel à l'intervalle cible n'est pas autorisée, les deux notes sont conservées identiques, sont jouées, et le pas est terminé. La répétition du même intervalle est ainsi considérée comme étant toujours autorisée, et la diagonale principale de la table est insignifiante.

• Sinon, deux boucles successives vont permettre d'amener l'intervalle actuel à égalité avec l'intervalle cible :

• Tant que l'intervalle entre hauteur1 et hauteur2 est inférieur à l'intervalle cible : "augmenter l'intervalle"

• On tire une note au hasard entre 50 et 70, et on la compare à la moyenne de hauteur1 et hauteur2.

• Si la valeur tirée est inférieure à la moyenne, on baisse la hauteur1 d'un demi-ton

• Sinon, on monte la hauteur2 d'un demi-ton.

Dans les deux cas, l'intervalle entre hauteur1 et hauteur2 augmente (on a toujours hauteur1 ≤ hauteur2).

• fin de tant que.

• Tant que l'intervalle entre hauteur1 et hauteur2 est supérieur à l'intervalle cible : "diminuer l'intervalle"

• On tire une note au hasard entre 50 et 70, et on la compare à la moyenne de hauteur1 et hauteur2.

• Si la valeur tirée est inférieure à la moyenne, on monte la hauteur1 d'un demi-ton

• Sinon, on baisse la hauteur2 d'un demi-ton.

Dans les deux cas, l'intervalle entre hauteur1 et hauteur2 diminue (on a toujours hauteur1 ≤ hauteur2, puisque hauteur2 - hauteur1 > au choix de l'intervalle entre 0 et 11).

• fin de tant que.

• à ce niveau, l'intervalle entre hauteur1 et hauteur2 a évolué, de demi-ton en demi-ton, appliqué sur l'une ou l'autre des deux hauteurs, selon que, globalement les voix étaient plutôt aiguës ou graves.

• Les hauteurs ainsi obtenues sont émises.

 

Les valeurs 50 et 70 sont arbitraires, et peuvent être lues limite grave et limite aiguë respectivement. Le choix effectué, pour augmenter l'intervalle entre descendre la note basse ou monter la note haute, influe sur la ligne mélodique globale. De façon à garder les lignes mélodiques dans l'ambitus, mais sans avoir à donner une règle stricte qui aboutirait à des répétitions, nous faisons la moyenne des notes et nous tirons une note au hasard dans l'ambitus. Si la note tirée est plus haute (que la moyenne des deux notes), nous faisons monter la ligne mélodique, si elle est plus basse , nous faisons descendre la mélodie. De cette façon, l'évolution de la mélodie n'est pas immuable, et les chances de monter (respectivement de descendre) sont moindres si les notes actuelles sont déjà hautes (respectivement graves). Toutefois, malgré l'absence d'inertie dans le mouvement mélodique, les notes suivantes étant obtenues en modifiant pas à pas les notes présentes, les intervalles mélodiques générés sont minimisés malgré le respect du but à réaliser qu'est l'intervalle harmonique cible.

 

Les deux premières voix étant gérées par ce processus évolutif, mais essentiellement linéaire (sans retour en arrière, sans répétition de motifs dans le temps), nous avons utilisé une méthode totalement différente pour générer la troisième voix. Cette fois, nous utiliserons un processus combinant la création et la répétition. D'autre part, l'intensité des deux premières voix était constante (réglée à une valeur moyenne). Les intensités des notes de la troisième voix seront générées de la même façon que leur hauteur, ceci introduisant une dynamique et un rapport étroit entre les hauteurs et les nuances.

 

Pour être en mesure de répéter des séquences, nous devons les mémoriser. Nous formons alors en mémoire une table de la longueur maximale des séquences, la première ligne de la table contenant les hauteurs des notes, la seconde contenant leurs intensités.

La troisième voix sera deux fois plus rapide que les deux premières (deux notes dans le temps indiqué par la variable tempo).

La table est lue pas à pas, depuis l'indice 0 jusqu'à une limite contenue dans une variable. Quand la limite est atteinte, la variable indice est remise à zéro. À chaque pas une note est émise, avec l'intensité et la hauteur lues dans la table.

De cette façon, si la limite ne varie pas, nous obtenons une séquence cyclique, strictement répétitive.

Mais une variable, contrôlée dans l'interface utilisateur, permet d'agir sur le cycle : la valeur de cette variable peut couvrir l'intervalle de 0 à 100.

Pour que cette valeur corresponde à un pourcentage de chance de changement, à chaque pas du cycle (avant chaque note), nous tirons aléatoirement une valeur entre 0 et 100. Si cette valeur est inférieure au pourcentage souhaité, alors nous exécutons les modifications :

• En premier lieu la modification de la limite de l'indice, donnant le nombre de notes de la séquence.

• Si la limite vaut 3 elle est portée à douze.

• Puis la limite est affectée par une valeur aléatoire comprise entre 3 et la valeur courante de la limite (étant fixée à six au départ, elle est donc toujours comprise entre 3 et 12).

La répétition de ces modifications font tendre progressivement la valeur de la limite vers 3, puis la première instruction la ramène vers une plus grande valeur. Cette progression peut toutefois être brutale. Le hasard peut également conserver indéfiniment la même valeur...

• Ensuite, toutes les valeurs de la table dans les cellules indéxées de zéro à la nouvelle limite sont simplement remplacées par de nouvelles valeurs prises aléatoirement entre des limites fixées. Pour les hauteurs entre 50 et 70 (le même ambitus que pour les deux premières voix), et pour les intensités entre 50 (mezzo forte) et 100 (forte). 127 étant fortissimo et 1 quasiment le silence.

 

Si le pourcentage de changement est réglé à zéro, nous obtenons une séquence parfaitement répétitive. S'il est réglé à 100, les valeurs de la table sont modifiées à chaque fois, donnant une séquence totalement aléatoire, renouvelée en permanence. Une valeur intermédiaire donnera des séquences répétées quelquefois puis remplacées par d'autres séquences. Le changement de séquence s’effectuant à un moment quelconque du cycle.

 

Le caractère aléatoire de la troisième voix est contrecarré par les répétitions. À l'écoute, cette troisième voix parait finalement être la première : Elle est deux fois plus rapide que les autres, et plus "répétitive", elle parait être accompagnée par les accords des deux premières voix. Ceci peut être accentué ou atténué par le choix des timbres et un réglage externe de la balance entre les voix. Les répétitions dépendent évidemment des réglages du pourcentage de changement, mais aussi de la table d'autorisation des successions d'intervalles : si la majorité des successions sont interdites, les deux voix se répètent souvent.

 

Un algorithme si simple ne peut fournir directement la matière à une œuvre, mais il fait partie d'un ensemble de modules, et doit être vu comme un élément intervenant pendant certaines périodes au sein d'une structure de niveau d'organisation supérieur. Les périodes générées par ce module sont globalement uniformes, il n'y a pas ici de développement dramatique.

 

 

6.5.4.2.      Le module Module

 

Le module Module est nommé ainsi car il génère des modulations, c'est-à-dire, des changement progressifs de tonalité et de mode, au travers de la génération d'une série d'accords.

 

Le principe est le suivant : À chaque appel de la fonction Métronome[90], l’accord généré précédemment est joué, puis analysé pour former la liste des tonalités auxquelles il peut appartenir. Un choix aléatoire est effectué pour sélectionner une de ces tonalités. Et enfin, un nouvel accord est reconstruit dans la tonalité choisie. Les tonalités analysées sont au nombre de 24 (12 tons majeurs et 12 tons mineurs harmoniques).

 

Une variable : tempo contrôle le nombre de millisecondes entre chaque appel de la fonction Métronome. la valeur minimale de tempo est 50 millisecondes.

 

La vélocité est la vitesse de frappe de la touche sur le clavier, elle doit être transmise dans le message MIDI commandant l’émission d’une note. Nous faisons varier la vélocité entre 30 et 127. Les limites extrêmes étant 1 et 127.

La valeur initiale de vélocité est de 64.

Puis, à chaque accord la vélocité est modifiée par la séquence suivante :

 

 

      velocite += aleatoire(-10, 10);

      if(velocite < 40)

            velocite = 100;

      else if(velocite > 117)

            velocite = 50;

 

 

La valeur de la variable vélocité est comprise entre 40 et 117, mais au moment de l’émission, la valeur de vélocité est modifiée par l’ajout d’une valeur aléatoire comprise entre -10 et +10.

 

L’émission de l’accord généré à l’appel précédent de Métronome est écrite comme suit :

 

 

for(k = 0; k < 5; k++)

{

      if(accord[k])

      {

            emettreNote(

            /* date */ MidiGetTime() + aleatoire(0, 300),

            /* canal */       k,

            /* hauteur */     accord[k],

            /* vélocite */    velocite + aleatoire(-10, 10),

            /* durée */       tempo + aleatoire(0, 200) );

      }

}

 

 

L’accord est contenu dans une table de 5 entrées. Une entrée nulle correspond à un silence, une valeur non nulle à un numéro de demi-ton dans le format MIDI.

MidiGetTime est une primitive de MIDIShare donnant le numéro de la milliseconde courante. L’ajout d’une valeur aléatoire (entre 0 et 300) à la date de l’attaque de la note permet d’obtenir des retards des notes d’un accord sur l’autre.

Les notes de l’accord ont globalement la même intensité (vélocité), mais des variations sont introduites par l’ajout de la valeur aléatoire entre -10 et 10.

Enfin, la durée de la note en millisecondes est calculée par la somme de la valeur du tempo et d’une prolongation aléatoire d’un cinquième de seconde au maximum.

La fonction EmettreNote construit un événement MIDIShare qui sera placé dans une liste d’attente triée par date d’émission, et émis à terme.

 

La phase suivante est l’analyse des tons possibles. Le plus simple et le plus direct est de parcourir les 24 tonalités et dans chaque tonalité, vérifier si toutes les notes de l’accord sont présentes. Ou plus exactement éliminer les tonalités pour lesquelles au moins une note de l’accord est absente.

Ce n’est évidemment pas une simulation de l’oreille humaine, ni une méthode subtile, mais le nombre de notes à traiter dans le temps imparti se prête à cette écriture combinatoire.

 

Dans le code suivant, la table tons est de 2 * 12 entrées. La variable t représente un ton de 0 à 11 (0 étant do), la variable m le mode (0 majeur, 1 mineur), la variable k le numéro de la note dans l’accord.

La variable dt est la note de l’accord rabattue sur la première octave par l’opération modulo 12, et la variable d est le degré de la gamme (de 0 à 6).

 

 

for(t = 0; t < 12; t++)

{

      for(m = 0; m < 2; m++)

      {

            tons[m][t] = 1;

            for(k = 0; tons[m][t] && k < 5; k++)

            {

                  if(accord[k])

                  {

                        int dt = accord[k] % 12;

                        int d;

                       

                        for(d = 0; d < 7; d++)

                        {

                             if((t+Gamme[m][d])%12== dt)

                             {

                                   break;

                             }

                        }

                        if(d == 7)

                        {

                             tons[m][t] = 0;

                        }

                  }

            }

      }

}

 

 

La phase suivante est le choix d’une des tonalités. Une première boucle dénombre les tonalités possibles (nb). Puis un nombre est tiré aléatoirement (choix) pour déterminer la tonalité parmi les possibles.

 

{

      int nb = 0;

      int choix;

     

      for(t = 0; t < 12; t++)

      {

            for(m = 0; m < 2; m++)

            {

                  if(tons[m][t]) nb++;

            }

      }

      choix = aleatoire(1, nb);

      for(t = 0; choix && t < 12; t++)

      {

            for(m = 0; choix && m < 2; m++)

            {

                  if(tons[m][t])

                  {

                        choix--;

                        if(!choix)

                        {

                             tonique = t;

                             mode = m;

                        }

                  }

            }

      }

}

 

 

Enfin, la dernière phase est la construction de l’accord suivant.

Le degré de la fondamentale de l’accord (degre) est choisi aléatoirement. Ensuite les notes de l’accord sont prises parmi les notes suivantes en allant de deux degrés en deux degrés. La formule (degre + 2 * aleatoire(0, 4)) % 7 donne aléatoirement un degré appartenant à l’accord de 5 sons formé de tierce en tierce à partir de degre.

Les notes de l’accord ainsi généré ne sont pas ordonnées, et ne prennent en compte les notes de l’accord précédent qu’au travers de l’interprétation de la tonalité de celui-ci.

 

 

degre = aleatoire(0, 6);

for(k = 0; k < 5; k++)

{

      int octave = aleatoire(3, 5);

      if(aleatoire(0, 100) > 40)

      {

            accord[k] =

                  tonique

                  + octave * 12

                  + Gamme[mode]

                        [(degre + 2*aleatoire(0, 4)) % 7];

      }

      else

      {

            accord[k] = 0;

      }

}

 

 

Dans 40% des cas, la note est remplacée par un silence.

 

Une voie supplémentaire a été introduite, pour jouer des notes prises dans la tonalité et le mode courant. Une seconde fonction Métronome exécute le code suivant :

 

 

octave = aleatoire(4,7);

hauteur =

      tonique

      + octave * 12

      + Gamme[mode][aleatoire(0, 6)];

 

emettreNote(

      /* date */ MidiGetTime(),

      /* canal */ 5,

      /* hauteur */ hauteur,

      /* vélocité */ aleatoire(50, 127),

      /* durée */ tempo / 2

      );

 

 

Le tempo de cette seconde fonction Métronome  est réglé au cinquième de la première, en conservant malgré tout la même limite inférieure de 50 millisecondes. La durée des notes de cette voix est la moitié du temps séparant les attaques. La vélocité est aléatoire et la hauteur est aléatoire également, mais dans le mode et la tonalité sélectionnée par la première fonction Métronome. Cette mélodie anticipe donc l’interprétation qui sera confirmée par l’audition de l’accord suivant.

L’interface permet d’activer ou de désactiver indépendamment les deux fonctions Métronome.

 

Figure 6.30

 

Ci-dessus (figure 6.30), un extrait de ce que produit Module, reproduit dans un phonogramme. Les traits sont plus allongés à droite de l’image à cause d’une variation du tempo au cours de l’exécution.

Ci-dessous (figure 6.31) un autre extrait du produit de Module, transcrit en fichier MIDI et importé dans un éditeur de partition. Les canaux sont retranscrits individuellement sur chaque portée. La première portée est en clé de sol les suivantes en clé de fa.

Figure 6.31

 

6.5.4.3.      Le module Pouzzolane

 

Le module dénommé Pouzzolane est basé sur un algorithme de génération de lignes mélodiques associé à un système de mémorisation influencé par le temps.

 

Le principe de cet algorithme est fondé sur l’idée suivante : On se remémore fréquemment des éléments récents que l’on oublie également plus souvent. À l’inverse, les souvenirs plus anciens interviennent moins fréquemment, mais sont conservés plus longtemps que les précédents.

 

Nous associons au module générateur de mélodies une banque de mémoires mélodiques et rythmiques[91] dont l’accès aléatoire est pondéré de façon à atteindre les différents registres avec une probabilité variable (cf. § Arbres d’appels de fonction pseudo-aléatoire).

 

L’application utilisant cet algorithme, Pouzzolane, génère huit voix en temps réel et peut être paramétré pendant l’exécution.

 

Figure 6.32 : Fenêtre de contrôle de Pouzzolane

 

Les contrôles externes du programme Pouzzolane (figure 6.24) sont au nombre de huit :

   • Un drapeau contrôlant la marche et l’arrêt du système (case marche). En fait, ce booléen contrôle l’émission du flux MIDI mais le calcul de l’algorithme ne s’arrête qu’à la terminaison de l’exécution du programme.

   • Un drapeau contrôlant le mode de répartition des voix sur les canaux MIDI : en mode poly,[92] un canal par voix, et sinon toutes les voix sont émises sur le même canal (case poly).

   • Une valeur exprimée en millisecondes donnant la pulsation de base, nommée tempo. Cette valeur est la valeur de retour de la fonction Métronome, elle est bornée à gauche par la limite arbitraire de 30 millisecondes. En effet, si le tempo prenait une valeur inférieure au temps nécessaire au traitement des interactions avec l’utilisateur, plus aucun contrôle ne serait possible.

• Cinq variables enfin, expriment des pourcentages permettant de contrôler les chances d’occurrence d’événements divers :

              • La création, ou recomposition de la mélodie d’une voix.

              • La mémorisation, ou copie de la mélodie d’une voix dans la banque de mélodies.

              • Le rappel, ou remplacement de la mélodie d’une voix par une mélodie de la banque de mélodies.

              • L’occurrence d’un silence.

              • Le changement de longueur de la mélodie[93] d’une voix.

 

 

6.5.4.3.1.               Structure des mémoires mélodiques

 

La mémoire principale (figure 6.33), qui est lue pour l’exécution, est une table de mélodies indexées par voix et par note. À chaque entrée on obtient un degré (de 0 à 6), une octave (un numéro d’octave) et une durée (en nombre de pulsations).

 

Figure 6.33 : mémoire principale

 

À chaque voix, on associe également une longueur, c'est-à-dire un nombre supérieur ou égal à 2 et inférieur ou égal à la longueur maximale, qui détermine le nombre de notes réellement jouées.

 

La mémoire secondaire (figure 6.34), ou banque de mémoires mélodiques, sur laquelle porte le principe du système, est constituée d’une table indexée par voix et par âge probable, chaque entrée fournissant une table de mélodie.

 

Figure 6.34

 

La probabilité d’accès est plus grande pour la partie récente (en haut sur le schéma) dans les indices faibles, et moins grande pour la partie ancienne de la banque dans les indices forts.

Le nombre de mémoires est actuellement fixé à 30, le nombre de voix à huit et la longueur maximale des mélodie à 12 notes. Cela représente environ 17K octets pour la banque.

 

6.5.4.3.2.               Algorithme de Pouzzolane

 

6.5.4.3.2.1.             Initialisation

 

Au départ, la mémoire principale est initialisée par un appel à la fonction de composition d’une mélodie pour chaque voix. Puis, la mélodie de la première voix est reproduite dans toute la banque secondaire.

 

6.5.4.3.2.2.             Un battement de Métronome

 

À chaque battement du tempo, c’est-à-dire à chaque appel de la fonction Métronome, et pour chaque voix indépendamment, nous effectuons les étapes suivantes :

              • Création

              • Mémorisation

              • Rappel

              • Émission

L’exécution de chaque étape est conditionnelle.

 

Création : La variable contenant le pourcentage de création est comparée à une valeur aléatoire comprise entre 0 et 100. Si cette valeur est inférieure à la valeur de la variable, alors la mémoire principale de cette voix est recomposée, pour sa longueur maximale, mais sa longueur actuelle n’est pas modifiée.

 

   • Mémorisation : Ensuite, en utilisant le même principe de comparaison de la variable de pourcentage avec un tirage aléatoire, on détermine si une mémorisation intervient. Dans ce cas : la mémoire principale de cette voix est recopiée dans une mémoire de la banque dont la valeur de l’indice est calculé comme suit :

  

 

      indice = aléatoire(0,

                        aléatoire(0,

                              aléatoire(0, nombre de mémoires)))

 

 

L’indice a une plus forte probabilité (cf. paragraphe Règles de pondération des tirages aléatoires) d’être proche de 0 (la mémoire récente), que d’indiquer de la mémoire ancienne par un valeur forte (proche du nombre de mémoires).

 

Rappel : Toujours pour le même battement, et à la suite des actions précédentes, le tirage aléatoire suivant permet de décider du rappel d’une mémoire secondaire, en respectant le pourcentage d’occurrence de rappels. Si un rappel doit avoir lieu, l’indice de la mémoire secondaire à recopier dans la mémoire principale est calculé par la même formule que précédemment. L’effet de l’étape de création précédente (si elle à eu lieu) peut ainsi être anéanti.

 

Émission : À chaque voix est associé un compte à rebours. Si celui-ci est à zéro, et que le drapeau de marche est armé, l’émission d’une note de la mélodie est provoquée. Une table supplémentaire fournit l’indice de la note à jouer pour la voix courante. Il est à noter que le format des données permet la modification de la mélodie et du rythme par la recomposition ou le rappel en cours d’exécution par le simple remplacement des valeurs dans la table.

Le compte à rebours est alors réaffecté avec la durée de la note qui vient d’être émise.

Pour respecter le choix du pourcentage de silences le compte à rebours peut être augmenté d’une valeur dépendant de la longueur de la mélodie.

Si un événement de silence doit être déclenché, la durée du silence est donné par le formule :

 

 

      durée du silence =

            aléatoire(0, aléatoire(1, 5) * longueur[voix])

 

 

• Si le compte à rebours est positif, il est décrémenté.

• Changement de longueur des mélodies : La longueur de la mélodie est modifiée avec la probabilité indiquée par un pourcentage. La nouvelle longueur de la mélodie de la voix courante est alors fixée par un tirage aléatoire équiprobable entre 2 et la longueur maximale.

 

• Enfin, le pointeur de note (position dans la mélodie) est incrémenté modulo la longueur actuelle de la mélodie.

 

6.5.4.3.2.3.             La composition des mélodies

 

Les mémoires mélodiques contiennent des valeurs en degrés et octaves. Les degrés sont des indices dans une table donnant le mode. Par exemple {0, 2, 4, 5, 7, 9, 11} pour le mode majeur classique. Une variable indique la tonalité de base, et la hauteur en demi-tons est calculée par :

             

 

hauteur = tonalité + 12 * octave + mode[degré]

 

 

La mélodie circule entre une limite basse et une limite haute, lb et lh.

La première note est fixée au hasard (tirage aléatoire équiprobable) puis, les notes suivantes dépendent de la note précédente et d’une orientation de la mélodie (montante ou descendante) influencée également par la hauteur de la note précédente.

 

 

Pour chaque note (suivant la première) :

            a = aléatoire(lb, lh)

            intervalle = aléatoire(seconde,

                             aléatoire(seconde,

                                   aléatoire(seconde, sixte)))

            si a > note précédente

                  note = note précédente + intervalle

            sinon

                  note = note précédente - intervalle

 

où seconde = 1, et sixte = 5

 

 

La durée des notes est donnée par :

 

 

durée = aléatoire(1, aléatoire(1, aléatoire(1, 5)))

 

 

Cette formule est la même que celle donnant l’intervalle mélodique.

 

  

6.5.4.4.      Le module Alpha

 

Le module Alpha est un module générateur, influencé par certains aspects du flux musical reçu en entrée. Il analyse d’une part les rythmes et d’autre part les hauteurs des notes, pour générer des événements dans le tempo et dans le même mode et la même gamme que le flux d’entrée (dans la mesure ou le flux permet d’identifier une structure rythmique ou tonale). Nous avons développé ce module indépendamment des travaux de ROWE, qui utilise des réseaux neuromimétiques pour que CYPHER (ROWE 1992) reconnaisse l’harmonie et les pulsations rythmiques.

D’autres systèmes de reconnaissance de structures musicales et des rythmes ont vu le jour (CHAFE, MONT-REYNAUD, RUSH 1982), Fa (ROSENTHAL 1992) est un programme écrit en LISP (WERTZ 1989) pour le Macintosh qui analyse les rythmes en se basant sur une étude des perceptions humaines.

Pour l’harmonie, ROWE utilise un réseau à deux couches, la couche d’entrée a 12 neurones correspondant aux douze demi-tons de la gamme chromatique, et la couche de sortie possède 24 neurones correspondant aux 24 tonalités classiques (12 gammes majeures et 12 gammes mineures). La présence des notes vient renforcer ou inhiber les tonalités.

 

Notre module contient une table triangulaire, de trente deux lignes[94]. La première ligne comporte une cellule, la seconde deux cellules, la nième ligne comporte n  cellules. Chaque cellule permet de mémoriser une hauteur, une durée, et une intensité. A chaque ligne est associée une valeur de satisfaction rythmique, et une valeur de satisfaction pour les hauteurs.

L’analyse consiste en la mise à jour des valeurs de satisfactions, et la génération consiste en l’exploitation des données contenues dans la ligne de plus haute satisfaction, d’une part pour les hauteurs, et d’autre part pour les durées rythmiques.

Le module Alpha reçoit les événements MIDI par une procédure sous interruption. Au moment de leur arrivée, les événements sont enregistrés dans une pile FIFO, puis, dans la boucle principale du programme, les événements sont traités :

à chaque ligne est associé un pointeur indiquant la cellule courante, ce pointeur est incrémenté modulo la longueur de la ligne. La hauteur, et la durée de l’événement sont comparées avec les valeurs de la cellule courante. Si les valeurs coïncident, la satisfaction (mélodique pour les hauteurs, et/ou rythmique pour les durées) est augmentée. Si au contraire, les valeurs diffèrent, la satisfaction est diminuée, jusqu’à un seuil minimum, et les nouvelles valeurs viennent remplacer les anciennes. Les valeurs de hauteurs sont comparées exactement (ce sont des valeurs entières, exprimées en demi-tons, et variant de 1 à 127). Les valeurs de durées, comptées en millisecondes écoulées entre deux attaques successives, sont arrondies au multiple de x inférieur avant la comparaison, x exprimant ainsi une tolérance rythmique du système. Nos expériences ont été réalisées avec des valeurs de x comprises entre 10 et 30 millisecondes.

Si le flux d’entrée contient des séquences répétitives, ces séquences ont une longueur déterminée, et la ligne dont la longueur correspond verra sa satisfaction augmenter. L’indépendance entre la satisfaction rythmique et la satisfaction mélodique permet éventuellement de sélectionner des lignes plus courtes que le motif répété : par exemple si les trois hauteurs la si do, sont répétées sur un rythme de quatre durées, la ligne 4 sera sélectionnée pour le rythme et la ligne 3 pour la mélodie, alors que le motif total a une longueur de 3 * 4 = 12 notes.

Pour la génération, nous pouvons utiliser les durées, les hauteurs et les intensités enregistrées dans les lignes de plus grande satisfaction. Nous pouvons en conserver l’ordre ou les utiliser dans un ordre différent. Nous pouvons encore générer aléatoirement des séquences conservant certaines caractéristiques des lignes sélectionnées, par exemple le même ambitus, le même nombre de notes, la même durée totale, etc.

Pour que le système se synchronise avec les événements futurs, nous calculons, d’après la date de la première note de la ligne et la durée totale de la ligne, l’instant de départ du prochain cycle. Puis nous émettons une séquence correspondant à un cycle. Le système de génération est alors mis en veille jusqu’à la fin de cette séquence.

 

6.6       Exosmose

 

La boîte à outils, la boîte à fenêtres, les modules d’allocation et de visualisation de mémoire, le système de description de contrôles, et les squelettes d’applications basés sur le module Métronome, permettent de construire rapidement une application spécifique d’une expérience de programmation musicale à mener.

Lorsque la nouvelle application est construite, elle est immédiatement connectable avec les applications existantes. Par exemple, si c’est une application générant un flux MIDI, ce flux peut être visualisé en tant que phonogramme, ou filtré par le module Alpha, avant d’être enregistré sous forme de fichier MIDI, état intermédiaire précédant l’édition sous forme de partition.

De l’intérieur, du point de vue de la programmation, les éléments de l’atelier aident à la l’élaboration, la construction, l’écriture, la modification, pour déboucher vers l’extérieur, sur l’intégration d’un nouvel élément utilisable dans l’activité compositionnelle[95].

 

La troisième catégorie d’applications de notre atelier, décrite dans le chapitre suivant, utilise également des noyaux de génération, mais ceux-ci produisent des séquences qui sont présentées sous forme de partitions traditionnelles et non plus de flux MIDI. Le flux MIDIpourra toutefois être généré dans un but de contrôle.


7.         Générateurs de partitions

 

Ne disposant pas d’écran graphique ni d’imprimante matricielle ni de table traçante, nous avons, dès 1978 réalisé des programmes imprimant des partitions avec les caractères alphanumériques des imprimantes classiques, comme le fit Lejaren HILLER en 1965 (HILLER 1965).

 

 

+-----------------+

|            O    |

+-------O---------+

|       #         |

+--O--------------+

|       O    b    |

+-----------------+

|                 |

+-----------------+

 

Figure 7.1

 

Voici un exemple (figure 7.1) de ce type de représentation que nous avons utilisé en 1977 : les successions de caractères “-” formant les lignes des portées, les lignes verticales (barres de mesures) étant formées à l’aide de caractères “|” , et leurs intersections avec des “+”. Les notes sont représentées par des “O” ou directement par leur altération “b” ou “#” pour simplifier la procédure d’écriture[96].

Des partitions pour orchestre : BABEL (en 1982-83), de musique de chambre : ECORCES (1983-84), et pour orgue : GZ50 (en 1979-80) ont ainsi été réalisée par Giuseppe ENGLERT (ENGLERT 1982-85). Dans ses partitions, la notation des durées est proportionnelle et les caractères utilisés indiquent différentes articulations.

Le développement de l’infographie (les écrans graphiques, les imprimantes laser, etc.) rend possible la programmation d’éditeurs ou de générateurs de partitions aboutissant à une qualité comparable à celle des gravures. Des polices de caractères sont prévues pour la représentation des symboles musicaux.

 

A B CD E F G H I J K L M N O P Q RS T U V W Z

a b c de f g h i j k l m n o p q rs t u v w x y z

Figure 7.2 : Un extrait de la police de caractère Petrucci.

 

Mis à part le dessin des symboles, le problème majeur dans l’écriture musicale est la mise en page, ou la justification des textes musicaux. Mockingbird , l’éditeur de partition développé par ORNSTEIN et son équipe calcule automatiquement la justification horizontale d’après des indications globales de densité (ROADS 1981).

 

7.1.      Éditeurs de partitions

 

Les éditeurs de partitions proposent généralement une fonctionnalité de conversion des fichiers MIDI vers leur format interne, ainsi que la possibilité de saisir les notes en les jouant directement sur un clavier MIDI, ou en les émettant depuis tout système capable de générer un flux MIDI. Deux problèmes majeurs apparaissent : d’une part la gestion temporelle est délicate, les événements MIDI ne sont pas forcément en mesure, d’autre part l’information contenue dans le flux MIDI est exempte de toute indication de mise en page.

Le problème temporel est traité en partie par un réglage d’options de discrétisation du temps incluant principalement le tempo et le symbole représentant la plus petite durée représentable.

Quant à la mise en page, les éditeurs adoptent pour les différents paramètres des valeurs par défaut, et l’utilisateur doit corriger la mise en page manuellement.

 

7.2.     Chnrng14 : Générateur de partitions pour piano et orchestre

 

Le nom CHNRNG14 provient du nom de l’algorithme de permutation (change ring) utilisé pour permuter les 14 accords de la structure verticale de la pièce.

L’application CHNRNG14 est constituée d’un module de génération et d’un module de visualisation et d’impression.

Le module de génération est spécifique de la pièce et sa structure reflète donc parfaitement la structure de la composition : La pièce étant formée de périodes, la fonction génératrice itère sur les périodes. Chaque période de 10 mesures à quatre temps est constituée de 14 accords (ou agrégats). Les agrégats sont lus depuis une table initialisée manuellement, mais l’ordre d’apparition des agrégats est déterminé par l’algorithme de permutation. La durée individuelle des agrégats est variable, mais la durée totale des 14 agrégats est constante. La composition de l’orchestre est déterminée pour chaque période : Tutti ou Archi. Chaque voix construit sa ligne mélodique en prélevant les notes dans les agrégats, en fonction de l’instrument (donnant le registre[97] , et mémorisant l’information de phrasé : début de phrase, phrase, fin de phrase ou respiration).

La méthode de détermination des structures rythmiques et des articulations varie selon la valeur d’une variable indiquant un mouvement global : Calmo, Agitato, ... Les durées des notes sont initialement calculées pour coïncider avec la durée des agrégats dont elles sont extraites, mais une deuxième phase vient perturber cette régularité en introduisant des retards (notes prolongées sur l’accord suivant) ou des anticipations (notes commençant avant l’accord auquelles elles appartiennent). Les notes peuvent ainsi chevaucher les limites des périodes.

 

7.3.     Impression de partitions

 

Les partitions habituelles sont des graphiques structurés, nous allons dans un premier temps décrire brièvement cette structure et établir les liens entre les éléments graphiques et leur signification sur le plan musical. Il s'agit ici d'offrir à un lecteur ne connaissant pas le solfège les points de repères et la terminologie suffisante pour la suite de l'exposé.

Puis nous considérerons les éléments nécessaires par rapport au contexte de la pièce pour laquelle a été conçu le module d'impression. Enfin, nous décrirons les points particuliers de l'implémentation d'un tel module.

 

7.3.1.         Notation musicale

 

Les partitions doivent permettre d'écrire, d'encoder les éléments principaux des pièces musicales instrumentales ou vocales[98] en vue de leur exécution ultérieure. Comme l'écriture alphabétique, la notation musicale ne retient qu'une partie du discours. L'écriture alphabétique ne permet pas d'encoder le ton, ou la vitesse avec laquelle une phrase doit être prononcée[99]. Ce que nous avons nommé éléments principaux sont sans doute les traits essentiels d'une musique ou qu'une époque à considéré ou considère comme fondamentaux. Ainsi, la notation musicale évolue en permanence[100], les auteurs peuvent inventer de nouvelles notations, leur permettant de spécifier des traits qui, prenant une importance particulière pour une pièce, sont laissés à l'appréciation de l'interprète dans d'autres œuvres. La notation peut également décrire des éléments qui semblent extérieurs au domaine musical, par exemple la position de l'interprète, ou la chorégraphie organisant les mouvements des instrumentistes. Certaines œuvres, telle la pièce Acqua de Giuseppe CHIARI (DORFLES 1976) ne spécifient aucune note, mais utilisent une notation d'événements ou de mouvements qui provoqueront l'apparition d'éléments sonores lors de leur exécution. Dans sa méthode pour piano, CHIARI utilise une écriture permettant de spécifier différentes façons de croiser les doigts des deux mains, de joindre les mains : ensuite, les mouvements des mains sur le clavier déclenchent des séquences de notes différentes suivant la façon dont les mains sont jointes. D'autres partitions sont simplement des graphiques, des dessins, sans sémantique symbolique, que les interprètes doivent retranscrire en musique d'après leur propre sensibilité.

Les partitions que les instrumentistes interprètent ne sont pas toujours des partitions classiques sous la forme de pentagrammes.

Certaines partitions sont graphiques, et demandent aux interprètes une interprétation non plus basée sur les symboles mais sur un plan imaginaire.

 

Figure 7.3 : Extrait de Treatise de Cornelius CARDEW

 

Dans cet extrait d’une page de Treatise de Cornelius CARDEW (CARDEW 1967), on trouve encore une influence dans le graphisme des symboles utilisés en musique, mais ils sont déplacés, déformés, exagérés, et soutenus par une architecture graphique articulée dans l’espace bidimensionnel de la page, et non pas sur les conventions d’écriture des pentagrammes. Le développement du graphisme laisse sentir le déroulement temporel dans la dimension horizontale, comme dans les partitions classiques, mais aussi comme dans nos phonogrammes. C’est pourquoi nous avons réalisé l’expérience de l’interprétation de quelques pages de CARDEW directement en tant que phonogrammes.

 

Nous décrivons ici les pentagrammes, c'est-à-dire la notation habituelle de la musique, sur des portées de cinq lignes.

Cette notation permet d'encoder des successions et des superpositions de notes dans le temps. La note est vue ici comme un événement sonore ayant une certaine hauteur, une amplitude et une durée.

La note peut également subir des modifications portant sur la façon de la jouer et de l'enchaîner aux autres notes : les articulations. Elle peut être détachée ou liée aux notes précédentes ou suivantes, piquée (jouée détachée et en écourtant la durée du son), lourée (jouée liée, ou avec une attaque faible, en marquant les temps forts), etc...

Les hauteurs sont sensées appartenir à la gamme chromatique (cf. § Harmonies). Il existe toutefois différents systèmes de notation de hauteur pour les intervalles inférieurs au demi-ton, les micro-intervalles, mais la notation habituelle utilise principalement les demi-tons, et les instruments de musique sont conçus pour jouer dans la gamme chromatique[101]. En fait, les portées ont été conçues pour écrire des hauteurs diatoniques[102] avant les hauteurs chromatiques.

 

Figure 7.4

 

La gamme do, ré, mi... en clef de sol (Figure 7.4), le sol est sur la deuxième ligne, les lignes sont comptées à partir du bas. La clef initiale de chaque portée donne un repère indiquant une note de référence : le tracé de la clef de sol commence sur la deuxième ligne. D’autres clefs, les clefs de fa, les clefs d’ut, placées sur différentes lignes indiquent des repères pour des encodages différents des hauteurs. Les différentes clefs sont nécessaires pour que, suivant l’ambitus[103] des instruments, les notes utilisées fréquemment restent vers le centre de la portée.

 

Ci-dessous (figure 7.5), la gamme chromatique en clef de fa quatrième ligne.

 

Figure 7.5 : La gamme chromatique

 

Le dièse   précédant une note indique que cette note et toutes les notes suivantes du même nom dans la mesure doivent être jouées un demi-ton plus haut (sauf nouvelle indication). Le bémol  agit de la même façon mais en baissant les notes d’un demi-ton. Et le bécarre  enfin, restitue aux notes précédemment altérées leur hauteur naturelle. Dièse et bémol (et bécarre) sont nommés globalement altérations, dièses et bémols peuvent être doublés pour indiquer un changement d’un ton. Les altérations entre parenthèses permettent de rappeler l’altération de la note.

 

7.3.1.1.      Structures des pages

 

Les pages d’une partition sont composées de systèmes, chaque système est un ensemble de portées. Les portées sont formées de cinq lignes continues, et peuvent être étendues localement, pour un petit groupe de notes ou une note unique, par des lignes supplémentaires. Les espaces inter-systèmes sont variables ainsi que les espaces entre les portées. Mais si les systèmes d’une page sont à enchaîner (à jouer les uns après les autres), les espaces sont conservés d’un système à l’autre.

 

Figure 7.6

 

Les systèmes sont indiqués par des barres, des accolades, ou des crochets à gauche de la page.

 

Figure 7.7 : Exemple de regroupement des portées d’un système

 

Cet exemple (figure 7.7) a été réalisé avec le programme ENCORE[104]. Les regroupements peuvent avoir plusieurs niveaux d’imbrication. Dans un même système, les barres de mesures ont une position horizontale identique. Même si les barres n’unissent pas les portées, elles sont alignées verticalement si les portées sont jouées simultanément.

Les chiffres 4 superposés indiquent la mesure : le nombre supérieur est un cardinal et le nombre inférieur est un code correspondant à un symbole de durée (la correspondance est donnée dans la table ci-dessous). La mesure à 4/4 indique donc quatre noires par mesure.

 

Figure 7.8

 

Cette table donne les symboles de base[105] permettant de représenter les durées (les notes à droite et les silences de même durée à gauche). La durée de chaque symbole est le double de la durée du symbole immédiatement en dessous. Les valeurs de droite indiquent le nombre de symboles nécessaires pour former la durée d’une ronde. Ces symboles de durée indiquent des durées relatives au tempo. Nous ne décrirons pas plus avant les détails de l’écriture du point de vue rythmique[106], mais d’autres règles permettent de modifier ces indications de durées. Par exemple un point après un symbole le prolonge de la moitié de sa durée. Ou encore, un regroupement de notes visualisé par une ligne portant un nombre au dessus ou au dessous des notes, indique que les durées doivent être multipliées par une fraction (un trois au dessus de 3 croches, indique une multiplication de la durée par , un 5 sur quatre doubles-croches indique une multiplication par ).

Les crochets indiquant les croches, les doubles-croches, etc., peuvent être regroupées sous la forme de barres unissant les hampes des notes pour faciliter la lecture (comme dans l’exemple de la gamme chromatique ci-dessus). En général, les groupes ne franchissent pas les frontières d’un temps. Un temps, c'est-à-dire l’unité de temps, est la durée correspondant à une pulsation du tempo. Dans une mesure à 4/4, le temps est la noire. Dans une mesure à 6/8, le temps est la noire pointée (équivalent à la durée de trois croches).

 

Les barres de mesures coupent les cinq lignes de la portée, mais peuvent être prolongées pour unir les portées d’un système, ou un groupe de portées d’un système. Les dimensions des éléments graphiques sont variables, comme les corps de caractères en typographie, la graisse est également variable, mais certaines tailles doivent être corrélées : par exemple le rapport entre l’écartement des lignes et la dimension des têtes de notes.

 

 

Figure 7.8

 

Dans le cas d’une note située dans un interligne, la note doit être en contact avec les lignes. Dans le cas d’une note placée sur une ligne, il doit y avoir un espace séparant la note des lignes voisines. Le schéma ci-dessus (figure 7.8) montre des notes lisibles en haut et illisibles en bas.

Les têtes de notes ont toutes la même taille, sauf les blanches et les rondes, généralement plus grosses que les autres. Dans l’exemple ci-dessous (figure 7.9), les blanches ont la même taille que les noires, ceci dépend du choix de l’éditeur.

 

 

Figure 7.9

 

Les têtes des notes ne sont pas circulaires (figure 7.9, à gauche), le grossissement montre leur forme ellipsoïdale et l’inclinaison de l’axe de l’ellipse pour les blanches et les noires.

 

Dans une même page, les portées peuvent être de dimensions variables, par exemple, dans une partie d’accompagnement de piano, les portées pour le piano sont en taille normale, et les portées pour la voix du soliste sont écrites en taille réduite. Le pianiste n’a pas à lire les notes (les hauteurs) du soliste, mais il doit lire globalement l’allure de la mélodie, les rythmes, et surtout les points de départ (les synchronisations).

 

Figure 7.10

 

Dans une même portée, des notes peuvent apparaître dans une taille réduite : les petites notes, représentent les agréments (appoggiatures, fioritures et ornements).

 

7.3.1.2.      La lecture

 

La lecture est effectuée de gauche à droite, et cette direction correspond globalement au déroulement temporel. Les systèmes d’une page sont lus les uns après les autres (de haut en bas). Les groupes de notes simultanées (les accords) alignées verticalement, éventuellement dans plusieurs portées, se lisent de bas en haut. Une page peut ne comporter que des portées à lire simultanément (de bas en haut) si elle est constituée d’un seul système (figure 7.11).

 

Figure 7.11

 

L’apparence de la page est simplifiée, donc sa lecture facilitée, si les mesures sont d’une taille régulière, mais les variations de densité forcent parfois à agrandir localement une mesure (ou un groupe de mesures) pour éviter les espaces trop nombreux qui seraient engendrés en écartant l’ensemble des mesures à la dimension nécessaire à la plus dense. Verticalement, la gestion des espaces est similaire : les espaces entre les portées sont les plus réguliers possibles, mais la densité de notes extrêmes peut forcer l’ajustement de la position verticale de certaines portées.

 

7.3.2.         Module d'impression

 

Le module d'impression prend en entrée une structure provenant du module de génération et des données de mise en page et de sélection provenant de l'interface utilisateur. Son rôle est d’effectuer la mise en page et de tracer la feuille sélectionnée dans le système d’écriture conventionnel, en visant une lisibilité optimale sans intervention manuelle.

 

7.3.2.1.      Structure des événements sonores et silencieux

 

La structure générée est constituée de tables de listes d'événements sonores ou silencieux. Nous désignerons par le terme note  ces événements. Les notes sont représentées par des structures, contenant :

• L’information relative à chacune : telle la hauteur de la note, sa durée, son articulation.

• L’information sur la structure : les liens vers la note précédente et vers la note suivante constituant ainsi les listes de chaque voix.

• L’information sur la voix à laquelle appartient la note : une référence vers l'instrument jouant la voix[107], l’information sur le phrasé[108], ou encore sur des modes de jeu de l'instrument, par exemple le contrôle de la sourdine d'instruments tels les violons, ou les trompettes.

 

Figure 7.12

 

La figure ci-dessus (figure 7.12) résume la structure fournie par le module de génération. La partition est constituée de la table des périodes. Chaque période (correspondant à un certain nombre de mesures, 10 pour la pièce CHACONES) est décrite par une table de départs. Un départ est un couple formé par une durée et une référence à une note : la note débutant la période pour une voix donnée. La durée enregistrée dans chaque départ est la durée de la note de départ déjà écoulée dans la période précédente. Les notes peuvent ainsi chevaucher les limites des périodes, le chaînage n'est pas interrompu par les périodes. Les tables de départs comprennent autant d'entrées que de voix. Nous construisons également un chaînage de notes par voix. Chaque note pointe vers la note la suivant et vers la note la précédant ainsi que vers une structure instrument (les structures instrument apparaissent également dans le schéma de structure de l'orchestre, ci-après).

 

7.3.2.1.1.               La structure des notes

 

Les structures des notes sont encodées sur seize octets. Douze octets contiennent les pointeurs vers les notes adjacentes et vers l’instrument, et quatre octets contiennent les paramètres de la note.

 

Figure 7.13

 

7.3.2.1.1.1.             Les hauteurs

 

La hauteur correspond à un numéro de demi-ton (similaire au code MIDI, mais transposé de 2 octaves vers le bas). Le zéro étant le do le plus grave jouable sur un instrument acoustique. La hauteur des événements silencieux est fixée à zéro, et son articulation à la valeur Tacet. (voir ci-dessous).

 

7.3.2.1.1.2.             Les durées

 

La durée totale de la note correspond au nombre d’unités de temps séparant l’attaque de cette note de l’attaque de la note suivante. Nous considérons la double-croche comme étant l’unité de temps.

La durée de silence est le nombre d’unités de temps séparant la fin de la partie sonore de l’événement de l’attaque de la note suivante (figure 7.14). Les événements silencieux ont une durée de silence égale à la durée totale.

 

Figure 7.14

 

7.3.2.1.1.3.             Les articulations

 

Les articulations, encodées sur trois bits sont les suivantes :

 

   • Tacet            Détermine un événement silencieux (figure 7.15).

 

Figure 7.15

 

   • Sostenuto     Notes normalement soutenues, jouées liées ou avec une légère attaque (figure 7.16).

 

                                           

Figure 7.16

 

   • Staccato       Notes piquées (figure 7.17). La durée sonore est de 1, représentée par une double-croche, et le reste de la durée est représenté par des silences. La figure ci-dessous représente trois événements.

 

Figure 7.17

 

   • Vibrato         Lente modulation de fréquence (figure 7.18).

  

Figure 7.18

 

Les têtes des notes prennent la même forme qu’avec l’articulation Sostenuto, mais elles sont suivies d’une marque.

 

   • Portato         Notes soutenues mais diminuées d’une petite respiration (figure 7.19).

 

Figure 7.19

 

   • Sfz_pp          Sforzato pianissimo (figure 7.20), Attaquée fortement et soutenue faiblement.

 

Figure 7.20

 

   • Sordina        Les notes jouées en sourdine (figure 7.22) sont représentées avec la même apparence que les notes Sostenuto (figure 7.16). Mais des marques indiquent la pose ou le retrait de la sourdine (voir ci-après, § Les indications de sourdine).

 

   • Trémolo       Modulation d’amplitude (figure 7.21), symbolisée par trois barres obliques sur les hampes, ou au dessus des rondes.

 

Figure 7.21

 

7.3.2.1.1.4.             Les indications de sourdine

 

Un certain temps est nécessaire à l’instrumentiste pour poser ou retirer la sourdine. Pour faciliter ces opérations, la partition indique le plus tôt possible quand poser ou retirer la sourdine. En début de page, la présence de la sourdine est rappelée pour que l’instrumentiste puisse reprendre à n’importe quel point.

Dans l’exemple ci-dessous (figure 7.22), sur la première portée, l’articulation est Portato au début de la ligne. Dès la dernière note Portato, l’indication de pose de la sourdine apparaît pour préparer la phrase suivante.

Sur la troisième portée, la marque de pose () est rappelé en début de page, et la marque de retrait () est placé sur la dernière note jouée en sourdine.

Sur la quatrième portée, la marque de retrait apparaît, car la phrase précédente est en sourdine.

L’encodage des marques de sourdine est indépendant de l’articulation, il peut être porté par des événements silencieux ou sonores, et est effectué dans les deux bits Sourdine de la structure note. Les valeurs prises sont :

   • Sans sourdine

   • Début sourdine

   • Fin sourdine

   • Avec sourdine

 

Figure 7.22 : Exemples d’indications de sourdine.

 

7.3.2.1.1.5.             Les altérations

 

Les altérations sont encodées sur deux bits : les quatre codes sont :

   • sans altération (note naturelle, ou prolongation d’une note altérée),

   • bécarre,

   • dièse et

   • bémol.

 

7.3.2.1.1.6.             Les agrégats

 

Le bit agrégat  (figure 7.13) est utilisé dans la partie de piano pour placer le signe de séparation entre les agrégats. Un agrégat est un ensemble d’accord formé dans la même base harmonique (sur le même ensemble de hauteurs). La pédale de maintien doit être relevée entre les agrégats. Les sons d’un même agrégat peuvent être mélangés par l’action de la pédale.

 

7.3.2.2.      Information de mise en page et de sélection

 

L’information de mise en page concerne en premier lieu le type de mise en page souhaité :

• Partition pour le chef d'orchestre

• Parties séparées

• Partition de piano

 

Ce choix déterminera la façon dont seront constitués les systèmes et leur répartition dans les pages, ainsi que la disposition des voix (répartition des instruments dans les systèmes). Dans les parties séparées, les systèmes d'une page sont joués successivement, alors que dans la partition d'orchestre les systèmes d'une page sont tous joués simultanément.

D'autres paramètres sont déterminés par ce choix : par exemple la clef et la transposition dans laquelle sera écrite la voix (Le chef d'orchestre doit lire sans faire de transposition, alors que des instruments tels qu'une clarinette en si bémol sont notés avec une transposition dans la partie séparée).

Nous avons conçu le système pour imprimer le matériel d'orchestre sur des imprimantes au format A4[109]. Mais les pages des partitions sont beaucoup plus grandes : nous juxtaposons verticalement cinq feuilles A4 orientées à l'italienne pour former une page de la partition d'orchestre. Chaque page de la partition de piano est constituée de trois feuilles. Seules les parties séparées sont imprimées directement, une feuille par page.

Nous distinguerons dans la suite la page : format de la partition, de la feuille : format de l'impression, constituant de la page.

L’information de sélection détermine la feuille qu'il faut afficher.

Par exemple, pour la partition d'orchestre, nous donnons un numéro de page et un numéro de groupe d'instruments (chaque groupe correspondant à un numéro de feuille dans la page).

 

La première tâche du module d'impression est de calculer la mise en page, ou plus exactement la mise en feuille, c'est-à-dire, déterminer quelles voix doivent apparaître dans la feuille, et à partir de quel moment (quelle note et quel temps dans la note) la voix doit être affichée.

Ce calcul de mise en page produit des tables, permettant un accès direct aux notes correspondant au départ de chaque portée de chaque feuille pour un type de partition donné. Les tables de mise en page sont conservées tant que la sélection du type ne change pas.

Un paramétrage global influe sur la mise en page, il concerne le nombre de temps par mesure, le nombre de mesures par feuille, le nombre de portées par feuille, la taille de la feuille (dimensions verticale et horizontale en pixels), les dimensions des marges : marge de tête, marge de pied, marge de gauche et de droite, marge bordant les barres de mesures ; ceci permettant de déterminer les espaces inter-portées, la taille des mesures, l'espace correspondant à un temps. Ces paramètres sont fixés pour chaque type de partition et sont invariables pour toute la pièce, ils sont donc définis par des constantes. Ces valeurs peuvent toutefois être modifiées pour obtenir une mise en page différente.

 

Que ce soit pour l'affichage sur l'écran, ou pour l'impression sur papier, la fonction de tracé de la feuille est la même. En effet, c'est seulement le contexte graphique qui change, les primitives graphiques restent les mêmes.

 

Les différentes portées étant indépendantes, le tracé d'une feuille est décomposé en tracés de portée. L'espacement inter-portée est suffisant pour éviter toute interpénétration des signes d'une portée à l'autre.

Pour chaque feuille, des données globales sont tracées également : le numéro de page, ou de feuille, le numéro et le nom du groupe d'instruments, ou le nom de l'instrument.

 

Figure 7.23

 

La figure ci-dessus (figure 7.23) représente les liens de dépendance dans le calcul des dimensions dans le sens vertical. Les boîtes ne recevant pas de lien d'une boîte supérieure représentent les valeurs d'entrée (constantes de mise en page). Les boîtes recevant un ou plusieurs liens de boîtes supérieures sont calculées d'après celles-ci. Ci-dessous (figure 7.24), le calcul des dimensions dans le sens vertical.

 

Figure 7.24

 

Les barres et les crochets visualisant les systèmes sont tracés au niveau de la fonction de tracé des portées. Nous avons encodé les différents types de barres et de crochets au niveau des structures décrivant les instruments. Comme une note correspond à chaque portée, et que la note pointe vers l'instrument, on trace le signe correspondant au type de barre et au type de crochet souhaité.

 

Les types de barre sont :

 

   • sans barre                            (second instrument de la portée)

   • haut de barre                       (premier instrument d'un système)

   • milieu de barre                    (instrument à l'intérieur d'un système)

   • bas de barre             (dernier instrument du système)

 

De même, nous définissons quatre types de crochets : ceux correspondant à des instruments apparaissant en second dans la portée (sans crochet), ceux des premiers instruments d'un sous-système (haut de crochet), ceux des instruments étant à l'intérieur d'un sous-système (milieu de crochet) et enfin ceux des derniers instruments d'un sous-système (bas de crochet).

 

La description des instruments contient également la clef à utiliser selon le type de partition.

 

Figure 7.25

 

Les structures de typeinstrument ne décrivent pas seulement les instruments au sens courant du terme (nous spécifierons alors instruments physiques), mais elles décrivent également leur rôle au sein d'un groupe, l'ensemble des groupes formant l'orchestre. Un même instrument physique peut ainsi être représenté par de multiples structures de typeinstrument. Ceci permet de décrire des changements de mise en page et des changements d'orchestre[110] au cours du déroulement de la pièce.

 

7.3.2.3.      Décomposition en éléments graphiques

 

Après le tracé des barres et des crochets, des clefs, des barres de mesures et des cinq lignes de la portée, il ne manque plus que les notes !

Le rôle du module d'impression est alors de transformer les notes (dans le sens événements sonores) en notes (dans le sens éléments graphiques représentant une note musicale).

 

Figure 7.26

 

En effet, comme cela apparaît dans l'exemple ci-dessus (figure 7.26), une même note peut être décomposée en plusieurs parties : on dénombre ici 5 événements, un événement silencieux (le demi-soupir) et quatre sons, le premier son est représenté par un seul signe (une croche), le second par trois signes (noire, blanche et croche), et les deux derniers par deux signes chacun.

Les signes représentant un même son sont reliés entre eux par des traits de liaison (des courbes situées au dessus ou en dessous des signes).

 

L'altération est placée devant le premier signe de l’événement et n'est répétée que si l'événement franchit une barre de mesure.

De façon à éviter toute confusion, nous avons rendu visible toutes les altérations : toutes les notes naturelles sont affublées d'un bécarre. Toutes les notes altérées sont précédées de leur altération même si la même note apparaît précédemment dans la mesure. Ceci évite au lecteur l'effort de mémorisation, pour chaque mesure, des altérations rencontrées. L'inconvénient, en contrepartie est l'augmentation de l'encombrement horizontal des notes.

 

7.3.2.4.      Tension élastique pour la mise en page

 

Les effets de la tension élastique appliquée aux éléments graphiques de la partition sont présentés ci-dessous dans un extrait de la partition d’orchestre (figures 7.28 à 7.30).

Le premier a une tension nulle, les éléments sont donc positionnés horizontalement strictement en fonction de leur position temporelle. Les éléments simultanés (entre les deux portées) sont sur une même verticale[111].

 

Figure 7.28 : Tension 0

 

Figure 7.29 : Tension 30

 

Avec une tension très grande, (la tension 30 peut modifier la place des éléments graphiques de 30 pixels), les éléments sont répartis uniformément dans la mesure : dans la portée supérieure, les quatre éléments sont plus écartés que les sept éléments de la portée inférieure. La portée inférieure affichant deux voix, conserve l’alignement vertical des éléments simultanés des deux voix, mais, il n’y a plus de correspondance verticale entre les deux portées.

 

Figure 7.30 : Tension 10

 

Nous avons adopté une tension de 10 pour l’impression finale de la partition. Cette valeur, semble être un compromis satisfaisant, augmentant la lisibilité, sans perdre totalement la cohérence verticale inter-portées.

 

7.3.2.5.      Position des altérations

 

Les notes d’un accord étant lues de bas en haut, les altérations des notes graves de l’accord pouvant chevaucher des altérations de notes plus hautes sont décalées vers la gauche.

 

Figure 7.31 : La position des altérations.

 

7.4.      Production de partitions à partir de phonogrammes

 

La conversion directe des phonogrammes en partition n’est pas implémentée, car il suffit de produire un fichier MIDI à partir du phonogramme, puis de relire ce fichier dans un éditeur de partition pour obtenir le pentagramme. Nous somme ici dans un contexte différent de celui de la pièce pour orchestre : les phonogrammes ne contiennent pas d’information spécifique telle que les articulations, ou l’instrumentation. Seules l’information sur les hauteurs et les durées des notes sont transmises à l’éditeur de partition.

 

Figure 7.32

 

La page ci-dessus (figure 7.32) est le résultat brut (sans opération manuelle de mise en page) obtenu sous l’éditeur FINALE à la lecture du fichier MIDI produit par un extrait de phonogramme à 60 millisecondes par pixel (image ci-dessous). La page n’est pas complète, elle comporte 16 systèmes (donc 32 portées). Cette page ne représente qu’une petite portion de l’image ci-dessous, on voit globalement les agrégats correspondants aux taches ponctuelles du phonogramme. Chaque système représentant un instrument, il faudrait accorder chaque instrument sur un seizième de demi-ton différent pour produire le résultat équivalent au phonogramme.

 

Figure 7.33

 

Extrait de phonogramme, réduit à l’échelle 1/6. La partie de l’image entre les marques ‘a’ a été traduite en fichier MIDI, puis relue avec l’éditeur FINALE (voir extrait de la partition résultante ci-avant). On peut remarquer que la densité de l’image n’est pas très élevée.

Le résultat (figure 7.34) est très souvent illisible par un instrumentiste humain, la densité est en général beaucoup trop élevée.

 

 

Figure 7.34

 

En ne sélectionnant que quelques canaux, on peut obtenir une partition lisible. Ceci dépend surtout de l’aspect de l’image, de sa densité, et de la vitesse choisie pour son exécution.

 

Figure 7.35

 

Ci-dessus (figure 7.35) un seul canal de la première séquence.

 

Nous avons généré la partition suivante (figure 7.36) à partir du résultat d’analyse par la transformée de Fourier rapide d’un son vocal, la phrase “Parmi des milliers d’étoiles...” prononcée par un enfant. Le phonogramme obtenu a été transformé en fichier MIDI en ne retenant uniquement qu’un canal sur 16.

 

Figure 7.36 : L’éditeur de partition utilisé pour la lecture du fichier MIDI est ENCORE.

 

7.5.      Conversion de partitions en phonogrammes

 

Le passage d’une partition vers un phonogramme n’est pas direct : soit la partition est saisie dans un éditeur de partition, puis convertie en fichier MIDI et enfin intégrée au phonogramme; soit la partition est digitalisée, et le bitmap obtenu est converti en phonogramme. Évidemment, cette dernière solution produira autre chose que ce que l’auteur de la partition avait prévu!

Les résultats de transcriptions de partition en phonogramme ressemblent au bandes perforées des orgues de Barbarie (figure 7.37).

 

Figure 7.37 : Les lignes d’une même voix sont écartées d’un intervalle correspondant à un multiple de 16, 16 pixels représentant un demi-ton.

 

7.6.      Lecture automatique de partitions musicales

 

Un problème connexe à la transformation de partitions en phonogrammes est la lecture automatique de partitions musicales. Nous avons connaissance d’une tentative de reconnaissance automatique de partition (MIDIScan de Musitek)[112] mais les performances (environ 5 minutes par page, 98% de taux de reconnaissance annoncé) sont loin d’atteindre les capacités humaines en la matière. L’approche de COUASNON et RETIF (COUASNON 1995) utilisant une grammaire pour la description de l’écriture musicale dans leur système de reconnaissance de partitions d’orchestre s’avère prometteuse, en effet, les temps de calculs sont de l’ordre de la dizaine de seconde par page, et le système localise automatiquement les endroits où il a pu commettre une erreur de reconnaissance.

Actuellement les manuscrits sont lus et tapés au clavier par des opérateurs de saisie. Les interfaces graphiques pour saisir les partitions à la souris sont plus lentes que la saisie clavier. Il faudrait une reconnaissance incluant la reconnaissance de texte, et ayant un taux de reconnaissance proche de 100% pour que le temps de digitalisation, de reconnaissance et de correction soit inférieur au temps nécessaire à la saisie directe.

 

7.7.     Liberté Verticale

 

Liberté verticale est une pièce pour piano seul, composée automatiquement et imprimée avec le module d’impression de la partie de piano de CHNRNG14.

 

La partition est composée de 38 variations. Pour une exécution de la pièce, l’interprète choisit librement des variations (consécutives ou non) mais l’ordre d’exécution des neuf variations doit être l’ordre original (les numéros des variations allant croissant). La durée totale des 38 variations est comprise entre 17 et 20 minutes : la double croche dure entre 210 et 250 millisecondes, ceci correspondant à un tempo compris entre 60 et 70 pulsations par minute. Ces tempi sont donnés à titre indicatif et sont laissés au choix de l’interprète pour chaque variation.

 

La pièce est basée sur deux concepts : Le mouvement, et la mémoire.

 

7.7.1.         Le mouvement

 

Les déplacements des mains de l’interprète sont simulés dans le programme. Les mains sont mues par des couplages élastiques les reliant à des points fixes, et des impulsions aléatoires viennent tirer les mains de droite et de gauche.

Une structure (nommée mobile) représente la position et la vitesse de chaque main :

 

 

typedef struct mobile

{

      int limiteInferieure, limiteSuperieure;

      int chocs;

     

      double position;

      double vitesse;

 

      double tensionLimites;

      double forceImpulsion;

      double inertie;

} mobile;

 

Les limites inférieures et supérieures représentent les points fixes. Le champ inertie permet de régler la viscosité du milieu.

 

Voici la procédure calculant le mouvement d’un mobile (passage d’un instant de la simulation à l’instant suivant) :

 

 

void elasticiteMobile(mobile *unMobile)

{

      int positionImpulsion =

            rox(unMobile->limiteInferieure,

                  unMobile->limiteSuperieure);

                            

      double acceleration =

       ((unMobile->limiteInferieure - unMobile->position)

        + (unMobile->limiteSuperieure - unMobile->position))

       * unMobile->tensionLimites

       + (positionImpulsion - unMobile->position)

         * unMobile->forceImpulsion;

     

      unMobile->vitesse += acceleration;

      unMobile->vitesse *= unMobile->inertie;

                            

      unMobile->position += unMobile->vitesse;

                                  

      if(unMobile->position > unMobile->limiteSuperieure

      || unMobile->position < unMobile->limiteInferieure)

      {

            ++unMobile->chocs;

      }

}

 

 

La fonction rox  est un générateur aléatoire délivrant une valeur entière comprise entre les deux paramètres. la variable positionImpulsion ainsi calculée donnera l’impulsion tirant la main d’un coté ou de l’autre.

L’accélération est donnée par la force élastique appliquée sur la main par les points d’attache avec le coefficient tensionLimites plus la force d’impulsion (distance entre la position actuelle de la main et la position de l’impulsion) multipliée par le coefficient forceImpulsion.

Ensuite, la vitesse est modifiée en fonction de l’accélération et de l’inertie (ou viscosité), et enfin la position est modifiée d’après la vitesse.

Le champ chocs est incrémenté à chaque fois que le mobile dépasse les limites fixées.

 

Des ruptures des mouvements des mains sont forcées à chaque variation (les points d’attache sont déplacés), et peuvent survenir au cours d’une variation. Les élastiques sont plus ou moins tendus (modification du champ tensionLimites), et le milieu dans lequel les mains évoluent est plus ou moins visqueux (modification du champ inertie). La viscosité change à chaque variation.

Il n’y a aucune corrélation entre la main gauche et la main droite, au contraire, une indépendance totale : même les viscosités des milieux de la main droite et de la main gauche sont différentes, les espaces ne sont pas les mêmes. Nous ne simulons pas la matérialité des mains en empêchant certains croisements, nous considérons tous les croisement possibles. Les limites haute et basse de la main gauche sont choisies plus graves respectivement que celles de la main droite, mais les ambitus se chevauchent (la limite basse de la main droite est plus basse que la limite haute de la main gauche).

Les déplacements horizontaux des mains donnent la hauteur globale des notes ou des accords. Les déplacements verticaux donnent les rythmes (approximatifs, car l’interprète est libre de les modifier). La structure mobile est unidimensionnelle, ainsi les mouvements verticaux et horizontaux de chaque main sont représentés par une structure mobile propre. Nous obtenons alors une indépendance totale entre les paramètres gérant les mouvements verticaux et ceux gérant les mouvements horizontaux.

 

Les mouvements des mains sont provoqués par des impulsions extérieures plus ou moins fortes (la force est réglable par le champ forceImpulsion des structures mobile, et la distance entre la position de l’impulsion tirée aléatoirement entre les limites et la main intervient dans cette force).

L’ambitus est donné principalement par la position d’attache des couplages élastiques (les limites) et la force des impulsions. Au cours d’une variation, les paramètres des mouvements : la tension des couplages élastiques, les points d’attache, la force des impulsions et la viscosité peuvent changer. Nous réglons les variations de ces paramètres par des tirages aléatoires et la comparaison des résultats avec un seuil (comme dans l’algorithme de génération mélodique Irlandais décrit ci-après). Si le seuil est dépassé, le paramètre est réaffecté avec une nouvelle valeur donnée par un tirage aléatoire entre deux bornes ou par une imbrication d’appels de la fonction aléatoire tels ceux décrits au paragraphe Arbres d’appels de fonction pseudo-aléatoire.

 

7.7.2.         La mémoire

 

Le second concept de base de la génération de la pièce est celui de la mémoire.

Les événements récents ont beaucoup de chance d’être rappelés au souvenir, les événements anciens sont rappelés moins souvent. À chaque variation, de nouveaux événements sont créés, la création d’événements risque plus de faire oublier les souvenirs récents que les anciens, mais fait vieillir les souvenirs provenant des variations précédentes. Nous avons décrit un mécanisme similaire dans le module Pouzzolane (cf. Le module Pouzzolane).

 

Les événements créés et mémorisés sont les modes et les positions des doigts des mains.

 

7.7.3.         Les modes et les positions de doigts

 

Les modes ont une étendue (champ module de la structure mode) variant de 7 à 14 demi-tons, et sont répétés pour couvrir tout l’ambitus.

 

 

typedef struct mode

{

      int taille; /* nombre de degrés */

      int module; /* nombre de demi-tons */

      char *degres;

} mode;

 

 

Ils sont constitués chacun d’une succession de demi-tons, de tons et de tons et demis. Le champ degres pointe vers une table donnant la distance de chaque degré à la tonique en demi-tons (la différence entre la valeur d’un degré et le précédent est donc 1, 2 ou 3, et la valeur du premier degré est toujours 0). Le champ taille donne le nombre de degrés du mode, et le champ module donne la distance en demi-tons entre deux toniques successives (habituellement 12, mais variant ici entre 7 et 14).

 

 

typedef struct doigts

{

#define NB_DOIGTS 5

      char taille;

      char position[NB_DOIGTS];

} doigts;

 

 

 Les positions des doigts sont notées en intervalle de degrés et sont applicables sur tous les modes.

La structure doigts possède un champ taille donnant le nombre de notes de l’accord à former (équivalent dans notre simulation au nombre de doigts à poser, au maximum 5 et au minimum 1), et une table position, donnant pour chaque doigt le nombre de degrés le séparant du premier doigt.

Pour calculer les notes à jouer à un instant donné, nous prenons en compte la position de la main (dans la structure mobile), une structure mode, et une structure doigts de la façon suivante :

 

Les positions successives de la main sont précalculées et rangées dans une table : positionsMainDroite, cette table est adressée en fonction du numéro de la variation courante (variation) de la durée des variations (DureeVariation) et de l’instant courant (temps).

 

 

hauteurBase =

      *(positionsMainDroite

            + (variation * DureeVariation) + temps);

 

 

La hauteur de base (hauteurBase) ainsi obtenue est en demi-tons et doit correspondre à la position centrale de la main, il est nécessaire de la baisser du nombre de demi-tons correspondant à l’intervalle entre le premier et le dernier doigt de l’accord, le premier doigt étant posé arbitrairement sur la tonique (la valeur exacte de la correction n’est pas cruciale).

 

 

hauteurBase -= unMode->degres[

      desDoigts->position[desDoigts->taille - 1]

            % unMode->taille];

 

 

La hauteur de base étant chromatique, nous la transformons en numéro d’octave (ou numéro de répétition du mode) et numéro de degré dans le mode. Il n’existe pas forcément de note dans le mode correspondant à cette hauteur chromatique, nous prenons alors la première note supérieure dans ce cas.

 

 

octave = hauteurBase / unMode->module;

intervalle = hauteurBase % unMode->module;

degre = 0;

while(degre < unMode->taille

&& unMode->degres[degre] < intervalle)

{

      degre++;

}

 

 

Pour chaque doigt actif dans la position, nous calculons ensuite le degré du doigt dans le mode (degreDoigt), en ajoutant au degré du premier doigt l’intervalle en degrés contenu dans la position. Puis nous corrigeons l’octave du doigt en ajoutant à l’octave de base le nombre d’octaves correspondant à la position du doigt (un accord peut dépasser la taille du mode). On retranche ces octaves supplémentaires par l’opération modulo sur le degré du doigt.

La hauteur chromatique finale est obtenue par la dernière formule, multipliant le nombre de demi-tons par octave du mode par le numéro d’octave et en ajoutant l’intervalle en demi-tons donné par le mode pour le degré du doigt.

 

 

for(doigt = 0; doigt < NB_DOIGTS; doigt ++)

{

      int degreDoigt, octaveDoigt;

 

      ...

                                              

      if(doigt < desDoigts->taille)

      {

            degreDoigt = degre +

                  (desDoigts->position[doigt]);

            octaveDoigt = octave

                  + degreDoigt / unMode->taille;

            degreDoigt %= unMode->taille;

                                                    

            hauteurChromatique =

                  unMode->module * octaveDoigt

                  + unMode->degres[degreDoigt];

            ...

      }

      ...

}

 

 

En tout, cent positions de doigts sont mémorisées simultanément et cinquante sont créées à chaque variation. Des positions identiques peuvent être mémorisées plusieurs fois. Pour les modes, cinquante modes sont mémorisés et vingt modes sont créés à chaque variation.

 

Voici un système de la première variation :

 

Figure 7.38 : En réduction à 40% environ

 

Figure 7.39 : Le détail de la première mesure du système.

 

Pour la notation, les mains gauche et droite sont distinguées par les formes des notes : des formes arrondies pour la main gauche et des losanges pour la main droite.

Les altérations sont notées uniquement avec des dièses, devant chaque note altérée. Sans tenir compte des notes altérées ou non dans la mesure. Il n’y a pas de bécarre, toutes les notes naturelles sont notées sans altération.

Quand une note naturelle et la même note dièse apparaissent simultanément dans un accord, elles sont notées avec le dièse devant, et la note naturelle juste après.

Les durées approximatives sont notées proportionnellement aux espaces horizontaux. L’interprète est libre de donner les intensités, les nuances, la dynamique et les articulations. Les accords peuvent être arpégés ou plaqués, détachés ou mélangés par l’action de la pédale.

 

7.8.     Algorithme de génération mélodique

 

Nous présentons ici un algorithme de génération de mélodies paramétrable, que nous avons utilisé pour produire d'une part des ritournelles dont la structure est inspirée des airs de danse Irlandais (les reels et les hornpipes), et d'autre part la partition de contrebasse d'une pièce intitulée Méduse, pour contrebasse et Phonogramme.

La mise en page et l’impression des mélodies générées sont réalisées par notre module d’impression.

 

7.8.1.         Irlandais, pour violon

 

Les reels Irlandais ont une structure très régulière, comme ce sont des airs de danse, les temps forts doivent toujours tomber de la même façon sous les pas, la durée des morceaux est constante (deux parties de huit mesures répétées chacune deux fois). Quelques morceaux peuvent être constitués de plus de deux séquences, mais elles sont toujours répétées. Comme le morceau est joué plusieurs fois (pour toute la durée de la danse), la répétition de chaque séquence contribue à briser la monotonie et introduire un intérêt à plus long terme.

 

Figure 7.40 : Extrait d'un recueil de 1001 airs de danse irlandais. ‘1001 Gems, The Dance Music of Irland’ (O’NEILL). C’est à partir de l’analyse de nombreux airs de ce recueil que nous avons conçu principe de ce générateur mélodique.

 

7.8.1.1.      Reels et Hornpipes, structure rythmique, harmonique et mélodique

 

Dans les reels, la mesure, à quatre temps, est binaire comme pour les hornpipes, mais ces derniers sont plus variables du point de vue rythmique, et la plupart sont écrits à deux temps. La presque totalité des notes sont des croches pour les reels et des doubles croches pour les hornpipes. Dans les hornpipes à quatre temps, le rythme croche pointée - double apparaît souvent, il apparaît de temps à autres dans les reels, associé aux triolets. (Les rythmes croche pointée - double peuvent être en fait une écriture simplifiée du triolet noire - croche).

 

Les mélodies donnent à elles seules le rythme, l'harmonie et l'air. Un seul instrumentiste, violoniste ou flûtiste, peut faire danser toute la population du village. Le tempo, très rapide, permet d'unir les groupes de quatre notes successives, qui forment ainsi un accord, pouvant contenir des notes de passage donnant la mélodie. Les groupes sont joués en accentuant la note initiale.

Les hornpipes (sortes de cornemuses) donnent un son soutenu et continu, les notes répétées de la mélodie sont articulées par des "coups de doigt" simulant une attaque. Les mordants et fioritures renforcent le rythme.

La structure harmonique est en général assez simple, et n'a pas focalisé notre attention.

Ce qui nous a intéressé, c'est la structure des répétitions des fragments mélodiques : Souvent, la première moitié de la première partie est similaire à la première moitié de la seconde partie, formant un plan ABAC (chaque lettre représentant quatre mesures). Mais en décomposant à nouveau, la partie AB peut se réécrire abac (chaque lettre représentant maintenant deux mesures) ou, à une échelle encore plus petite (une mesure en quatre temps, ou même un temps en quatre notes). Mais ces plans ne sont pas systématiquement utilisés, ou les copies ne sont que partielles. D’autres plans peuvent apparaître, tel ABCB. C'est comme si la belle décomposition arborescente binaire (fractale) que l'on peut imaginer depuis les seize mesures jusqu'aux notes groupées par quatre était taillée, tronquée, déformée, mais tout de même sous-jacente.

Notre algorithme de génération de mélodie applique des plans de recopie similaires (détaillés dans le paragraphe plans de copie), à des échelles différentes dans le morceau, et dans un ordre indépendant de l'échelle à laquelle il s’applique. Le plan peut être appliqué sur une mesure avant d'être appliqué à l'ensemble du morceau, mais l'inverse peut également se produire, brisant la régularité globale.

 

7.8.1.2.      Base modale

 

Une description des modes majeur, mineur harmonique, mineur diatonique ascendant et descendant est construite sous la forme d’une table constante (figure 7.41). On accède à la table en fournissant un numéro de mode (une convention a été prise : majeur = 0, mineur harmonique = 1, ...) et un numéro de degré de 0 à 6 pour les degrés de I à VII, la table délivre alors le nombre de demi-tons séparant ce degré de la tonique.

 

 

int modes[4][7] = {

/*      I II III IV V VI VII  */

      { 0, 2, 4, 5, 7, 9, 11 }, /* Majeur */

      { 0, 2, 3, 5, 7, 8, 11 }, /* Mineur harmonique */

      { 0, 2, 3, 5, 7, 9, 11 }, /* Diatonique ascendant */

      { 0, 2, 3, 5, 7, 8, 10 }, /* Diatonique descendant */

      };

Figure 7.41 : La table des modes

 

La mélodie est initialement générée dans une base modale, chaque note étant représentée par un numéro de degré pris non seulement à l’intérieur d’une octave, mais sur toute l’étendue (en ajoutant 7 au numéro de la note, on reste sur le même degré, mais une octave plus haut).

Dans les générateurs précédents, nous notions un couple de valeurs pour chaque note : (degré Œ [0 - 6], octave), mais ceci s’avère compliqué à gérer. Avec la base modale couvrant toute l’étendue, nous retrouvons :

 

     

      note = octave * 7 + degré

 

 

   ou :

 

     

      degré = note % 7        (modulo)

      octave = note // 7      (division entière)

 

 

Cette notation simplifie l’écriture, puisque les intervalles diatoniques sont maintenant gérés par les simples opérations d’addition et de soustraction.

 

La conversion d’une note (depuis la base modale) en hauteur (en base chromatique, ou numéro de demi-ton) est donnée par la formule :

 

 

      hauteur = tonique

                  + 12 * (note // 7)

                  + modes [ mode ] [ note % 7 ]

 

 

7.8.1.3.      Ligne mélodique

 

La ligne mélodique monte, reste constante, ou descend ; elle reste comprise entre deux bornes extrêmes, déterminées suivant la capacité de l’instrument (l’ambitus).

En prenant une suite de valeurs aléatoires à l’intérieur de l’ambitus, nous obtenons une ligne mélodique décousue, très rapidement lassante (perçue comme étant finalement toujours identique, puisque la relation d’une note à une autre est identique, quelque soit le couple de notes choisi).

 

Figure 7.42 : Perception d’une trame uniforme :

 

De loin (à long terme), la trame parait uniforme, de près, chaque portion est unique.

De plus, les intervalles mélodiques sont quelconques, ce qui maximise la difficulté d’exécution. Pour la majorité des instruments, passer d’un extrême à l’autre est plus difficile que de jouer des notes conjointes.

 

Pour ces raisons, nous avons construit la ligne mélodique en nous basant sur les intervalles mélodiques, de façon à pouvoir contrôler la contiguïté de ces intervalles.

Au lieu de choisir les intervalles montant ou descendant au hasard, nous souhaitons pouvoir donner une dynamique intéressante à la ligne mélodique. En effet, si les intervalles sont pris au hasard, entre (-x, et +x), et si le générateur pseudo-aléatoire n’est pas strictement régulier, la ligne mélodique peut “déraper” systématiquement vers le haut ou vers le bas, donnant globalement une sorte de dent de scie.

 

Pour éviter ce problème, nous avons développé l’algorithme suivant :

 

 

Initialisation :

note ¨ aléatoire (mini, maxi)

 

Boucle :

point ¨ aléatoire (mini, maxi)

si point > note

      note ¨ note + aléatoire (0, intervalle maxi)

sinon

      note ¨ note - aléatoire (0, intervalle maxi)

 

 

La mélodie monte si le point aléatoire choisi est supérieur à la dernière note, et elle descend si le point est inférieur. Plus la mélodie est aiguë, moins elle a de chance de monter à nouveau, et si elle est au maximum, elle ne peut que redescendre (ou rester constante).

En fait, cette base très simple est efficace, mais nous l’avons augmentée de règles permettant de pondérer l’occurrence des notes répétées, et des différents intervalles (par exemple en favorisant les intervalles conjoints).

 

7.8.1.4.      Règles de pondération des tirages aléatoires

 

La pondération peut être réalisée simplement en imbriquant les appels à une routine délivrant équitablement des valeurs aléatoires dans un intervalle donné :

 

 

répartition régulière

x = aléatoire(mini, maxi)

 

 

La fonction pseudo-aléatoire utilisée est sensée fournir les valeurs entières entre mini et maxi (bornes incluses) de façon équiprobable.

C'est-à-dire la probabilité d’obtenir la i-ème valeur est :

 

      Pn(i) =

 

i étant compris en 1 et n, et avec n = maxi - mini + 1.

 

 

tendance vers le bas

x = aléatoire(mini, aléatoire(mini, maxi))

 

 

La probabilité P’n(i) d’obtenir la i-ème valeur de l’intervalle [mini, maxi] est maintenant de :

 

P’n(i) =

 

 

Pour le premier tirage, la probabilité d’obtenir la i-ème valeur est de quelque soit i. Ceci est représenté en haut de la figure 7.43 :

 

Figure 7.43

 

Puis, le deuxième tirage est effectué avec une nouvelle borne, déterminée par le premier tirage. Par exemple, nous avons une chance sur n d’obtenir la troisième valeur (i = 3) au premier tirage, le deuxième tirage donnera alors équiprobablement une des 3 valeurs possibles, venant ajouter *chances d’obtenir, la première, la seconde et la troisième valeur.

Dans la partie inférieure  du schéma, les lignes verticales montrent la distribution des chances dans chaque cas, et les lignes obliques représentent l’addition des chances.

Ceci permet de construire la formule de P’n(i) donnée ci-avant.

La somme des probabilités  doit être égale à un :

 

 =

             + + + ... +

             + + ... +

                   ...

             + ) = 1

 

Dans cette disposition, on voit clairement que la somme des termes de chaque diagonale est 1.

 

Pour obtenir une tendance vers les valeurs supérieures, il suffit d’inverser les arguments dans la formule précédente :

 

 

tendance vers le haut.

x = aléatoire(aléatoire(mini, maxi),maxi)

 

Pour accentuer encore la tendance, nous pouvons imbriquer les appels plusieur fois :

 

 

tendance vers le bas accentuée.

x = aléatoire(mini,

            aléatoire(mini,

                  aléatoire(mini, maxi)))

 

  

La probabilité P’’n(i) d’obtenir la i-ème valeur entre mini et maxi devient :

 

 

 

Si de plus, la fonction aléatoire accepte les bornes dans n’importe quel ordre, une répartition accentuée sur le centre est donnée par :

 

 

x = aléatoire(aléatoire(mini, maxi),

            aléatoire(mini, maxi))

 

 

7.8.1.4.1.               Arbres d’appels de fonction pseudo-aléatoire

 

La complexité du calcul de la probabilité augmentant rapidement en fonction des niveaux d’imbrication des appels à la fonction pseudo-aléatoire, nous avons implémenté une interface graphique permettant de construire des arbres binaires, et utilisé ces arbres binaires en tant qu’arbre d’appel de la fonction aléatoire.

Chaque nœud de l’arbre binaire représente un appel à la fonction pseudo-aléatoire de répartition équiprobable. La première image (figure 7.44), ne contenant qu’un nœud, représente un seul appel et représente une répartition équiprobable :

 

Figure 7.44 : aléatoire(0, n - 1)

 

Pour construire expérimentalement la courbe représentant la répartition des probabilités de tirage des valeurs, nous effectuons un nombre important de tirages (1000 fois le nombre de valeurs possibles) en respectant l’arbre d’appel. Nous construisons un histogramme donnant, pour chaque valeur (en abscisse) le nombre d’occurrences obtenu (en ordonnée).

 

Figure 7.45 : Répartition de aléatoire(0, 63), histogramme pour 1000 tirages aléatoires par valeur possible (64000 tirages). Le nombre d’occurrence de chaque valeur oscille autour de 1000. Les histogrammes sont présentés dans une fenêtre de 200 pixels, quelle que soit la variation de la courbe. Ainsi, d’un histogramme à l’autre l’échelle n’est pas la même. Dans l’exemple ci-dessus, les variations sont amplifiées : la courbe est en fait globalement rectiligne et horizontale.

 

La fonction pseudo-aléatoire utilisée est basée sur l’itération de l’équation d’une droite modulo 232. La semence x0 est une valeur arbitraire, puis pour délivrer une nouvelle valeur, on calcule xn+1 = (a.xn + b) modulo 232. Les constantes a et b sont choisies parmi les nombres premiers[113].

 

En ajoutant un nœud à droite (figure 7.46), on crée un appel imbriqué à la fonction aléatoire. Ceci a pour conséquence d’augmenter le nombre d’occurrence des valeurs faibles (proches de zéro) (figure 7.47).

 

Figure 7.46 : aléatoire(0, aléatoire(0, n - 1))

 

Figure 7.47 : Répartition de aléatoire(0, aléatoire(0, n - 1)).

 

Exemple d’une structure d’imbrication plus complexe (figure 7.48 et 7.49) :

 

Figure 7.48

 

Figure 7.49 : Histogramme correspondant à l’arbre de la figure 7.48.

 

Arborescence accentuant les valeurs faibles (figures 7.50 et 7.51) :

 

Figure 7.50 : aléatoire(0, aléatoire(0, aléatoire(0, n - 1)))

 

Figure 7.51 Répartition de aléatoire(0, aléatoire(0, aléatoire(0, n - 1))).

 

La courbe de la figure 7.51 a la même allure que pour aléatoire(0, aléatoire(0, n - 1)) (figure 7.47), mais elle est accentuée. La probabilité d’obtenir 0 passe de environ 1/16 à 1/5.

 

Arborescence augmentant les valeurs centrales (figures 7.52 et 7.53) :

 

Figure 7.52 : aléatoire(aléatoire(0, n - 1), aléatoire(0, n - 1))

 

Figure 7.53 : Répartition de aléatoire(aléatoire(0, n - 1), aléatoire(0, n - 1))

 

Tous les arbres complets tels que celui ci-dessous (figure 7.54) donnent un histogramme accentuant les valeurs centrales.

 

Figure 7.54

 

De la profondeur de l’arbre dépend la largeur de la courbe obtenue. Voici (figure 7.55) l’histogramme correspondant à cet arbre complet de profondeur 5 :

 

Figure 7.55

 

Arborescence d’appels permettant de diminuer fortement la probabilité d’obtenir les valeurs extrêmes (figures 7.56 et 7.57) :

 

Figure 7.56

 

Figure 7.57

 

En coupant la branche gauche de l’arbre précédent, seules les valeurs proches du maximum voient leur probabilité se réduire (figures 7.58 et 7.59).

 

Figure 7.58

 

Figure 7.59

 

Arborescence donnant une progression linéaire des probabilités (figures 7.60 et 7.61) :

 

Figure 7.60

 

Figure 7.61

 

L’inversion droite-gauche de l’arbre donne une progression linéaire décroissante. En général, l’inversion droite-gauche de toute arborescence donnera l’histogramme inversé droite-gauche également.

 

Les courbes d’accentuation des valeurs faibles ou fortes données au début de ce paragraphe sont concaves. On peut former des histogrammes convexes (figure 7.63) avec une arborescence telle que celle de la figure 7.62 :

 

Figure 7.62

 

Figure 7.63

 

7.8.1.4.2.               Interface de construction des arbres binaires

 

Pour l’interface de construction des arbres binaires, nous avons utilisé les mêmes concepts que dans les interfaces des constructions de couplages élastiques et des schémas : exploiter les différents mouvements ou trajets de la souris pour reconnaître les différentes actions à appliquer, et leur localisation pour déterminer les paramètres de ces actions. Ceci permet de simplifier  l’interaction, en évitant l’usage de menus, de boutons ou de modes d’édition.

Pour la construction d’une arborescence binaire, les différentes actions sont :

• Création d’un nœud fils à droite

• Création d’un nœud fils à gauche

• Suppression d’un sous-arbre à droite

• Suppression d’un sous-arbre à gauche.

Toutes ces actions portent sur un nœud existant dans l’arbre.

Initialement, la racine de l’arbre doit exister. La racine, qui doit être conservée, ne peut pas être supprimée avec les actions énumérées ci-dessus.

Pour désigner le nœud sur lequel une action va porter, le plus intuitif est de débuter un mouvement de souris sur la représentation du nœud. La création d’un nœud fils n’est souhaitée que dans le cas ou le nœud père ne possède pas de fils (pour un coté donné). De même (mais à l’inverse), la suppression n’est nécessaire que si le fils existe. Donc la distinction entre les actions de création et suppression peut être déterminée en fonction de la présence ou de l’absence du sous-arbre. Ensuite, il ne reste qu’à distinguer les actions portant sur le coté droit ou gauche : nous déterminons le coté par la direction du mouvement de la souris.

 

7.8.1.5.      Paramétrage des choix aléatoires

 

Une dizaine de paramètres permettent de régler, d'accorder, le style général, et/ou le nombre d’occurrences de certains effets dans le programme. Par exemple le nombre de chances (sur 1000) d'avoir un silence au lieu d'une note, ou encore, la proportion de croches ou de doubles-croches, etc...

Tout ces paramètres seront détaillés dans l'annexe, à l'endroit où ils apparaissent dans le code.

La forme générale d'exploitation d'un paramètre est celle ci :

 

 

if ( aléatoire(0, 1000) < paramètre )

{

            // action correspondant au paramètre

}

 

 

Si le paramètre est réglé à zéro, l'action ne sera jamais effectuée. S’il est réglé à une valeur supérieure à 1000, l'action sera toujours effectuée, et enfin, s’il est réglé à la valeur n entre 0 et 1000, l'action sera effectuée dans n cas sur 1000 en moyenne.

 

7.8.1.6.      Plans de copies

 

Après la génération de la mélodie, nous la modifions par l'application des plans de copies. 

Nous proposons deux formes de plans de copies, que nous appelons plans locaux et plans généraux.

 

La boucle appliquant les plans de copies contient un test qui détermine à chaque tour si le plan doit être appliqué ou non : un paramètre détermine le nombre de chances d'appliquer le plan.

 

7.8.1.6.1.               Les plans locaux : recopie d'une note

 

Une position et une longueur (en nombre de doubles-croches) sont déterminés. La longueur est au maximum de 32 (deux mesures). La table de la mélodie est scrutée à partir de cette position, pour trouver la première note. Puis cette note est recopiée une fois sur deux dans la suite de la mélodie sur toute la longueur déterminée au départ. Seule la hauteur de la note est utilisée, les durées ne sont pas modifiées. Ceci génére des passages similaires au début de la seconde partie du reel n°598 de la figure 7.40 (mesures 9 et 11, une note sur deux est un la), ou encore à la seconde mesure du reel n°595.

 

7.8.1.6.2.               Les plans généraux : forme ABAC

 

Si le plan doit être appliqué, une longueur est déterminée : cette longueur est une puissance de deux supérieure à deux, représentant un nombre de doubles-croches (inférieur ou égal au quart de  la durée totale). puis toutes les positions dans le morceau multiples du quadruple de cette longueur sont traitées : le traitement consiste à recopier la portion initiale dans la troisième portion. Les durées et les hauteurs sont copiées.

 

Figure 7.64

 

Dans l'exemple ci-dessus (figure 7.64), généré par le programme, nous voyons l'effet d'un plan de longueur 4 (le plus petit) : dans toutes les mesures, chaque troisième temps est similaire au premier.

Cette forme ABAC apparait dans le reel n°596 (sur les quatre premières mesure de chaque partie), ainsi que dans le reel n°597 (figure 7.40).

 

7.8.2.         Méduse, pour Contrebasse et Phonogrammes

 

La seule des trois Gorgones dont le regard était mortel...

Persée lui trancha la tête, et de son sang  naquit Pégase...

 

Méduse s'articule sur deux pôles d'interprétation opposés, complémentaires et indissociables : lecture et écriture. Ces deux pôles sont dédoublés, réfractés par l'interface séparant l'homme de la machine.

La partie de contrebasse, interprétée, lue par un instrumentiste humain est générée entièrement automatiquement, depuis la construction musicale jusqu'à l'écriture.

Les pages de Phonogramme sont écrites à la main, construites intuitivement, tracées, dessinées et deviennent la tablature, la partition que la machine devra lire et jouer.

 

Le module de génération du programme Méduse est identique à celui du programme précédent, à quelques variations près :

• La longueur des séquences a été augmentée et chaque page (chaque variation) comporte maintenant 16 mesures.

• L'unité la plus petite est restée la double-croche, mais les structures rythmiques s'articulent sur la durée d'une blanche au lieu de la durée d'une noire, ceci introduisant la possibilité de syncopes (dans un couple de temps), et doublant la taille minimale des plans généraux de copies.

• Des règles ont été ajoutées pour faciliter l'exécution à la contrebasse : les écarts supérieurs à la quarte sont traités de façon à être soit séparés par un silence, soit partir d'une corde à vide, soit arriver sur une corde à vide.

• La corde à vide est forcée, en trouvant la corde la plus proche de la note, sans tenir compte de la tonalité.

 

Figure 7.65 : Une page de Méduse

 

Les autres modifications du programme ont porté sur la mise en page, feuille verticale au lieu du format à l'italienne, la sélection d'une autre structure d'instrument (pour déterminer l'ambitus), mais c'est surtout le réglage des paramètres qui permet de choisir un style différent : la contiguïté est augmentée, ainsi que les modulations.

 

La densité de la Méduse est proche de celle de l'eau de mer, ses cheveux sont des serpents, son système nerveux ne comporte qu'un seul et unique neurone.

 

 

 

Notre générateur de partitions, initialement conçu pour la génération et l’impression d’une unique pièce pour orchestre et piano concertant a remplit son rôle : CHACONES fut jouée en concert[114]. à BERNE (Suisse) en mai 1995, interprétée au piano par Christoph KELLER, et par l’orchestre de BERNE dirigé par Mario VENZAGO. La qualité du matériel produit permit à l’orchestre la mise au point de l’œuvre en un temps limité.

Enfin, nous avons réutilisé le module d’impression pour réaliser d’autres pièces.

 


Conclusion

 

Nous avons présenté notre Atelier Incrémentiel pour la Musique Expérimentale. Cet atelier, constitué de programmes, de squelettes d’applications, de modules et de bibliothèques de fonctions est un terrain propice à sa propre évolution, et à son développement. Cette qualité est nécessaire dans le domaine, car la musique expérimentale n’a pas de règles établies, au contraire, chaque pièce, chaque œuvre est basée sur des concepts différents et nouveaux[115]. Il est donc difficile de fixer, de mettre en boîte, de spécifier des concepts génériques à l’activité compositionnelle tout en gardant une grande puissance d’expression. Les modules de composition algorithmique sont donc fait sur mesure, et programmés indépendamment pour chaque composition. Ils permettent d’effectuer des expériences et d’obtenir rapidement des variations de ces expériences. Dans ce cas, ce sont les bibliothèques, les modules de base, ainsi que les squelettes qui se révèlent utiles à la construction de nouvelles applications spécifiques d’une pièce. A l’opposé, Phonogramme est un exemple d’application de l’atelier qui est utilisable dans des contextes très variés, par différents compositeurs, et pour différentes pièces. La raison de l’ouverture de cette application est la neutralité de la représentation utilisée. Les représentations graphiques de la musique et du son que nous avons développées forment non seulement le cœur des interfaces homme-machine, mais deviennent la matière cruciale, le support direct de l’information manipulée.

• Les phonogrammes sont à la fois une représentation du son et un système d’encodage des images.

• Les réseaux de couplages élastiques sont construits graphiquement, sont déterminés par les coordonnées des nœuds et leurs liens (ce sont des graphes), et correspondent à des classes de sons, ou à des classes de transformations de sons (lorsqu’ils sont utilisés en tant que filtres).

• Enfin, les trajectoires élastiques sont elles aussi un exemple où l’aspect graphique est intimement lié à l’aspect sonore.

Ces représentations étant proches de la physique du son par la simplicité de la synthèse additive des phonogrammes, par la simulation physique des vibrations et résonances dans les réseaux, et par la formation brute du signal au moyen des trajectoires, elles sont neutres par rapport au niveau conceptuel de la structuration des compositions musicales. Nous voulons toutefois permettre de construire ces structures, sans en guider l’organisation ; c’est ce que nous proposons par le biais des interfaces graphiques et des outils spécialisés tels que le pinceau à timbres.

 

8.1.     Les limitations actuelles et l’évolution de l’atelier

 

L’atelier est constamment en évolution, les nouvelles possibilités développées pour une utilisation particulière peuvent être utiles dans d’autres cas, mais elles appellent également à la création d’outils complémentaires. L’utilisation de l’atelier par d’autres compositeurs nous a souvent conduit vers la réalisation de nouveaux outils, ou au perfectionnement de fonctions existantes.

 

8.1.1.         Les limitations actuelles de AIME dans le domaine graphique

 

Par exemple, il s’est avéré très difficile de construire une simple droite traversant en diagonale toute la surface d’un phonogramme. La numérisation du dessin donnant un résultat peu régulier, et le dessin d’une droite avec la souris et un pinceau carré s’avérant impossible, nous avons essayé de créer la droite dans une autre application pour l’importer dans Phonogramme. Le problème fut alors la taille de l’image à importer (4000 X 2000) pixels environ. La mémoire de la machine était insuffisante pour copier la totalité de l’image. Finalement[116], nous avons ajouté la possibilité de tracer des droites directement depuis l’application phonogramme. Le résultat est intéressant, puisque la droite, tracée avec toutes les caractéristiques du pinceau peut, par exemple être accompagnée d’harmoniques, varier en épaisseur, ou respecter une sélection d’échelle microtonale. La fonction de tracé de droite a permis immédiatement d’offrir la possibilité d’un tracé en mode lié pour le pinceau.

La pièce intitulée Triptyque de Giuseppe ENGLERT (ENGLERT 1994) a été construite initialement sur papier, à l’aide d’outils géométriques, règles, compas, équerres... Le tracé des lignes de construction a été numérisé, puis, les images ont été travaillées dans l’application Phonogramme, pour effacer les lignes de construction et emplir les surfaces à l’aide du pinceau à timbres. à cette occasion, nous avons implanté une gomme sélective, c'est-à-dire une fonction permettant l’effacement des segments dont la valeur de gris est comprise dans une fourchette donnée par l’utilisateur, permettant ainsi de supprimer les traits de construction.

 De nouvelles fonctions géométriques pourraient être intégrées à l’application, la construction des lignes de base de la pièce aurait pu être faite directement avec le programme (sans étape de numérisation).

Pour la réalisation de la pièce Triptyque, nous avons développé également les outils permettant de modifier les valeurs de gris d’une portion de l’image. Ceci pour être en mesure de régler simplement la dynamique, l’équilibre des intensités dans la pièce. Il n’y a pas actuellement d’outil équivalent sous la forme d’un pinceau, nous sommes obligés de traiter des zones rectangulaires. L’ajout de ce type de pinceau ne posera pas de problèmes particuliers, et permettra de contrôler  plus simplement l’évolution locale de la dynamique.

 

Un système de marquage des segments de phonogramme permettrait de mémoriser les coups de pinceaux, c'est-à-dire d’être en mesure de reconnaître l’ensemble des segments appartenant à une même forme. De cette façon, une entité ajoutée à l’image pourrait conserver son identité, et être sélectionnée ou manipulée individuellement. Les sons (perçus individuellement) ont actuellement une représentation composite.

La couleur a fait timidement[117] son apparition dans le système de visualisation de mémoire, elle permet de distinguer rapidement des objets d’apparence (de forme) identiques. Les ergonomes du système Macintosh déconseillent de donner à la couleur un rôle important (c'est-à-dire faire porter à la couleur une information qui n’est accessible que de cette manière), de sorte que les applications soient utilisables avec des écrans noir et blanc ou en niveaux de gris. Mais les nouvelles dimensions apportées aux représentations graphiques par la couleur ne peuvent pas être ignorées. En particulier la dimension artistique : Marc BATTIER, qui a utilisé Phonogramme pour réaliser différentes pièces (BATTIER 1993), a coloré les phonogrammes dans une autre application pour compléter son œuvre.

Nous pensons à plusieurs attributions possibles de la couleur dans les phonogrammes. Par exemple, pour visualiser les groupes de segments visés ci-dessus, ou encore pour associer des formes d’ondes différentes aux segments. Actuellement, la forme d’onde est toujours sinusoïdale, la modification de la table d’onde par l’utilisateur est impossible, mais l’implémentation d’un tel système est immédiate. Les différents systèmes d’encodage de la couleur peuvent être utilisés avec des significations distinctes au niveau musical : le système de la table de couleur (Look up table) serait adapté pour l’attribution d’information symbolique. Par exemple pour visualiser un effet associé à une note, visualiser les changements de timbre, ou encore pour distinguer des autres les notes protégées (celles que l’on ne peut pas effacer) etc.... En effet, la modification d’une entrée de la table de couleur a une répercussion immédiate sur l’ensemble de l’image (sans avoir à changer le contenu de la mémoire d’image. Par contre, le système d’encodage permettant la représentation de millions de couleurs (16 millions en 24 bits), semble plus adapté à la représentation d’information de nature physique que symbolique. Nous pensons par exemple à un système de conversion d’images en sons, utilisant des filtres colorés[118] successifs pour extraire différents plans de l’image ; chaque plan de l’image fournissant alors un phonogramme en niveaux de gris que l’on pourrait associer à une forme d’onde particulière.

 

8.1.2.         Limitations temporelles

 

La gestion du temps dans notre système est comptée en millisecondes[119]. Nous n’avions pas eu la nécessité de décomposer le temps en fractions plus fines[120]. Or, dans certains cas, pour obtenir une grande précision de représentation, la vitesse de 1 milliseconde par pixel est trop faible.

De même, dans la gestion des fichiers MIDI, un travail est nécessaire pour que l’on puisse contrôler plus efficacement le paramétrage temporel. Actuellement une unique variable indique si un pixel sera traduit en noire, croche, double croche ou triple croche.

Dans le système d’impression de partition, nous avons volontairement limité la représentation des durées à la double croche, pour forcer la simplicité de lecture des partitions produites. Ceci n’est pas nécessaire, voire limitatif, dans le cas de production de parties solistes. Une représentation intéressante des durées des notes est la notation rationnelle, permettant de compter des durées telles que celles de 3 notes sur 5, jouées dans le temps de 4, et les 2 notes restantes remplacées par 11 notes, le tout sans commettre d’erreur de calcul en additionnant les durées individuelles pour obtenir une durée totale.

 

8.2.     Développements actuels et perspectives

 

Nous développons actuellement un nouveau système de génération s’intégrant dans l’atelier. L’idée de base est l’utilisation de grammaires en tant que générateurs[121]. Pour notre future composition, nous voulons créer un nouvel espace pour établir un champ d’expression, dans lequel nous modèlerons un matériau ayant de nouveaux comportements et propriétés. Nos grammaires seront des éléments mouvants, modifiables, et en permanente évolution. L’exécution d’une grammaire consistant en la génération automatique de phrases acceptables dans cette grammaire à un moment donné. Nos grammaires sont des graphes quelconques, constitués de nœuds typés.

Voici, au travers de l’exemple de la figure 8, les différents types de nœuds utilisés :

.

Figure 8.1 : Un sous ensemble d’une grammaire générée aléatoirement. Le schéma a été obtenu à partir de la fenêtre de visualisation automatique des allocations de mémoire (cf. chapitre Métronome, § Boîte à outils), et les noeuds étiquetés manuellement (après une observation nous donnant les types des structures par la visualisation de leur contenu).

Les Définitions (d1, d2, d3) comportent un pointeur vers leur nom, et un pointeur vers le nœud qu’elles dénomment.  Les Séquences (s1) pointent vers une table de (pointeurs vers les) noeuds devant se succéder (pour s1 : d2,  p1, t1, p1, r1, v1, j1).  Les noeuds Parallèles  (p1) pointent vers une table de nœuds à exécuter simultanément. Les Répétitions  (r1) pointent vers le nœud à exécuter plusieurs fois (la structure contient le nombre maximal et minimal de répétitions). les Disjonctions (j1) pointent vers une table des nœuds à choisir au moment de l’exécution (pour j1 : l’exécution consiste à déterminer si v1 ou d3 ou t2 sera exécuté). Les Terminaux  (t1, t2) , contiennent une valeur (ou un pointeur vers une structure quelconque) et un pointeur vers une fonction à exécuter. Le nœud Vide (v1) représente l’absence d’élément (son exécution consiste à retourner à l’appelant).

 

Pour construire une grammaire, nous décrivons une structure, nommée environnement de création, contenant la répartition souhaitée entre les différents types de nœuds[122], le paramétrage de construction des différents types de nœuds, ainsi que les pointeurs vers les fonctions de création de nœuds terminaux.

Par exemple, la création d’une séquence nécessite de connaître la taille de la séquence, donc, l’environnement de création contient les paramètres pour l’appel de la fonction pseudo-aléatoire devant délivrer la taille d’une séquence. Une structure (borne) décrit les bornes minimales et maximales souhaitées, ainsi que l’arbre d’appel de la fonction pseudo-aléatoire (tels que ceux décrits dans la section Règles de pondération des tirages aléatoires). L’environnement contient une structure borne pour chaque paramètre numérique nécessaire à la construction.

Lorsque des nœuds sont crées, ils doivent être interconnectés. Actuellement, les interconnections sont établies au hasard, entre tous les nœuds d’une liste, et tous les pointeurs de chaque nœud de la liste sont modifiés. Nous envisageons différentes possibilités pour gérer les connections, par étages, par sous-ensembles, etc...

Dans le cas de la figure 8, la répétition r1 pointe vers elle-même (la définition d2 également), lors de l’exécution, leurs définitions devraient être automatiquement changées, pour pointer vers d’autres nœuds, ou encore, lors de la construction (ou de la modification) de la grammaire, de telles définitions impliquant des boucles sans fin et sans génération (c'est-à-dire sans exécution de terminal) devraient être évitées.

 

Pour exécuter une grammaire, à partir d’un nœud, nous construisons un contexte d’exécution, et nous installons ce contexte dans un nouveau processus. Le processus est ensuite lancé par son intégration dans un chaînage de processus activés par une fonction d’exécution.

Les contextes contiennent un pointeur vers un noeud syntaxique, un index utilisé pour les séquences et les répétitions, mémorisant le noeud courant dans la séquence, ou le nombre actuel de répétitions, et enfin un pointeur vers le contexte appelant. Le pointeur vers le contexte appelant est nul pour le contexte de départ.

Les processus sont destinés à la gestion de l’exécution concurrente de plusieurs nœuds. En particulier, de nouveaux processus sont crées lors de l’exécution des noeuds de type Parallèle. Les processus sont détruits lors du retour d’un contexte n’ayant pas de contexte appelant.

 

Figure 8.2 : Le pointeur (en haut à gauche) est le pointeur vers le processus actif, le processus actif est seul (ses pointeurs suivant et précédent pointent vers lui-même), le contexte courant est le contexte 2, appelé par le contexte 1 (la barre diagonale en bas du contexte 1 montre qu’il n’a pas de contexte appelant). Le contexte 2 exécute le nœud terminal désigné par la répétition 1 (qui est le nœud dont on a initialement lancé l’exécution).

 

Les processus contiennent un pointeur vers le processus suivant et précédent, permettant ainsi la constitution d’un double chaînage cyclique. L’exécution est en fait séquentielle, mais à chaque pas d’exécution, le processus suivant est activé. Un pas d’exécution consiste en une sélection suivant le type de nœud pointé par le contexte, et la modification du contexte, ou du processus suivant les cas :

 

• Pour un nœud de type Vide : Retour au contexte appelant :  le processus pointe vers le contexte appelant et le contexte courant est libéré.

 

Retour :

(*processusActif)->contexte = contexte->appelant;

detruireContexte(contexte);

Le retour au contexte appelant.

 

• Pour une Séquence :

              • Si l’index est égal à la taille de la séquence, Retour.

              • Sinon, nous créons un sous-contexte, (nouveau contexte dont l’appelant est le contexte courant), le nœud du sous-contexte étant le nœud désigné par la valeur de l’index[123]. L’index du contexte est incrémenté, et le sous-contexte est activé en le connectant au processus.

 

if(contexte->item >= Sequence(noeud)->taille)

{

      goto Retour;

}

{

      contexteSyntaxique *sousContexte = creerContexte(

            contexte,

            Sequence(noeud)->elements[contexte->item]);

 

      if(sousContexte)

      {

            contexte->item++;

            (*processusActif)->contexte = sousContexte;

      }

      else

      {

            goto Retour;

      }

}

La création d’un sous contexte.

 

• Pour une Répétition : Un tirage aléatoire détermine le nombre de répétitions à effectuer.

              • Si l’index est supérieur à la valeur du tirage, le retour est provoqué, sinon, un sous-contexte est créé pour exécuter le nœud désigné par la répétition.

 

{

      int item = hasard(

            Repetition(noeud)->mini,

            Repetition(noeud)->maxi);

                 

      if(contexte->item > item)

      {

            goto Retour;

      }

      {

            contexteSyntaxique *sousContexte = creerContexte(

                  contexte,

                  Repetition(noeud)->element);

 

            if(sousContexte)

            {

                  contexte->item++;

                  (*processusActif)->contexte = sousContexte;

            }

      }

}

Exécution d’une répétition [124]

 

• Pour les nœuds de type Parallèle, nous créons n-1 nouveaux processus, pointant sur des nouveaux contextes d’exécution de chacun des nœuds d’indice de 1 à n-1 (n étant la taille de la table du nœud parallèle).

Seul le premier nœud de la structure (d’index 0) est exécuté dans le contexte courant. C’est donc au retour de l’exécution du premier nœud que le contexte appelant sera poursuivi.

 

{

      int item;

     

      for(item = 1; item <= Parallele(noeud)->taille; ++item)

      {

            contexteSyntaxique *sousContexte = creerContexte(

                  (contexteSyntaxique *)0,

                  Parallele(noeud)->elements[item]);

            if(sousContexte)

            {

                  lancerProcessus(

                        processusActif,

                        creerProcessus(sousContexte));

            }

      }

      /* l'item 0 est la continuation */

      contexte->noeud = Parallele(noeud)->elements[0];

      contexte->item = 0;

}

Exécution des nœuds de type Parallèle.

 

La question de synchronisation peut être traitée en ce point, par exemple en traitant tous les nœuds dans de nouveaux processus (y compris le premier) et en affectant les contextes appelants de tous les nouveaux contextes. Puis, lors du retour d’exécution d’un sous-contexte, comptabiliser (avec l’index) le nombre de sous-contextes terminés, et n’effectuer le retour que si tous les sous-contextes sont revenus.

 

• Pour les Définitions, le contexte courant est modifié pour pointer vers le nœud désigné par la définition.

 

contexte->noeud = Definition(noeud)->element;

contexte->item = 0;

Exécution d’une Définition

 

• Pour les nœuds Terminaux, une fonction est appelée. Le nœud contient un pointeur vers la fonction à appeler, et un champ pour le paramétrage de cette fonction. Puis le retour est déclenché pour revenir au contexte appelant.

 

      (* (Terminal(noeud)->execution))

            (Terminal(noeud)->terminal);

      goto Retour;

Execution d’un nœud de type Terminal

 

Cette structure de l’environnement d’exécution permet de gérer un nombre quelconque d’exécutions concurrentes, dans différents chaînages de processus auxquels on pourra affecter des priorités différentes.

Des grammaires différentes peuvent être exécutées simultanément.

Les fonctions des nœuds terminaux pourront être des fonctions produisant un flux MIDI, dessinant dans un phonogramme, ou encore modifiant la grammaire qui les contient. Des opérations de base de modification de grammaire peuvent être intégrées en tant que primitives. Par exemple la création de nouveaux nœuds, la copie de nœuds existants, la suppression de nœuds, la modification des liens de nœuds, etc.

Les schémas pourront servir de support à la représentation graphique des grammaires. Les cellules pourront aisément être augmentées de caractéristiques graphiques (couleurs, formes, signes) permettant de distinguer les types de nœud, les flèches et l’emboîtement des cellules sont adaptés pour représenter les liens entre les nœuds. L’emboîtement favorise la construction arborescente, typique de l’architecture des grammaires, alors que les flèches permettent les références à des objets distants ou parents. Les textes des cellules permettant la création de liens invisibles, de mentionner un objet défini ailleurs, ou encore de désigner une primitive. La vocation première des schémas fut la représentation de structures de données, les cellules représentant les structures et les unions, et les flèches représentant les pointeurs. Notre programme Structographe permet ainsi de construire l’équivalent de tout ce qui est définissable par l’instruction typedef du C. Les champs des structures sont représentés par des sous-cellules, nommées, et contenant un type, les types de base sont connus du système et représentés par une cellule portant leur nom, et enfin, les tables sont représentées par des cellules dont le texte est numérique et contenant une sous-cellule définissant un type. La compilation du schéma fournit un texte source définissant les structures en langage C.

 

Figure 8.3 : Un exemple de schéma dans Structographe.

 

/* déclarations */

typedef struct liste liste;

typedef int (* a)[10];

typedef int *bar[20];

/* déclarations non référencées */

typedef union foo foo;

/* définitions */

union foo

{

      a *y;

      liste x;

};

struct liste

{

      void *car;

      liste *cdr;

};

Figure 8.4 : Le code généré à partir du schéma de la figure 8.3 par Structographe.

 

Nous n’avons pas beaucoup utilisé Structographe pour la programmation, nous l’avons surtout utilisé pour l’enseignement, peut-être parce qu’il est plus simple d’écrire directement le code, et qu’il nous manquait une sémantique, la possibilité de décrire des actions sur ces structures directement dans les schémas. La représentation des grammaires nous semble plus intéressante dans le sens où ce sont maintenant des actions, un mode opératoire, qui sera décrit par les schémas.

Le développement du système de visualisation des allocations de mémoire pourrait déboucher sur un système de description graphique des structures et d’actions sur ces structures, plus simple à manipuler que les schémas de Structographe. Nous pensons par exemple à une action directe sur des exemplaires des structures pour indiquer au système comment procéder une étape de traitement (qui peut être associée à un nœud terminal d’une grammaire). Par exemple, la modification d’un pointeur peut être indiquée par le déplacement de l’extrémité d’une flèche. L’annulation d’un pointeur par le dessin d’un trait diagonal dans la structure. Une séquence d’actions étant représentée par une sorte de bande dessinée dont les phylactères seraient le code, et les héros, les structures de données. Mais les bandes dessinées ne remplacent pas la littérature, nous pensons que la programmation dans les langages standards, tels que le langage C, Lisp ou Smalltalk, est toujours efficiente, et peut-être plus directe que la création laborieuse d’un graphique complexe.

Après la littérature et la bande dessinée, viendra peut-être l’heure du cinéma, ou de l’immersion programmatique : “à la sortie de la ville de la programmation conceptuelle, sur la route de la composition musicale, vous entrez dans un paysage reposant et rayonnant, à droite, ces fichiers de sons de percussions ont une apparence ligneuse (travelling dans une allée gazonnée bordée par des sortes de sculptures, dont l’ombre projetée sur le sol indique l’heure) car, observez leur spectre sur l’étiquette en bas (zoom), les harmoniques aiguës diminuent plus rapidement que le fondamental (production du son lorsqu’un des visiteurs frôle la structure). À gauche, ces structures métalliques sont des enregistrements vocaux filtrés par un système de ressorts (retournez la, pour voir la formule de transformation gravée dans l’acier inoxydable). Faites attention à la trappe qui permet de retrouver le son original, et suivez le guide...”

 


Annexe 1 Dimensions physiques des sons

 

Les formules de dimension, permettent de situer les différentes grandeurs physiques dans un espace à trois dimensions : la masse, le temps et l’espace. On pourrait tout aussi bien prendre un autre repère, tel la vitesse, l’espace et la masse.

Cette vision (Figure A1.1) est schématique, et la réalité physique connue actuellement est beaucoup plus complexe.

 

Figure A1.1 : Les formules de dimension

 

Figure A1.2

 

Pression = Force / Surface

Travail = Force . Longueur

Puissance = Travail / Temps

Radiance Énergétique = Puissance  / Surface

 

Les sons sont le résultat de la perception des variations de pression de l'air (ou du milieu ambiant) dans le temps.

Le signal s peut-être représenté par une fonction du temps et de l'espace.

 

s(t, x) = amplitude en fonction du temps et du point de l'espace.

 

Le son enregistré par un micro, pendant une certaine durée, est pris en un seul point de l'espace.

 

s(t) = amplitude en fonction du temps.

 

Les sons purs sont constitués d'une oscillation sinusoïdale.

 

s(t) = A.sin( 2p f.t + F)

 

t représente le temps en secondes.

A représente l'amplitude de crête.

f la fréquence = 1/T.

T la période (la durée d'une oscillation).

F La phase (angle à l'instant t = 0).

le facteur 2p représente simplement un changement d'échelle pour qu'une seconde de temps corresponde à un cycle quand la période est de 1.

2pf est la fréquence angulaire.

s(t) est en correspondance directe avec  la position de la membrane vibrante du micro (ou du haut parleur), ou des molécules d'air. Quand cette valeur est positive, les molécules sont comprimées et se déplacent dans une direction donnée, quand la valeur est négative, les molécules sont espacées, et se déplacent dans le sens inverse.

 

L'amplitude correspond à l'intensité du son. Si l'amplitude était nulle, il n'y aurait plus aucune vibration, et donc un silence. Mais l'amplitude ne fournit  pas toujours une bonne mesure de l'intensité sonore : pour des signaux complexes, la valeur maximale de l'amplitude peut être très grande à un instant mais être beaucoup plus faible ailleurs. La valeur efficace est calculée en effectuant la racine carrée de la somme des carrés des amplitudes instantanées.

 

Valeur efficace =

 

 

Figure A1.3 : La pression acoustique est égale à la force par unité de surface.

 

   p = F / S.

 

L'énergie acoustique (correspondant à un travail) est une force exercée sur une certaine distance.

   E = Fd

 

La puissance acoustique est la quantité d'énergie par unité de temps.

   P = E/t

 

L'intensité acoustique (correspondant à la radiance énergétique en optique) est une puissance par unité de surface.

I = P / S

 

L'intensité acoustique est donc liée à l'amplitude des déplacements des molécules.

Les mesures d'intensité sonore sont exprimées en Décibel qui est le log d'un rapport de deux puissances acoustiques :

Db = 10 log (P1 / P0)

ou de deux énergies acoustiques :

Db = 10 log (E1 / E0)

ou de deux pressions acoustiques :

Db = 20 log (p1 / p0)

La puissance étant proportionnelle au carré de la pression.

Pour p0 on prend la plus basse pression acoustique perceptible (par un jeune humain (sic) (BINGEN 1959) dans une gamme de fréquences moyennes).

 

La fréquence d'un tel signal (sinusoïdal et périodique) correspond à la hauteur tonale du son.

Les fréquences plus élevées donnent des sons aigus.

Les basses fréquences des sons graves.

Les oreilles humaines perçoivent les sons avec une acuité variable en fonction des fréquences. Le graphe donnant le seuil d'intensité minimale perçu en fonction de la fréquence est un audiogramme. Les fréquences inférieures à 20 Hertz ou supérieures à 20000 voir 30000 Hertz (selon les sources) ne sont pas perceptibles. En vieillissant, la bande de fréquences perceptible se réduit, et les seuils de perception augmentent. Les gens exposés longtemps aux mêmes fréquences y sont de moins en moins sensibles.

 

La phase d'un signal sinusoïdal n'est pas perceptible.

 

Les sons périodiques complexe ou composites, sont constituées de, ou peuvent être décomposés en une somme d'oscillations sinusoïdales d'amplitudes variables, ou série de Fourier.

 

s(t) = A0 + A1sin(w t + F1 ) + A2sin(2w t + F2 ) + ... Ansin(nw t + Fn )

 

Chaque sinus représente un harmonique de la fréquence angulaire fondamentale w = 2p f.

Le énième harmonique a pour fréquence n fois la fréquence fondamentale.

Aet Fn représentent respectivement l'amplitude et la phase du énième harmonique.

En augmentant la valeur de n, la précision de l'approximation augmente. La valeur de n devrait être infinie pour pouvoir représenter tous les signaux périodiques sous cette forme. Mais en pratique, les amplitudes des fréquences au dessus d'une certaine valeur deviennent négligeables (pour les signaux acoustiques qui nous intéressent).

 

La modification des phases change la forme de l'onde résultante, mais ne modifie pratiquement pas la perception du son. Les phases sont utiles à l'audition pour permettre de situer la provenance du son dans l'espace. En effet le fait d'avoir deux oreilles nous permet de capter les signaux sonores venant d'une source depuis deux endroits distincts de l'espace. La distance entre la source sonore et chaque oreille est différente, donc le temps mis par l'onde pour parcourir ces distances sera différent, cela se traduira par un déphasage des signaux perçus par chaque oreille variant en fonction de la direction de la source.

 

Les harmoniques ont un rapport profond et simple avec les vibrations.

Par exemple, quand une corde de guitare vibre, la fréquence fondamentale correspond à l'oscillation de toute la longueur de la corde. le second partiel harmonique correspond à l'oscillation de la moitié de la longueur de la corde, le troisième partiel au tiers, etc....

Les musiciens utilisent ce fait en plaçant un doigt (sans appuyer) sur la corde juste à l'endroit d'une division entière de la longueur (sur un nœud) pour éliminer tous les partiels correspondant à des longueurs plus grandes, et faire ressortir un harmonique particulier.

Quand la longueur de la corde est divisée par deux, la fréquence est multipliée par deux, et le son monte d'une octave.

 

Voici les premiers harmoniques du do3, (ut de la troisième octave) :

   fondamental = h1 = do3, h2 = do4, h3 = sol4,  h4 = do5, h5 = mi5, h6 = sol5, h7 = sib5, h8 = do6.

Les harmoniques ayant un indice égal à une puissance de deux correspondent tous à des do, d'octave en octave, et, évidemment, dans chaque octave, il y a deux fois plus d'harmoniques que dans l'octave précédente.

 

Cette correspondance entre les notes de la gamme et les harmoniques n'est pas exacte, nous allons voir pourquoi.

 

Les intervalles harmoniques :

 

une octave correspond à la multiplication par 2.

une quinte (intervalle do3-sol3 par exemple) correspond à 3/2 (multiplier par 3 fait passer du do3 au sol4 et diviser par 2 fait passer de sol4 à sol3).

une tierce majeure (do3-mi3) 5/4.

 

Une octave est composée de douze demi-tons, en montant de 7 octaves, 84 demi-tons, on multiplie la fréquence par 27 = 128

Une quinte est constituée de 7 demi-tons. En montant de 12 quintes, 84 demi-tons, on multiplie la fréquence par 312/212 = 129,74...

La quinte tempérée est donc légèrement plus petite que la quinte harmonique.

La gamme tempérée est formée de 12 demi-tons égaux. Un demi-ton correspond dans cette gamme à 2 1/12.

La quinte tempérée devient 2 7/12 = 1.498307... alors que la quinte harmonique est de 3/2 = 1.5.

 

L'effet Doppler

 

Doppler a formulé l'expression qui permet de calculer les variations de fréquence des sons perçus lorsque la source sonore et/ou l'observateur se déplacent.

 

N' = N.

 

Où N' est la fréquence apparente (correspondant à la hauteur perçue), V est la vitesse de propagation des ondes sonores dans le milieu, w la vitesse de déplacement de l'observateur (positive vers la source) et s la vitesse de déplacement de la source sonore (positive vers l'observateur). Ceci présupposant que la source et l'observateur se déplacent sur une même droite.

Par exemple, si l'observateur est attaché sur les rails et qu'une locomotive arrive droit sur lui à la vitesse de 20 mètres par seconde en sifflant un la à 880Hz, la température étant de 15° et la pression normale, la formule donnera :

 

N' = 880. = 935Hz

 

L'observateur percevra donc un son plus aigu (à peu près un demi-ton au dessus) que celui qui est émis.

Une fois l'observateur franchi, la locomotive continue à siffler, mais cette fois, elle s'éloigne de l'observateur, et la formule devient :

 

N' = 880. = 831.1Hz

 

Ce qui correspond approximativement à un la bémol, un demi-ton plus grave que le la.

 

Un élément m'intrigue dans cette formule : si maintenant nous considérons la situation, moins dramatique finalement, du chauffeur de la locomotive écoutant crier la personne attachée sur les rails, (en supposant que son cri est un la à 880Hz), nous obtenons successivement :

 

N' = 880. = 931.7Hz

 

quand le mécanicien s'approche de la source, et :

 

N' = 880. = 828.2Hz

 

quand le mécanicien s’éloigne. La formule n'est pas symétrique pour la vitesse de la source et la vitesse de l'observateur.

 

Figure A1.4 : Déplacement de l’observateur

 

Représentons la source et l'observateur dans un graphe où la position dans l'espace est mesurée horizontalement, et le temps verticalement. Un objet fixe est représenté par une verticale. Dans le graphe ci-dessus, nous avons représenté l'observateur se déplaçant de la position o à la position o' en 14 unités de temps, et la source sonore à la position fixe s.

La source émet un son (dans les deux directions) qui se déplace d'une unité d'espace en une unité de temps. Ce son est périodique, de période 2 unités de temps. La position spatio-temporelle des débuts des périodes est donc représentée par des lignes obliques, partant à 45° de la source toutes les deux unités de temps.

Les intersections de la droite (o, o') représentant l'observateur avec les lignes représentant les débuts des périodes permettent de calculer la fréquence apparente du son pour l'observateur :

 

1/ Approche de l'observateur :

 

Entre t2 et t6, pendant que l'utilisateur se rapproche de la source, il y a trois intersections (alors que dans le même temps, la source n'a émis que deux périodes (6 - 2) / 2. La fréquence est donc plus élevée d'un rapport de 3/2.

N' = N. = . = .

 

N = , La fréquence est l'inverse de la période qui ici vaut 2.

V = La vitesse de propagation du son est de 1 (1 unité de longueur par unité de temps dans ce schéma).

w = puisque l'observateur se déplace d'une unité de longueur pour 2 unités de temps. et s = 0, car la source est fixe.

 

Nous retrouvons bien notre rapport de fréquences = 3/2.

 

2/ Éloignement de l'observateur :

 

Entre t6 et t14 , il n'y a que 2 intersections alors que la source émet 8/2 = 4 périodes. Ceci donne le rapport 2/4 = 1/2.

 

N' = N. = . = .

 

 

Maintenant considérons le cas où c'est la source sonore qui se déplace :

 

Figure A1.5 : Déplacement de la source sonore

 

La source va de s en s' pendant 12 unité de temps, et l'observateur reste à la position o.

Nous voyons qu'entre t3 et t6 (pendant que la source s'approche), l'observateur percevra une fréquence 2 fois plus élevée que celle émise par la source. Et entre t6 et t12, quand la source s'éloigne, il n'y a plus que 2 intersections pour 3 périodes, ce qui donne le rapport 2/3, justement l'inverse du rapport obtenu quand l'observateur s'approchait de la source fixe.


 

Annexe 2 : Irlandais

 

{

      int dureeTotale = DureePeriode;

 

Les durées sont exprimées en nombre de double croches (la plus petite unité de temps traitée). Ici, DureePeriode = 8 * 16.

 

      int position = 0;

      int noTemps = 0;

      int ambitus = pInst->hil - pInst->lol;

 

L’ambitus est donné par la structure décrivant l’instrument.

 

      int octambitus = ambitus / 12;

      int dernièreNote = 0;

                            

Le mode de départ est majeur ou mineur. Rox est un générateur aléatoire développé par Giuseppe G. ENGLERT.

     

      mode = rox(0, 1);

 

La tonalité de départ est choisie dans les notes de la gamme

de do majeur.

 

      tonalite = modes[0][rox(0, 6)]; /* tons + simples */

     

 

Trois tableaux : memomel, memodur et memoacc, de longueur 8 * 16 (une case par double croche) contiennent respectivement la hauteur de la note (ou zéro pour un silence), la durée de la note, et le degré de la fondamentale de l’accord dans la structure harmonique.

                 

{

      int k;

     

Boucle d’initialisation des tableaux, la structure harmonique est une division des séquences de 8 mesures, par morceaux de 2 mesures, successivement sur la tonique, la sous-dominante, la dominante et la tonique.

 

      for(k = 0; k < 8 * 16; k++)

      {    

            memomel[k] = 0;

            memodur[k] = 0;

            if( (k % (2 * 16)) < 8 )

            {

                  memoacc[k] = 0; /* T */

            }

            else if( (k % (2 * 16)) < 8 * 2)

            {

                  memoacc[k] = 3; /* SD */

            }

            else if( (k % (2 * 16)) < 8 * 3 )

            {

                  memoacc[k] = 4; /* D */

            }

            else

            {

                  memoacc[k] = 0; /* T */

            }

      }

}

 

while(dureeTotale > 0)

{

      int duree;

      int intervalle;

     

La globale gblModulation est un nombre compris entre 0 et 1000 permettant de régler la probabilité de changement de tons.

La nouvelle tonalité est choisie d’après la dernière note produite.

 

      if(dernièreNote

      && rox(1, 1000) < gblModulation)

      {

            tonalite = modes[mode][dernièreNote % 7];

            mode = rox(0, 1);

      }

 

Les durées sont choisies entre 1 et 4, en fonction de la position de la note dans le temps courant (noTemps variant de 0 à 3) 0 indique un début de temps, 3 indique la dernière double croche du temps.

Le switch permet dans ce cas, de choisir les durées de façon à éliminer toutes les syncopes.

La globale gblCroches permet d’augmenter ou de diminuer les chances d’écrire des croches.

     

      switch(noTemps)

      {

      case 0 :

            if(rox(1, 1000) < gblCroches)

            {

                  duree = 2;

            }

            else duree = rox(1, 4);

            break;

      case 1 :

            duree = rox(1, 3);

            break;

      case 2 :

            if(rox(1, 1000) < gblCroches)

            {

                  duree = 2;

            }

            else duree = rox(1, 2);

            break;

      case 3 :

            duree = 1;

            break;

      }

 

Les règles rythmiques précédentes sont annulées par le choix de la durée double-croche (en fonction du réglage du paramètre gblDoubleCroche).

 

      if(rox(1, 1000) < gblDoublesCroches)

      {

            duree = 1;

      }

 

Les règles rythmiques précédentes sont annulées également par le choix de la durée croche pointée sur un temps fort, quand la variable gblHornpipe est grande.

 

      if(noTemps == 0

      && rox(1, 1000) < gblHornpipe)

      {

            duree = 3;

      }

 

La variable gblSilence règle le pourcentage de silences.

                                        

      if(rox(1, 1000) >= gblSilences)

      {   /* note */

            int absPitch;

            int octave, degre;

 

Choix de la première note, ou application de la règle de rupture, qui fait ignorer la dernière note, et repartir la mélodie sur une nouvelle note.

Octambitus contient le nombre d’octaves de l’ambitus.

 

            if(dernièreNote == 0

            || rox(1, 1000) < gblRupture)

            {

                  dernièreNote = rox(1, octambitus * 7);

            }

 

            else

 

            {

 

A priori, l’intervalle mélodique est conjoint (intervalle = 1 -> seconde):

 

                  intervalle = 1;

 

Mais, la variable gblRepetition règle le pourcentage de notes répétées, et l’intervalle peut être remis à zéro.

                 

                  if(rox(1, 1000) < gblRepetition)

                  {

                        intervalle = 0;

                  }

                  else if(rox(1, 1000) > gblContiguite)

                  {

 

Une faible valeur de la variable gblContiguite augmente les chances d’incrémenter la valeur de l’intervalle mélodique.

 

                        intervalle ++;

                       

                        if(rox(1, 1000) > gblContiguite)

                        {

                             intervalle++;

 

Les intervalles de quarte ont été installés puis abandonnés, il se peut que des quartes apparaissent toutefois, à cause des autres règles modifiant la mélodie.

 

                             /* if(rox(1, 1000) > gblContiguite)

                             {

                                   intervalle++;

                             } */

                        }

                  }

 

Le cœur de l’algorithme de génération : la ligne mélodique monte ou descend suivant que le point aléatoire est plus haut ou plus bas que la dernière note.

                 

                  if( rox(1, octambitus * 7) > dernièreNote )

                  {

                        dernièreNote += intervalle;

                  }

                  else

                  {

                        dernièreNote -= intervalle;

                  }

            }          

           

            if(rox(1, 1000) < gblPlanAccords)

            {

                  /* influence accords */

 

                  if(!noTemps

                  || noTemps == 2)

                  {

 

L'influence de la grille d'accords sur la mélodie ; elle n'agit que sur les temps forts (début du temps) et les demi-temps, elle n'agit pas sur les quarts de temps. On regarde la position de la note par rapport au notes de l'accord déterminé par la table memoacc. Puis on fait monter ou descendre la note pour qu'elle devienne constituante de l'accord.

 

                        int delta;

                        degre = dernièreNote % 7;

                       

                        /* fondamentale */

                        delta = (memoacc[position] + 7 - degre) % 7;

                       

                        if(delta == 1)

                        {

                             dernièreNote++;

                        }

                        else if(delta == 6)

                        {

                             dernièreNote--;

                        }

                        else

                        {    

                             /* tierce */

                             delta = (memoacc[position] + 2 + 7 - degre) % 7;

                       

                             if(delta == 1)

                             {

                                   dernièreNote++;

                             }

                             else if(delta == 6)

                             {

                                   dernièreNote--;

                             }

                             else

                             {

                                   /* quinte */

                                   delta = (memoacc[position] + 4 + 7 - degre) % 7;

                            

                                   if(delta == 1)

                                   {

                                         dernièreNote++;

                                   }

                                   else if(delta == 6)

                                   {

                                         dernièreNote--;

                                   }

                             }

                        }

                  }

            }

            octave = dernièreNote / 7;

            degre = dernièreNote % 7;

           

            {

                  static precNote = 0;

                 

                  int nmode;

                 

                  nmode = mode;

                  if(nmode == 1)

                  {

                        if(precNote >= dernièreNote)

                        {

                             nmode = 3; /* 2; */

                        }

                        else

                        {

                             nmode = 2; /* 3; */

                        }

                  }

                  absPitch =

                        modes[nmode][degre]

                            + tonalite

                             + octave * 12

                             + pInst->lol;

                 

                  memomel[position] = absPitch;

                  memodur[position] = duree;

                  precNote = dernièreNote;

            }

      }

      else

      {    

            /* silence */

            memodur[position] = duree;

            memomel[position] = 0;

            dernièreNote = 0;

      }

      dureeTotale -= duree;

      position += duree;

      noTemps += duree;

      noTemps &= 3;

}

/* fin while */

 

A ce point, toutes les notes ont été calculées, et sont notées en numéros de demi-tons dans la table memomel.

 

/* plans locaux de recopies */

{

      int compte;

     

      for(compte = 0; compte < 6; compte++)

      {

            if(rox(1, 1000) < gblPlanLocal)

            {

                  int hauteur = 0;

                  int parite = 0;

                  int longueur = rox(1, 32);

                  position = rox(0, 8 * 16 - 1);

                 

                  while(longueur-- > 0

                  && position < DureePeriode)

                  {

                        if(!hauteur)

                        {

                             hauteur = memomel[position];

                        }

                        else if(memomel[position])

                        {    

                             if(parite & 1)

                             {

                                   memomel[position] = hauteur;

                             }

                             parite++;

                        }

                        position++;

                  }                                             

            }

      }

}

 

/* plans généraux de recopies */

{

      int compte;

     

      for(compte = 0; compte < 6; compte++)

      if(rox(1, 1000) < gblPlanRecopie)

      {

            int plan = rox(2, 5);

           

            int tailleBloc = (1 << plan);

           

            for(position = 0; position < DureePeriode; position += (4*tailleBloc))

            {

                  int inside;

                 

                  for(inside = 0; inside < tailleBloc; inside++)

                  {

                        memodur[position + tailleBloc * 2 + inside] =

                             memodur[position + inside];

                        memomel[position + tailleBloc * 2 + inside] =

                             memomel[position+ inside];

                  }

            }

      }

}

Transformation des tables en structures chaînées pour notre système d'impression des partitions.

 

for(position = 0; position < DureePeriode; position++)

{

      int absPitch = memomel[position];

      int duree = memodur[position];

      if(absPitch)

      {    

            derniereNote[voix] =

                  CreerNote(

                     derniereNote[voix], /* preced */

                     (Note *)0,          /* suiv */

                     absPitch,              /* hauteur absolue */

                     duree,           /* duree */          

                     0,               /* respiration */

                     Sostenuto, /* Tremolo Staccato..., (articulation) */

                     pInst);

      }

      else

      {    

            derniereNote[voix] =

                  CreerNote(

                     derniereNote[voix], /* preced */

                     (Note *)0,          /* suiv */

                     0,               /* hauteur absolue */

                     duree,           /* duree */          

                     duree,                 /* respiration */

                     Tacet,           /* articulation */

                     pInst);

      }

      if(!Partition[periode][voix].note)

      {

            Partition[periode][voix].note

                  = derniereNote[voix];

      }

      if(!derniereNote[voix])

      {

            return FALSE;

      }

}                

continue; /* instrument suivant */

 


Annexe 3 : Règle de couplage (frottement)

 

void calculerCouplageAccNoeud(fnoeud *unNoeud)

{

      chaineIter mailles;

      f_point tension;

      f_point acceleration;

     

      if(!unNoeud

      || unNoeud->fixe)

      {

            return;

      }

     

      acceleration.f[0] = acceleration.f[1] = 0;

     

      iterPremier(&mailles, &unNoeud->departs);

      while( iterParcours(&mailles) )

      {

            flien *unLien = iterElement(&mailles);

           

            fnoeud *uneArrivee = unLien->arrivee;

            if(uneArrivee)

            {

                  tension.f[0] = (uneArrivee->present.f[0]

                             - unNoeud->present.f[0])

                        * unLien->tension1;

                  tension.f[1] = (uneArrivee->present.f[1]

                             - unNoeud->present.f[1])

                        * unLien->tension1;

                  acceleration.f[0] += tension.f[0];

                  acceleration.f[1] += tension.f[1];

            }

            iterSuivant(&mailles);

      }

      iterPremier(&mailles, &unNoeud->arrivees);

      while( iterParcours(&mailles) )

      {

            flien *unLien = iterElement(&mailles);

           

            fnoeud *unDepart = unLien->depart;

            if(unDepart)

            {

                  tension.f[0] = (unDepart->present.f[0]

                             - unNoeud->present.f[0])

                        * unLien->tension2;

                  tension.f[1] = (unDepart->present.f[1]

                             - unNoeud->present.f[1])

                        * unLien->tension2;

                  acceleration.f[0] += tension.f[0];

                  acceleration.f[1] += tension.f[1];

            }

            iterSuivant(&mailles);

      }


 

      /* frottement

      c'est une accélération, elle s'oppose toujours à la vitesse

      et, (tel que c'est écrit, impose un mouvement résiduel lorsque

      la vitesse est inférieure au frottement en valeur absolue)

      */

 

      if(unNoeud->vitesse.f[0] > 0)

      {

            unNoeud->vitesse.f[0] -= unNoeud->frottement;

      }

      else

      {

            unNoeud->vitesse.f[0] += unNoeud->frottement;

      }

      if(unNoeud->cumul.f[1] > 0)

      {

            unNoeud->vitesse.f[1] -= unNoeud->frottement;

      }

      else

      {

            unNoeud->vitesse.f[1] += unNoeud->frottement;

      }

     

      unNoeud->vitesse.f[0] += acceleration.f[0];

      unNoeud->vitesse.f[1] += acceleration.f[1];

     

      unNoeud->futur.f[0] =

            unNoeud->present.f[0]

            + unNoeud->vitesse.f[0];

      unNoeud->futur.f[1] =

            unNoeud->present.f[1]

            + unNoeud->vitesse.f[1];

}

 


Annexe 4 : Phénomènes Physiques en Acoustique, Étude expérimentale du timbre des sons

 

Extrait du : Nouveau Cours de Physique élémentaire

(pour la classe de mathématiques)

sous la direction de E.Fernet

J.Faivre-Dupaigre, E.Carimey

Édition Masson 1906

 

Analyse d’un son complexe par les résonnateurs (sic)

 

Si l’on possède une série de caisses de résonnance (sic), ou résonnateurs de dimensions diverses, on conçoit, d'après ce qui précède, que l'on puisse les utiliser pour savoir si tel ou tel son simple existe dans un son complexe. Il suffit, en effet, de déterminer quels sont ceux de ces résonnateurs qui entrent en vibration sous l'influence de ce son complexe. Telle est la méthode imaginée par von Helmoltz.

 

L'expérience a montré que la forme de résonnateur la plus favorable, pour le but que l'on se propose, est celle de cavités sphériques présentant une ouverture AB et à l’opposé de cette ouverture, un conduit MN que l'on introduit dans l’oreille.

 

Fig.

 

Dans cette forme de tuyaux sonores, le son fondamental est le seul qui prenne nettement naissance : c'est ce son simple que nous appellerons le son propre du résonnateur.

 

Fig.

 

Pour faire l'analyse d'un son produit à l’extérieur, l’observateur bouche l’une de ses oreilles; dans l’autre, il introduit successivement les conduits de divers résonnateurs, de dimensions telles que leurs sons propres correspondent aux diverses notes de l’échelle musicale.

Si le son complexe qui est soumis à l’analyse contient un son simple ayant même hauteur que le son propre d'un certain résonnateur, l’oreille entend éclater ce son avec une intensité presque assourdissante. Au lieu de mettre les résonnateurs à l'oreille, on peut les munir de capsules manométriques dont on observe les flammes dans un miroir tournant. On détermine ainsi d’un seul coup d’oeil quels sont les résonnateurs qui entrent en vibration sous l'influence du son complexe étudié. C'est ainsi que l'on a pu constater l’existence de telle ou telle note, dans des sons complexes qui semblaient d'abord bien difficiles à analyser, comme le bruit d'une voiture, le sifflement du vent, le murmure de l'eau, etc. Lorsqu'on approche de l'oreille un objet présentant une cavité, un coquillage, une bouteille, un flacon quelconque, la masse d'air renfermée dans la cavité joue le rôle d'un résonnateur : de là, le son de hauteur fixe que l'on entend dans ces conditions, parce que ce son se trouve toujours parmi les bruits confus qui se produisent continuellement autour de nous.

 

Composition des sons complexes

 

Les résultats fournis par les analyses précédantes sont les suivants : les sons complexes sont toujours constitués par la superposition d'un certain nombre de sons simples : le son fondamental, plus ou moins intense et un certain nombre d'autres sons plus aigus. Mais il y a deux sortes de sons complexes : 1° ceux dans lesquels le son fondamental n'est accompagné que de ses harmoniques; 2° ceux dont le son fondamental est accompagné de sons partiels qui ne sont pas ses harmoniques.

 

Les sons complexes formés d'un son fondamental et de ses harmoniques ont un timbre agréable et constituent, à proprement parler, les sons musicaux. Lorsque des instruments de diverses espèces fournissent une même note musicale, ils rendent le même son fondamental ; mais chacun d'eux superpose à ce son tel ou tel groupe d'harmoniques, avec telle ou telle intensité relative. Ainsi, le son d'un diapason, ou ceux que rendent, sous l'action d'un courant d'air trop faible, les gros tuyaux fermés de l'orgue, sont des sons simples ou presque dénués d'harmoniques. La présence des six premiers harmoniques, que l'on constate dans les notes graves du piano, ou dans celles des tuyaux ouverts de l'orgue, donne à ces sons de la plénitude et de l'éclat. Dans le violon ou le violoncelle, le nombre des harmoniques superposés est généralement assez considérable, d'autant plus grand que la corde est plus fine. De là le caractère d’acuité que présentent les sons de ces instruments, et qui arrive à en rendre l’audition désagréable lorsqu’ils sont maniés par des exécutants inhabiles.

 


Références bibliographiques

 

[1] Apple Computer Inc.

            Inside Macintosh

            Volumes I à VII

            Addison Wesley, 1985 - 1991

 

[2] Apple Computer Inc.

            Audio Interchange File Format ‘AIFF’

            a Standard for Sampled Sound Files.

            Version 1.3 Jan. 1989

 

[3] ALLEN J. F.

            Maintaining Knowledge about Temporal Intervals.

            Communications of the ACM, 26(11) pp 832-843.  1983

 

[4] ARFIB Daniel

            Conception Assistée par Ordinateur en Acoustique Musicale

            Thèse de doctorat

            Université d’AIX MARSEILLE II, 1977

 

[5] ARFIB Daniel et DELPRAT Nathalie

            “Musical Transformations Using the Modification of Time Frequency Images”

            CMJ 17:2 pp 66-72 1993

 

Peter K. A. ????

[6] “Planète en panne”  ARFIB Daniel

            “Une boîte à outils de traitements sonores en MATLAB”

            Rapport du LAFORIA 95/13, mars 1995

            Deuxièmes Journées d’Informatique Musicale JIM’95

            p 165

 

[7] BALMAS Françoise

            “Classifying Programs : a Key for Program Understanding”

            Seventh Int. Conf. on Software Engineering and

            Knowledge Engineering, Rockville (MD).

            Juin 1995

 

[8] BARBAR K, BEURIVE A. DESAINTE-CATHERINE M.

            “Structure hiérarchique et relations temporelles d’une pièce de musique”

            Rapport du LAFORIA 95/13, mars 1995

            Deuxièmes Journées d’Informatique Musicale JIM’95

            p 133 - 141

 

[9] BARBAUD Pierre,

            “Initiation à la Composition Musicale Automatique”

            Dunod PARIS, 1966

 

[10] BARNSLEY M. F

            Fractals Everywhere

            Springer-Verlag New-York 1989

 

[11] BATTIER Marc

            Note de programme pour :

            Toca, for Marimba and Electronic Sounds

            KOBE International Modern Music Festival

            JAPON, 1993

 

[12] BEKKOUCHE Sabah

            “Génération du code de détection d’erreur (H.E.C)

            Etude et Maquette d’implantation logicielle.”

            Université Paris-8 Département Informatique Juin 1994.

 

[13] BELKIN Alan

            “Macintosh Notation Software : Present and future”

            CMJ 18;1 pp 52-69 1994

 

[14] BINGEN J.N CROMBEZ R. DEFFET L.

            Unité de Mesures Scientifiques et Industrielles

            Eyrolles, PARIS 1959

 

[15] BEAUCHAMP K.G.

            Transforms for Engineers

            a Guide to Signal Processing.

            Oxford Science Publications

            Clarendon Press, 1987

 

[16] BOULANGER Richard.

            “Making Music with CSound.”

            BERKLEE College of Music

            1990

 

[17] BLOSTEIN Dorothéa, HAKEN Lippold

            “Justification of Printed Music

            Communications of tha ACM/March 1991/Vol. 34. n°3

 

[18] BRACEWELL R. N.

            The Fourier Transform and its Application.

            Second Edition, Revised

            McGRAW HILL, 1986

 

[19] BYRD Donald (don@cogsci.indiana.edu)

            “Music Notation Softwares and Intelligence”

            CMJ 18:1 pp 17-20 1994

 

[20] CADOZ Claude, LUCIANI Annie et FLORENS Jean Loup

            “CORDIS-ANIMA : A Modeling and Simulation System for Sound

            and Image Synthesis - The General Formalism”

            CMJ 17:1 pp 19-29 1993

 

[21] CADOZ Claude

            Les Réalités Virtuelles

            Dominos Flammarion 1994

 

[22] CARDEW Cornelius

            Treatise

            The Gallery Upstairs Press, BUFFALO, NEW YORK 1967

 

[23] CHAFE Chris, MONT-REYNAUD Bernard et RUSH Loren

            “Toward an Intelligent Editor of Digital Audio : Recognition of Musical Constructs”

            CMJ 6:1 1982

 

[24] CHOWNING John M.

            “The Synthesis of Complex Audio Spectrum by Means of Frequency

            Modulation”

            Journal of Audio Engineering Society 21:7 1973

 

[25] CHOWNING John. M et BRISTOW David

            FM Theory & Applications, By Musicians for Musicians

            Yamaha Music Foundation, Japan, 1986

 

[26] COUASNON Bertrand et RETIF Bernard

            “Utilisation d’une grammaire dans la reconnaissance de partitions

            d’orchestre”

            Rapport du LAFORIA 95/13, mars 1995

            Deuxièmes Journées d’Informatique Musicale JIM’95

            p 143

 

[27] DECARLOS Douglas

            XSpringies A Mass and Spring Simulation System for X Windows.

            dmd@gradient.cis.upenn.edu 1992

 

[28] DJOHARIAN Pirouz

            “Generating Models for Modal Synthesis”

            CMJ 17:1 pp 57-65 1993

 

[29] DORFLES Gillo

            Il Metodo per Suonare di Giuseppe CHIARI

            Martano editore, TORINO, 1976

 

[30] DUBOIS Paul

            TransSkel Transportable application skeleton

            1986

            Wisconsin Regional Primate Research Center

            1220 Capital Court

            Madison WI 53706 USA

 

[31] ENGLERT Giuseppe G.

            Automated Composition and Composed Automation

            dans : The Music Machine

            édité par C. Roads MIT Press 1989 p-191

            translated from french by Otto LASKI with Curtis ROADS.

            Musique : Composition Automatique, Automation Composée

            Informatique et Sciences Humaines 45

            Sorbone, Paris, 1981

 

[32] ENGLERT Giuseppe G.

            GZ50               1979-80

                        pièce pour orgue, à l’occasion des 50 ans de Gert ZACHER.

            BABEL           pièce pour orchestre 1982

            ECORCES      quintette 19

 

[33] ENGLERT Giuseppe G.

            Pièce générée et imprimée par le programme CHNRNG14:

            CHACONES, pour Orchestre et piano concertant

            Création à BERN, SUISSE, mai 1995.

           

[34] ENGLERT Giuseppe G.

            “Our Score : A Description of Metro 3, A Compositional and

            Performance Software Program".

            Leonardo Music Journal Vol. 3 pp. 53-58 1993.

 

[35] ENGLERT Giuseppe G.

            Pièce pour Métro3 :

            Sopre la Girolmeta

            Fête des musiciens Suisses

            MARTIGNY 1992

 

[36] ENGLERT Giuseppe G.

            Pièce pour Phonogramme

            Triptyque

            STIMMUNGEN das festival für Gerd ZACHER.

            ESSEN 1994

 

[37] ETHINGTON Russ et PUNCH Bill

            “SeaWave : A System for Musical Timbre Description”

            CMJ 18:1 pp 30-39 1994

 

[38] FAIVRE-DUPAIGRE J. CARIMEY E.

            Nouveau Cours de Physique Elémentaire

            3ième Partie, Classe de Mathématiques.

            Masson & Cie, PARIS 1906.

 

[39] FEITEN Bernhard et GÜNZEL Stefan (Feiten@kgw.TU-Berlin.de)

            “Automatic Indexing of a Sound Database Using Self-organizing

            Neural Nets”

            CMJ 18:3 pp53-65, 1994

 

[40] FINK Mathias

            “Le Retournement des ondes acoustiques

            La Recherche 264, Avril 1994 Vol. 25

 

[41] FINK Mathias

            “Time Reversal mirrors

            J.Phys. D:Appl.Phys 26,1,1993

 

[42] FOBER Dominique, LETZ Stéphane, ORLAREY Yann

            “MIDIShare, Un système d’exploitation musical pour la

            communication et la collaboration”

            Rapport du LAFORIA 95/13, mars 1995

            Deuxièmes Journées d’Informatique Musical JIM’95

            pp 91-100.

 

[43] GAVER William W.

            “Synthesizing Auditory Icons

            INTERCHI’93 pp-228-235

 

[44] GOGINS Michael

            Iterated Functions Systems Music

            CMJ 15:1 pp 40-48

 

[45] GOLDBERG Adele, ROBSON David

            Smalltalk-80

            The Language and its Implementation

            Addison-Wesley 1989

 

[46] GOLDBERG David E.

            “Genetic Algorithms and WALSH Functions

            Complex Systems 3 (1989) pp129-152, pp153-171

 

[47] GREUSSAY Patrick

            Contribution à la Définition Interprétative et à l’Implémentation des Lambda-langages.

            Thèse, Université Paris VII, 1977

 

[48] HILLER Lejaren

            “Automated Music Printing”

            Journal of Music Theory 9 pp 129-150

            1965

 

[49] HOLM Frode      (holm@cs.ucsb.edu)

            “Understanding FM Implementations : A Call for Common

            Standards”

            CMJ 16:1 pp 34-42

 

[50] HORNER Andrew, BEAUCHAMP James, HACHEN Lippold

            Machine Tongues XVI : Genetic Algorithms and their application to

            FM synthesis.

            CMJ 17:4 pp 17-29, 1993

 

[51] JAFFE David A., O SMITH Julius

             “Extension of the Karplus-Strong Plucked-String Algorithm”

            CMJ 7:2 1983

 

[52] JONES Kevin

            “Compositional Applications of Stochastic Processes”

            CMJ 5:1 1981 (in The Music Machine pp 381-397)

 

[53] KARPLUS Kevin, STRONG Alex

            “Digital Synthesis of Plucked-String and Drum Timbre”

            CMJ 7:2 1983

 

[54] KRIEF Philippe

            M.PV.C. Un système interactif de construction d’environnements de prototypage de multiples outils d’interprétation de modèles de représentation

            Thèse, Université Paris-8, septembre 1990.

            LITP 90.66

 

[55] LANSKY Paul et STEIGLITZ Kenneth

            “Synthesis ot Timbral Families by Warped Linear Prediction”

            CMJ 5:3 1981

           

[56] LESBROS Vincent

            Mémoire de DEA en Intelligence Artificielle

            Département Informatique

            Université Paris-8. 1988

 

[57] LESBROS Vincent

            Lexique Smalltalk

            Rapport interne

            Département Informatique (LIT), Université Paris-8, Novembre 1989

 

[58] LESBROS Vincent (1995a)

            “Atelier informatique pour la musique expérimentale”

            Rapport du LAFORIA 95/13, mars 1995

            Deuxièmes Journées d’Informatique Musicale JIM’95

            pp 67-80

 

[59] LESBROS Vincent.(1995b)

            "From Images to Sounds - a Dual Representation"

            Computer Music Journal à paraître.

 

[60] LESBROS Vincent

            - Pièces pour Phonogramme :

                        “Farni-NT”, CHELLES 1994

                        ”Phonographiques”  & ”Pouzzolane”, STIMMUNGEN das          festival für Gerd ZACHER, ESSEN 1994

                        “Midisonnante”, ZURICH 1994

            - Partie électronique live avec Métro3 et Composition partielle des

            partitions pour instrumentistes avec le programmeAléamoire.

            de la pièce Pays Musique de Pierre MARIETAN, 1991

 

[61] MARCHAL Suzanne (André-)

            Notions Elémentaires d’Harmonie

            HEUGEL et Cie, PARIS 1974

 

[62] MARIETAN Pierre

            ”Pays Musique”

            Septième Centenaire de la Confédération Suisse

            Création : Cathédrale de LAUSANNE 1991

            Diffusion : France Culture 1991

 

[63] MARTINEZ Lirio

            Un atelier d’informatique musicale interactive temps reel

            Mémoire de maîtrise, Université Paris-8

            à paraître 1995.

 

[64] MIDI Manufacturers Association, Japan Standard Commitee

            MIDI 1.0 Detailed Specification

            Document version 4.1

            The International MIDI Association 1989

           

[65] MORRISON Joseph Derek et ADRIEN Jean Marie

            “MOSAIC : A Framework for Modal Synthesis”

            CMJ 17:1 pp 44-56 1993

 

[66] MOON Francis C.

            “The continuum limit of lattices ‘solitaire’ solutions”

            in Chaotic and Fractal Dynamics pp 350-353

            John Wiley & Sons, 1992

 

MOORER

(systeme de la table dd’onde reference avant Traitement du signal chap 2)

[67] O'NEILL Waltons'Musical Instrument Galleries Ltd.

            1001 Gems, The Dance Music of Irland

            2-5 North Frederick Street, Dublin.

 

[68] ORLAREY Yann, LEQUAY Hervé

            “MIDIShare : a real time multi-tasks software module for Midi

            applications.”

            Proceedings of the ICMC, 1989, ICMA, San Fransisco.

 

[69] PARKER Charlie

            Extrait du CD analysé par la transformée élastique (introduction,          figure 1.11).

            CD The Complete Charlie Parker on Verve

            édition. 1988, VERVE 837 146 2

            Plage 4 de 16" à 24"

            (Charlie Parker with Strings) disque original.

 

[70] RISSET Jean Claude et MATHEWS Max

            “Analysis of Musical Instrument Tones”

            Physics Today 22:2 1969

 

[71] ROADS Curtis

            “Granular Synthesis of Sound”

            CMJ 2:2 pp 61-62 1978

 

[72] ROADS Curtis

            “A Note on Music Printing by Computer”

            CMJ 5:3 1981

 

[73] ROADS Curtis

            The Computer Music Tutorial

                        Chapitre 8 : Graphic sound synthesis

            MIT Press (à paraître 1995)

 

[74] RODET Xavier

            Analyse du Signal Vocal dans sa Représentation Amplitude-Temps

            -Synthèse de la Parole par Règles.

            Thèse de Doctorat

            Université PARIS VI, 1977

 

[75] ROGERS David F.

            “Algorithmes pour l’Infographie”

            MacGraw-Hill 1988

 

[76] ROSENTHAL David (dfr@media.media-lab.mit.edu)

            “Emulation of Human Rhythm Perception”

            CMJ 16:1 pp 65-76 1992

 

[77] ROWE Robert

            “Machine Listening ans Composing with CYPHER”

            CMJ 16:1 pp 43

 

‘‘‘TERHART

  ??? (algorithme de conversion de signaux audio en partition)’’’

 

[78] SNELL John

            “Design of a Digital Oscillator that will Generate up to 256 Low-

            Distorsion Sine Waves in Real Time”

            CMJ 1:2 pp 4-25 1977

 

[79] SOIZE C.

            Méthodes Mathématiques en Analyse du Signal

            Masson 1993.

 

[80] Standard MIDI Files 0.03

            Opcode System

            Palo Alto, California

 

[81] VERCOE Barry L.

            “CSOUND : A manual for the Audio Processing System and

            Supporting Programms with Tutorial.”

            Medialab MIT 1986-91

 

[82] WARUSFEL André

            Les nombres et leurs mystères

            Seuil 1961

 

[83] WERTZ Harald

            (Common) LISP - Une introduction à la programmation

            Masson, 1989

 

[84] WERTZ Harald

            Une collection personnelle d’image fractales (non publiée)

            1994

 

[85] XENAKIS Iannis

            Formalized Music

            Indiana University Press 1971

 

[86] YAVELOW Christopher

            Macworld Music & Sound Bible

            IDG Books Worldwide, Inc. 1992

                        Editeurs de partitions : pp 865-994

 

[87] ZICARELLI David

            OVALTUNE

            Intelligent Computer Music Systems, Inc.

           

 

 



[1] ou du milieu siège de la propagation du son.

[2]GRAME : Laboratoire de recherche, LYON.

[3]Les liaisons des émetteurs aux noeuds soumis à l’excitation, et celle des noeuds et des liens aux récepteurs  ne sont pas représentées ici.

[4]En tant qu’image, ou en tant que séquence d’événements sonores.

[5]C’est-à-dire enregistrés à partir d’une source naturelle.

[6] Deux TX816 de YAMAHA comprennant chacun 8 modules TF1. Les TF1 sont des synthétiseurs basés sur la technique de modulation de fréquence équivalents au modèle DX7 sans le clavier.

[7]La gamme chromatique est constituée de l’ensemble des 12 demi-tons existants.

[8]Nous l’avons testé sur une machine basée sur le processeur MOTOROLA 68000 cadencé à 8 MHz (Macintosh Plus)

[9]Peu de studios de musique électroacoustique possèdent seize synthétiseurs.

[10]Le format PICT est le format standard pour les images sur Macintosh.

[11]Jouée à CHELLES (région parisienne) en Juin 1994

[12]STIMMUNGEN das festival für Gerd ZACHER. ESSEN 1994

[13]ZURICH 31/12/1994

[14]L’éditeur de phonogrammes est nommé Phonogramme.

[15]La somme des vecteurs formés par le point et ses voisins.

[16]Dépendant du nombre de liens.

[17]La viscosité est un paramètre permettant de régler une déperdition d’énergie. Ceci est nécessaire pour amortir les mouvements et éviter une résonance infinie.

[18]Au GAIV, Groupe Art et Informatique de Vincennes à St DENIS.

[19]De NED, New England Digital Corporation.

[20]MIDIShare (ORLAREY 1989).

[21]Le matériel d’orchestre comprend :

                • la partition pour le chef d’orchestre (ou la partition simplement) qui doit permettre de lire toutes les voix simultanément,

                • les parties séparées, qui sont les partitions destinées à chaque groupe d’instruments jouant les mêmes notes dans le même système d’écriture (même transposition, même clef) ne contenant que la voix destinée au groupe,

                • et le matériel comprend enfin la partition de piano, l’instrument soliste de cette pièce.

Il arrive toutefois, pour certains passages dans les parties séparées, que la partie soit écrite dans des systèmes à deux portées. Ceci est utile quand les instruments d’un groupe se distinguent dans de rares passages.

[22]Les graines (ou semences) sont les valeurs initiales mémorisées dans le générateur.

[23]Par exemple la lisibilité de portées contenant les voix de deux instruments simultanément.

[24]UPIC Unité Polyagogique Informatique du CEMAMu.

[25]Echelle tempérée au 32ième de ton

[26]La particularité des fractales est l’invariance d’échelle, mais concrètement, les images manipulées sont des portions de fractales numérisées à une résolution donnée, et un changement d’échelle de l’image, ou le choix d’une zone d’une fractale peut modifier son aspect global.

[27]Pixel : picture element

[28]Une image peut être vue comme une fonction qui, à un couple de coordonnées, fait correspondre une information sur la couleur :

Image(x, y) -> couleur

[29]Nombre de lignes des bus de données, taille des registres des processeurs.

[30]Le nombre de configurations augmente si l’on accepte les intervalles nuls (x1 = x2).

[31]Le format PICT est le format standard des fichier images sur Macintosh.

[32]Une table de vecteurs donne l’adresse de chaque routine de la bibliothèque graphique, et des fonctions permettent de redéfinir temporairement l’adresse des routines. Ceci peut être utilisé pour implanter ses propre routines graphiques de base dans le système, ou encore pour reinterpréter des images vectorielles de ce format (inventer de nouveaux types de contextes graphiques). Par exemple, pour l’impression, un contexte graphique spécialisé traduit toutes les opérations graphiques en commandes PostScript.

[33] le calcul 2 / 2.54 * 240 donne 188,9 au lieu de 16 * 12 = 192. La résolution exacte pour deux centimètres par octave est 243,84 points par pouce.

 

[34]Les 16 canaux peuvent être activés ou désactivés individuellement. Lorsqu’ils sont désactivés, les segments du phonogramme correspondant ne sont ni visualisables ni modifiables.

[35]Leur dérivée donne l’écart entre la fréquence analysée et la fréquence d’analyse.

[36] Au Japon, la fréquence utilisée est 442 et non 440 Hertz.

[37]Sauf pour la première position, mais la lecture est effectuée avant l’écriture.

[38]Le message Note On indique la pression d’une touche sur un clavier, ou l’attaque d’une note en général.

[39]Le message Note Off indique que l’on relève le doigt pour un clavier, ou le début de la chute du son en général.

[40]A moins de passer par une étape intermédiaire : émettre premièrement un événement privé à destination de l’application elle-même, qui, à la réception est soit ignoré (dans le cas ou l’exécution à été arrêtée), soit converti réellement en message MIDI si l’exécution se prolonge.

[41]Les interfaces MIDI sont connectées aux ports série et parallèle.

[42]Les signaux peuvent être décomposés en d’autres signaux de base que les sinusoïdes, par exemple les carrés, comme dans la transformée de Walsh (GOLDBERG 1989).

[43]Si l’on ajoute des éléments dans une section qui est en cours d’exécution, ceux-ci ne sont pas pris en compte actuellement : c’est juste à l’instant de déclenchement que tous les événements sont préparés. Nous pourrions intégrer les segments créés lors d’un coup de pinceau si une exécution est en cours. Mais, lors d’un effacement, nous ne pouvons pas éliminer les messages déjà envoyés. Ceci est envisageable, en créant un système de messagerie (les messages différés sont envoyés à l’application elle-même, qui ne les poste définitivement qu’à leur retour, lorsque la date est atteinte, ou qui les élimine si un contre-ordre est survenu entre le premier envoi et la date prévue d’émission. Ceci alourdirait considérablement le travail d’émission et de réception de messages, et n’a pas été implémenté.

 

[44]Nous traitons également un autre cas particulier : celui ou les rectangles des cellules sont égaux et parfaitement superposés. Dans ce cas, nous considérons qu’il n’y a pas d’inclusion. Le graphe d’inclusion des cellules est sans cycle.

[45]La suppression s’effectue en biffant une surface, c’est-à-dire en effectuant un trajet avec le pointeur de  la souris enfoncé, dont la longueur à une certaine proportion avec le cadre englobant le trajet (plus du double du perimètre). À ce moment, toutes les cellules incluses dans ce cadre sont supprimées, ainsi que les flèches partant de ces celules ou y arrivant.

[46]Evidemment, dans le cas particulier où le diviseur (ou le multiplicateur) est une puissance entière de la base, un simple décalage est plus efficace.

[47]Un exemple de recherche d’algorithmes simples pour produire des sons paramétrables de façon intuitive est fourni par W. W. GAVER (GAVER 1993).

[48]La programmation des DSP n’est pas accessible directement (n’est pas intégrée dans les compilateurs standards) et demande un investissement non négligeable en temps. Ce coût est encore supérieur aux avantages par rapport aux besoins de nos expériences.

[49]Dans les réseaux de couplages élastiques les points sont soit fixes, soit mobiles.

[50]Le coeffient du ressort est choisi de façon à ce que la tension ne soit jamais supérieure à 1.

[51]Représentée par les niveaux de gris

[52]On obtient le même type de résultat avec le carré de la distance. Le coefficient du ressort doit être ajusté (de l’ordre de 10-7 pour le carré de la distance et de 10-4 pour la distance euclidienne.

[53]Ce régime d’oscillation serait impossible à obtenir physiquement, car la longueur du ressort passe par une valeur nulle, et le ressort traverse son point d’attache fixe.

[54]La vitesse étant un vecteur, elle possède un module, c’est-à-dire la longueur du vecteur, et une direction.

[55]J'appelle résonance propre le son obtenu en déséquilibrant initialement un système de couplages élastiques, et en le laissant osciller ensuite sans le perturber de nouveau.

[56]Enveloppe:  Surface dans l'espace amplitude/temps délimitée par les droites reliant les extremums d'amplitude. Comme le signal vaut en moyenne zéro; l'enveloppe est globalement symétrique par rapport à l'axe du temps, donc nous pouvons simplifier en limitant la représentation des enveloppes à leur courbe supérieure.

[57] Ceci pourrait être développé pour réaliser un algorithme de suivi de fondamental.

[58]La possibilité d’utiliser le DSP (Digital Signal Processor) ou du matériel dédié pour effectuer les calculs des bancs de résonateurs est envisagée.

[59]Macintosh

[60]Par exemple pour être en mesure de gérer des ascenseurs dans des boites de dialogue. Et la gestion automatique des liaisons entre les variables et les contrôles (cf § Descriptions de contrôles).

[61]Les états de parcours de chaînages sont maintenus dans des structures, pour permettre plusieurs parcours simultanés, modifiant éventuellement le chaînage parcouru. Ceci simplifie l’écriture et donne un degré de liberté supplémentaire par rapport à l’implémentation effective du chaînage.

[62]Nous utilisons les surfaces sensibles pour précalculer, pendant les temps de réflexion de l’utilisateur, les fonctions à appeler et leurs paramètres, en fonction de l’endroit où il cliquera.

[63]Par exemple, un module utilisant les chaînages bidirectionnels n’a pas a connaître le détail des champs des structures représentant les maillons pour construire et modifier ces chaînages. Mais, s’il doit faire des opérations particulières telles que permuter les éléments du chaînage par couple, un accès direct aux champs des maillons sera plus efficient que l’appel aux fonctions de retrait et d’insertion de la bibliothèque. Une telle permutation n’étant pas une opération commune, l’intèrêt de l’ajout de cette fonction à la bibliothèque est limité.

[64]Il suffit donc de refaire l'édition de lien pour visualiser les allocations faites par un module. On peut aussi redéfinir le nom de la fonction d'allocation. Par exemple :

#define malloc memoireGraphique

#define free libererGraphique.

Un point d’entrée supplémentaire est nécessaire pour la gestion de la fenêtre de visualisation : si l’application est construite avec nos squelettes, ce point d’entrée est automatiquement établi.

[65]Nous utilisons habituellement un allocateur dynamique que nous avons conçu spécialement pour l'allocation de nombreux  objets de taille réduite. Notre allocateur réserve des pages de mémoire classées selon la taille des objets, et gère autant de free-listes (chaînage des blocs disponibles). Ceci pour améliorer les performances par rapport à celle des implémentations standard de malloc et free. Notre fonction d'allocation : memoire, prend les mêmes arguments que malloc, mais notre fonction de libération : liberer, prend en argument l'adresse et la taille de l'objet à libérer (lorsqu'on libère un objet, nous connaissons sa taille). Nous avons donc implémenté ce système graphique avec le même paramétrage que notre ancien allocateur, et d’autre part avec le paramètrage standard.

[66]Les structures assoc sont des nœuds typés d’un arbre binaire. Le type contient le numéro du bit à tester dans les clefs, et suivant la valeur du bit, la recherche est poursuivie à droite ou à gauche. Les feuilles de l’arbre (formées avec les mêmes structures) contiennent une clef et la valeur associée.

[67]Sur une machine 32 bits

[68]Sur le Macintosh, l'alignement x vaut 2, les pointeurs sont toujours à des adresses paires.

[69]Les pointeurs vers le début des structures sont affichés, pas les éventuels pointeurs vers un champ d'une structure autre que le premier.

[70]Cela est possible, mais même si nous visualisons une centaine d'objets remplis de nombres aléatoires les chances sont approximativement de 100/2^32 par groupe de quatre octets consécutifs.

[71]Les rectangles peuvent être déplacés à la souris, ou se déplacer eux mêmes (cf. Actualisation dynamique  et élastique  ci-dessous).

[72]Nous avons pensé représenter le contenu des blocs par des couleurs différentes, mais nous avons finalement préféré une interaction volontaire (par exemple un double-clic sur un rectangle) pour afficher le contenu de l'objet sous forme héxadécimale. Les chaînes de caractères sont malgré tout repérables rapidement : en langage C elles sont terminées par un zéro. Comme nous avons la taille du bloc de mémoire, nous pouvons afficher les chaînes qui ne contiennent que des caractères imprimables, sous une forme lisible lors du double-clic.

[73]Nous pouvons colorer les flèches représentant les pointeurs en fonction de la taille de la structure d’origine et de l’offset du pointeur dans la structure. Ceci permet d’isoler (visuellement) les pointeurs d’un même type (les flèches car des doublets n’ont pas la même couleur que les flèches cdr).

[74]Nord, sud, est, ouest (Haut, bas, gauche, droite) et les quatre directions intermédiaires.

[75]Lorsqu'il n'y a pas d'événement utilisateur à traiter et qu'aucune autre tâche ne garde le contrôle du processeur,

[76]L'affectation des pointeurs dans une structure a lieu évidemment après son allocation, et, à sa libération, les pointeurs qu'elle peut encore contenir ne sont plus intéressants. Dans la construction dynamique d'un chaînage, l'actualisation des liens a toujours une structure de retard, si elle n'est faite qu'au moment de l'allocation ou de la libération.

[77] Avec un déplacement minimum unitaire : si la valeur absolue est 1, le déplacement sera

de 1.

[78]D’après une idée de Daniel GOOSSENS

[79]Sous MicroSoft Windows.

[80]A titre indicatif, un squelette d’application multifenêtre, pour un seul type de document, généré par VisualC++ occupe un mégaoctet (avec les références pour le débogage). Alors qu’une de nos applications sans fonctionalité occupe une cinquantaine de kilooctets.

[81]Destiné aux informaticiens non musiciens

[82]Dans son cours d’informatique musicale à l’universtité Paris 8

[83]Les termes introduits sont en gras dans tout le paragraphe

[84] ou sous-tonique, en mode mineur, sans l'altération.

[85]Nous verrons la définition de la tierce ci-après.

[86]Une modulation est un changement de ton.

[87] Cette numérotation 3-7, donne la composition des intervalles de l'accord en nombre de demi-tons. Ce n'est pas le chiffrage traditionnel employé en harmonie.

 

[88]Formée à partir des données relevées dans (MARCHAL 1966).

[89]Opposés aux intervalles mélodiques. Les intervalles harmoniques sont mesurés entre deux notes simultanées et non consécutives.

[90]Il y a une fonction Métronome par application, ce nom est conservé car le mode d’appel de la fonction reste le même, bien que les actions déclenchées dans le corps de la fonction soient spécifiques de l’application ou du module.

[91]Nous les nommons mémoires mélodiques dans la suite, la notation des durées des notes étant incluse implicitement.

[92]polyphonique

[93]Nous appelons longueur de la mélodie le nombre de notes de cette mélodie (et non la durée de celle-ci).

[94]Cette valeur arbitraire peut être modifiée.

[95]Si tant est que l’on puisse dissocier la programmation de la composition.

[96]Nous avons également utilisé des imprimantes de machines à calculer programmables. Dans ce cas, l’imprimante étant alimentée en continu par un rouleau de papier, la portée est écrite dans l’autre sens, les “|” pour les lignes et les “-” pour les barres de mesure.

[97]les registres sont des plages délimitant des groupes de hauteurs du grave à l’aigu.

[98]Dans la suite, nous parlerons d'instrumentistes, ou d'instruments, en englobant l'instrument qu'est la voix.

[99]Sauf, évidemment en cas de convention explicite donnée dans le texte.

[100]"On n'avance pas plus vite que la musique" Disait Michel SERRES à Pierre BOULEZ dans l'émission La marche du siècle 26 octobre 1994.

[101]Il existe des techniques pour faire varier la hauteur des notes, et obtenir des micro-intervalles sur la plupart des instruments (même avec un orgue, comme dans la pièce Ultrachromatischen de John CAGE). Mais, même si un violon permet de jouer toutes les hauteurs intermédiaires entre les notes des gammes classiques, les violonistes apprennent d'abord à jouer juste, c'est-à-dire dans la gamme chromatique ou dans un sous-ensemble de cette gamme.

[102]Les notes de la gamme, do, ré, mi, fa, sol, la, si.

[103]L’étendue

[104]ENCORE © 1993, logiciel de Passport Designs inc.

[105]Cette liste n’est pas exhaustive.

[106]Ceci est expliqué dans tous les solfèges.

[107]La même voix peut changer d'instrument.

[108]Le phrasé n'est utilisé actuellement que dans le module de génération.

[109]Le format A4 (21 X 29,7 cm), correspond aux possibilités de la plupart des imprimantes laser disponibles sur les ordinateurs personnels.

[110]Dans certaines périodes de la pièce tous les instruments physiques jouent (Tutti), alors que dans d'autre périodes, seuls les instruments à cordes jouents (Archi).

[111]Remarque : Les rondes, les pauses et les demi-pauses ne sont pas positionnées à l’emplacement correspondant à l’instant de leur départ (commes les autres signes)  mais au centre de l’espace correspondant à leur durée.

[112] MIDIScan for Windows, Version 1.0, Musitek, 410 Bryant Circle, Suite K, Ojai, CA 93023 (Avril 1993).

[113]L’implémentation de la fonction rand() du système que nous utilisons emploie cet algorithme, mais sans prendre a et b premiers.

[114](Cf. Article “Komponieren heisst programmieren” de Von Peter Révai, Computerworld, 3 juil. 1995, N°27/95 )

[115]Nous considérons ici que la musique dite expérimentale est ainsi qualifiée car  les œuvres de ce type sont le résultat d’expériences : elles sont le reflet d’une recherche, et non pas le résultat de l’application d’une théorie.

[116]L’opération d’import peut également être faite depuis un fichier, mais cette solution n’est pas pratique : elle nécessite beaucoup de manipulations.

[117]Des problèmes nouveaux se posent, par exemple pour l’attribution automatique d’une couleur aux flèches en fonction de la taille de la structure de départ et de l’offset du pointeur. En effet, si l’on utilise une formule quelconque pour calculer ses couleurs, elles risquent de ne pas être lisibles d’une part (par exemple trop proche de la couleur du fond, ou des cellules), et d’autre part, les couleurs générées doivent pouvoir être clairement distinguées les unes des autres pour devenir pertinantes.

[118]Nous avons réalisé, dans le domaine de l’impression textile, un système de filtrage d’image pour générer les films correspondant à chaque encre utilisée pour imprimer l’image. Le filtrage Jaune, Magenta, Cyan, et Noir n’étant qu’un cas particulier, utilisé pour les impression sur papier principalement. Les impressions textiles utilisent en général une dizaine d’encres de base.

[119]Ceci à été initié par le système de représentation temporel de MIDIShare.

[120]Sauf dans le cas des sons échantillonnés : un échantillon pouvant représenter 1/44100 de seconde, et, lors de la simulation des couplages élastiques, plusieurs unités de temps de simulation correspondent à un échantillon.

[121]Des auteurs tels BARBAR, BEURIVE et DESAINTE-CATHERINE (BARBAR 1995), utilisent des grammaires formelles pour décrire les structures musicales et étudient la propagation des propriétés des éléments dans ces grammaires. Les grammaires sont également utilisées pour la reconnaissance de structures musicales imprimées (COUASNON 1995), ou encore pour la génération de rythmes (JONES 1981).

[122]en pourcentage de chances selon le type.

[123]Lors de la création d’un contexte, l’index est initialisé à zéro.

[124]Il serait préférable de tirer une seule fois le nombre de répétitions (quand l’index vaut 0, c'est-à-dire au début de l’exécution) puis de décompter jusqu’à ce que toutes les exécutions du  nœud répété soit faites. Dans l’écriture actuelle de la fonction, le nombre de répétitions effectives est probablement plus proche de mini que de maxi.