Belanger These Udem2008
Belanger These Udem2008
Belanger These Udem2008
par
Olivier Bélanger
Faculté de musique
Novembre 2008
présentée par:
Olivier Bélanger
Cette thèse se divise en quatre parties. Les trois premiers chapitres concernent
les outils, développés au cours des cinq dernières années, qui ont été utilisés pour
la composition du Cycle des voix. Il s’agit de deux modèles de synthèse en mode
source-filtre et d’un environnement de programmation musicale. Le premier cha-
pitre explique la démarche de création d’un modèle de la voix chantée, ainsi que les
avancements apportés à un domaine déjà largement développé. Le second chapitre
élabore sur les analyses acoustiques effectuées sur les sons provenant d’un didjeridu
et sur la construction d’un modèle virtuel. Le troisième chapitre concerne le logiciel
de programmation musicale Ounk, alliant la puissance du langage de programma-
tion Python et la qualité du moteur audio Csound. Dans ce chapitre, sont présentés
les objectifs qui ont poussé au développement d’un nouvel environnement de pro-
grammation musicale, la démarche utilisée ainsi que les principales caractéristiques
du logiciel. La quatrième partie élabore sur les intentions musicales, les contraintes
imposées ainsi que sur les stratégies adoptées lors de la composition de l’oeuvre
musicale le Cycle des voix.
This thesis is divided in four parts. The first three chapters present the tools,
developed over the past five years, that were used for the composition of the Cycle
of Voices. These tools are two source-filter synthesis models and an audio scripting
environment for musical signal processing and composition. The first chapter ex-
plains the chosen approach for the development of a singing voice synthesis model
and how it contributes to a well developed domain. The second chapter develops
on acoustic analysis of sounds produced by the didjeridu and on the development
of a virtual model. The third chapter is concerned with Ounk, a software pro-
gram for music programming, combining the power of the programming language
Python and the qualities of the Csound audio engine. In this chapter, the goals
that lead to the development of a new musical scripting environment, some design
decisions and the main features of the software are explained. The fourth chapter
discusses musical intentions, imposed constraints and some strategies developed for
the composition of the pieces the Cycle of Voices.
DÉDICACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv
REMERCIEMENTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v
RÉSUMÉ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vi
ABSTRACT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2.2 Synthèse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.2.1 Source d’excitation : vibration des lèvres . . . . . . . . . . . 42
2.2.2 Modélisation de la cavité buccale . . . . . . . . . . . . . . . 44
2.2.3 Effets spéciaux (excitations externes) . . . . . . . . . . . . . 44
2.2.4 Modes de résonance du tuyau . . . . . . . . . . . . . . . . . 45
2.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
CHAPITRE 3 : OUNK . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.1 Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.2 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.3 Particularités du langage . . . . . . . . . . . . . . . . . . . . . . . . 50
3.3.1 Attributs audio . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.3.2 Gestion des canaux de sortie . . . . . . . . . . . . . . . . . . 51
3.3.3 Gestion du temps . . . . . . . . . . . . . . . . . . . . . . . . 52
3.3.4 Utilisation de la liste comme valeur de paramètre . . . . . . 53
3.3.5 Passage des valeurs de contrôles . . . . . . . . . . . . . . . . 54
3.3.6 Passage des échantillons audio . . . . . . . . . . . . . . . . . 55
3.3.7 Communication à l’aide du protocole Open Sound Control . 56
3.3.8 Rendu en temps réel ou différé . . . . . . . . . . . . . . . . . 57
3.3.9 Gestion des processeurs multiples . . . . . . . . . . . . . . . 58
3.3.10 Gestion des répertoires . . . . . . . . . . . . . . . . . . . . . 59
3.4 Environnements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.4.1 Instrument MIDI . . . . . . . . . . . . . . . . . . . . . . . . 60
3.4.2 Step sequencer . . . . . . . . . . . . . . . . . . . . . . . . 62
3.4.3 Instrument Python . . . . . . . . . . . . . . . . . . . . . . . 64
3.4.4 Boucleur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.4.5 Instrument «Csound» . . . . . . . . . . . . . . . . . . . . . 67
3.4.6 Interface graphique . . . . . . . . . . . . . . . . . . . . . . . 69
xi
CONCLUSION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
SOURCES DOCUMENTAIRES . . . . . . . . . . . . . . . . . . . . . . 83
LISTE DES FIGURES
La synthèse vocale demeure aujourd’hui un des rares types de synthèse qui n’a
pas encore trouvé de solution idéale. Une synthèse de la voix chantée de bonne
qualité, légère en puissance de calcul, en espace disque et en mémoire vive, capable
de synthétiser des phrases complètes n’existe pas encore. La synthèse de la voix
chantée développée au cours de ce projet est orientée spécialement pour les compo-
siteurs en ce qu’elle offre une très bonne qualité sonore tout en étant peu coûteuse
et extrêmement simple à manipuler. Une avancée au niveau de la production de
phonèmes incluant des consonnes a été apportée, spécialement en ce qui concerne
les consonnes plosives.
Un modèle de synthèse du didjeridu, tout en étant relativement simple de
conception, constitue un instrument de traitement possédant une sonorité excep-
tionnelle. De par sa forme conique, le didjeridu crée une suite de modes de résonance
ayant un rapport inharmoniques entre eux, permettant de générer des filtres très
complexes tout en restant simple à manipuler. Bien que la théorie sur l’acoustique
du didjeridu soit facilement accessible, aucun modèle n’est actuellement disponible
dans les environnements de composition et de synthèse sonore. Le modèle qui a
été développé au cours de ce projet offre une très bonne qualité sonore et des pa-
ramètres de contrôle simples, reliés aux principes physiques et aux modes de jeu
de l’instrument.
Les modèles de synthèse décrits ci-dessus ont d’abord été implémentés dans
l’environnement Max/MSP, qui s’est avéré inefficace à plusieurs niveaux. Durant
la composition des pièces de ce projet est né le besoin d’un environnement de
programmation plus versatile et puissant au niveau de l’algorithmie, de meilleure
qualité sonore et permettant un contrôle simplifié des modèles de synthèse. Le
logiciel de programmation musicale Ounk a été développé pour répondre à ces
besoins. Alliant la puissance du langage de programmation Python à la qualité
2
Fig. 1.1 – Schéma de production d’un signal vocal voisée. (Everest, 1989)
Fig. 1.2 – Schéma de production d’un signal vocal non-voisé. (Everest, 1989)
5
1.2.1 Le Voder
En 1939, dans les laboratoires de Bell, Homer Dudley met au point le Voder,
une machine servant à modéliser le signal de la voix. Comme pour beaucoup des
recherches dans le domaine de la synthèse vocale, le Voder était conçu pour réduire
la quantité de signal transmis sur les lignes de téléphone.
Le Voder est un instrument qui doit être manipulé par un technicien haute-
ment entraı̂né. Dix touches de clavier servent à contrôler l’amplitude de dix filtres
passe-bande, responsables du contenu spectral du signal, c’est-à-dire des formants
de la voix. Un levier situé à la hauteur du poignet permet d’alterner entre un si-
gnal d’excitation périodique (train d’impulsions) et un signal d’excitation aléatoire
(bruit blanc). Une excitation périodique permet de recréer les voyelles et certaines
consonnes tandis qu’une excitation aléatoire permet de reconstituer les fricatives,
telles que le [f], le [s] et le [ch]. La fréquence du signal périodique est contrôlée par
une pédale, permettant de créer des inflexions de voix réalistes (Bilmes, 2003). Les
expérimentations de Homer Dudley sur les principes du vocoder1 ont grandement
1
Extension du Voder basée sur l’analyse du son vocal.
6
La synthèse par forme d’onde formantique a été développée au milieu des années
70 par Xavier Rodet, à l’IRCAM (Rodet, 1984). Le principe consiste à générer des
flux de grains dont le contenu spectral correspond aux formants de la voix.
Les grains sont générés en appliquant une enveloppe d’amplitude sur un signal
de type sinusoı̈dal, enregistré dans une table, produisant ainsi une sinusoı̈de amor-
tie. Le signal obtenu est un spectre harmonique dont la fréquence fondamentale
correspond à la fréquence de génération des grains et la largeur de bande à l’action
combinée de la fréquence centrale et de la forme de l’enveloppe d’amplitude. Entre
trois et cinq flux de grains FOF peuvent être superposés afin de reproduire les
formants d’un son de voyelle. Cette technique permet d’obtenir une qualité sonore
remarquable et offre l’avantage de contrôler la synthèse avec des paramètres très
évocateurs de l’instrument réel, tels que la fréquence fondamentale et l’emplace-
ment des formants dans le spectre (Rodet et al., 1984).
Fig. 1.4 – (a) Signal temporel d’une FOF. (b) Le spectre d’amplitude obtenu.
(Iturbide, nil)
7
Le modèle de conduit vocal mis au point par John Kelly et Carol Lochbaum est
constitué d’une série de tuyaux recréant la forme du conduit vocal. Leurs travaux
furent publiés sous forme d’article paru en 1962.
Fig. 1.5 – Modèle acoustique d’un conduit vocal, constitué d’une séquence de
sections de cylindre et modèle du filtre numérique correspondant, d’après Kelly et
Lochbaum, 1962. (Smith, 2005).
Ce modèle est en quelque sorte l’ancêtre des modèles physiques par guides
d’ondes, et a été utilisé pour synthétiser la célèbre reprise synthétisée de la chan-
son «Bicycle built for two», mise en musique par Max Mathews. Cette pièce est
probablement le premier exemple sonore, toutes méthodes confondues, d’un modèle
physique de synthèse de la voix chantée (Smith, 2005).
1.2.4 SPASM
veau des contrôles. L’excitation est une combinaison d’un signal harmonique (train
d’impulsions) et d’un signal aléatoire (bruit blanc). Le contrôle des transforma-
tions de chaque section du conduit vocal permet de synthétiser un grand nombre
de phonèmes, notamment des voyelles et des consonnes nasales, grâce à la jonction
entre la cavité buccale et le conduit nasal.
La bifurcation du conduit vocal vers le conduit nasal située au voile du palais
peut être modélisée avec une jonction à trois passages. Une partie de l’énergie en
provenance de la glotte sera dérivée vers la cavité nasale, une autre partie continuera
vers les lèvres et le reste sera réfléchi et retournera vers la glotte (Cook, 1991).
20
10
0
Tp Tc To
0 0.005 0.01 0.015
Time (sec)
Ta
derivative glottal wave
0
Tp Te Tc To
Amplitude
!0.5
!1
!Ee
0 0.005 0.01 0.015
Time (sec)
le souffle, l’effort et l’articulation peuvent être spécifiés via une interface de contrôle
et facilement reliés aux paramètres des filtres générant la source d’excitation.
1.3 Objectifs
Fig. 1.8 – Schéma de base d’un modèle de synthèse de la voix en mode source-filtre.
Fig. 1.11 – Sonagramme d’une voyelle synthétisée où la raucité a été introduite à
la mi-parcours.
Le filtrage produit par le conduit vocal est simulé par un banc de filtres passe-
bande en parallèle, reproduisant des pics d’amplitude dans le spectre, que l’on
nomme les formants, caractéristiques du signal vocal. Afin d’améliorer la précision
des filtres et la qualité sonore du signal généré, chacun des formants est modélisé
par une cascade de trois filtres résonants du second ordre. Cette chaı̂ne de filtres
passe-bande donne une pente de coupure plus nette, éliminant ainsi les composantes
spectrales indésirables. Csound permet d’obtenir cette cascade de filtres résonants
16
à l’intérieur d’un seul opcode3 , pour lequel on spécifie le nombre de filtres désirés
dans la série. En plus d’être extrêmement stable, cet opcode est plus léger en
temps de calcul qu’une série de filtres indépendants, puisque le calcul des vecteurs
d’échantillons audio se fait à l’intérieur de la mémoire cache du processeur. Trois
paramètres sont nécessaires à la définition d’un formant : la fréquence centrale,
l’amplitude et la largeur de bande. Ces paramètres ont été obtenus par l’analyse
d’échantillons de voyelles prononcées par des chanteurs et chanteuses de tessitures
différentes, ainsi que par des ajustements à l’écoute, et sont mémorisés dans des
tables à l’intérieur du modèle. Selon le registre et la voyelle demandée, le modèle
ira récupérer les valeurs des formants appropriées. Pour obtenir des voyelles aux
timbres légèrement différents chaque fois qu’une note est chantée, une variation
d’environ 2% est appliquée à la fréquence centrale des formants, éliminant ainsi
l’effet robotique d’une voyelle qui serait répétée avec exactement la même forme de
conduit vocal.
Cinq formants sont définis pour les quinze principales voyelles françaises de
l’alphabet phonétique international (voir figure 1.12). Les deux premiers formants
jouent un rôle important dans la perception de la voyelle produite. Le troisième et le
quatrième formants, en combinaison avec les deux premiers, aident à la perception
et à la catégorisation de certaines consonnes (Delattre et al., 1955, 1958). Le rôle
du cinquième formant consiste à ajuster la qualité du timbre de la voix. Ce dernier
pourrait être éliminé sans perdre l’intelligibilité du phonème prononcé.
Un deuxième groupe de filtres peut être utilisé afin de simuler la cavité na-
sale. Lorsqu’une voyelle ou une consonne nasale est produite, des annulations de
fréquence sont modélisées par l’ajout de filtres à réponse impulsionnelle finie créant
3
resonx. Opcode est le nom donné aux opérateurs dans le langage Csound.
17
Fig. 1.12 – Les voyelles telles que définies dans le modèle représentées sur le triangle
en fonction du point d’articulation et de l’ouverture de la bouche.
1.6.2 Registres
Selon la tessiture de la voix qui produit une sonorité de voyelle, les fréquences
centrales des formants ne seront pas situées aux mêmes fréquences. Les rapports
de fréquences centrales de formants pour une voyelle donnée seront aussi différents
selon les registres. On ne peut donc pas tout simplement étirer ou contracter une
configuration de base des fréquences centrales en fonction de la tessiture (Martin,
2000). Des recherches ont aussi démontré qu’il est possible de catégoriser les re-
gistres en fonction de l’emplacement des formants pour une fréquence fondamentale
fixe (Coleman, 1971). Quatre registres sont définis dans le modèle : basse, ténor,
alto et soprano. Pour chaque registre, des tables de paramètres sont mémorisées
pour les valeurs de fréquences centrales, d’amplitudes et de largeurs de bande. Le
modèle utilisera les tables correspondant à la tessiture de voix choisie par l’utilisa-
teur.
Registre F1 F2 F3 F4
basse 400 750 2400 2600
ténor 360 770 2530 3200
alto 420 850 3040 4160
soprano 500 950 3240 4160
Tab. 1.1 – Table des fréquences des formants pour la voyelle [o] en fonction du
registre.
Un problème particulier se produit lorsqu’une note très aiguë est produite dans
le registre de soprano. Si la fréquence fondamentale est plus élevée que la fréquence
centrale du premier formant, il y aura moins d’énergie dans ce formant, créant
19
4
Voir tableau des trajectoires en annexe I.
20
L’équation 1.1 présente la formule utilisée pour définir une trajectoire d’un
point de départ f1 , correspondant à la fréquence centrale initiale du formant de la
consonne, à un point d’arrivé f2 , correspondant à la fréquence du formant de la
voyelle. α représente le coefficient de courbure et N le nombre total d’échantillons
dans la transition.
1 − e−αn/N −1
F (n) = f1 + (f2 − f1 ) (1.1)
1 − e−α
Les transitions de formant, lors de la production d’une consonne plosive, sont
très rapides, de 30 à 80 ms de durée. Le système auditif est extrêmement sensible
à ce type de transitions, qui constituent un des principaux indices de perception
des consonnes plosives (Blumstein and Stevens, 1979, Jackson, 2001). Deux autres
indices participent à la reconnaissance des consonnes : la présence de bruit et le
VOT5 . Une brève impulsion de bruit est toujours présente lors de la production
des consonnes plosives non-voisées telles que [p], [t] ou [k]. Le VOT, c’est-à-dire un
court instant de silence entre le bruit et le départ de la note, devra être ajusté de
façon très précise en fonction de la consonne prononcée. Ces paramètres sont aussi
mémorisés dans des tables et appelés au besoin.
La figure 1.13 illustre un exemple de trajectoires de fréquences centrales des
trois premiers formants pour les syllabes [da] (en bleu) et [ba] (en rouge). Les
trajectoires démarrent sur les valeurs définies pour la consonne et se déplacent
rapidement vers les valeurs de formants de la voyelle [a], puis gardent ces valeurs
jusqu’à la fin de la note. La forme du conduit vocal diffère selon que l’on produit
un [b] ou un [d], ce qui a pour effet de modifier le point de départ des transitions
de formant. On constate que la différence entre les deux consonnes réside dans
le point de départ des deuxième et troisième formants. Alors que dans les deux
cas, la fréquence centrale du premier formant part d’une valeur plus basse que la
5
Voice Onset Time, voir page 15 pour la description.
21
fréquence du formant de la voyelle, dans le cas du [d], le point de départ des deux
autres formants se situe au-dessus de la fréquence du formant de la voyelle.
Fig. 1.13 – Trajectoires des trois premiers formants pour les syllabes [da] et [ba].
Selon une étude sur les indices de perception des consonnes plosives (Delattre
et al., 1955), il est possible de réduire la base de données nécessaire à la définition
des trajectoires de formant en assignant un point de départ commun pour toutes
les consonnes ayant le même point d’articulation, indépendamment de la voyelle
qui suit. Par exemple, les consonnes labiales [b], [p] et [m] sont toutes articulées au
niveau des lèvres et peuvent donc toutes être synthétisées en démarrant la transition
au même locus acoustique (même point de départ). Les consonnes alvéolaires [d], [t]
et [n], qui sont articulées avec la langue contre le palais, auront elles aussi le même
locus. La théorie du locus acoustique fonctionne particulièrement bien pour situer
le point de départ du deuxième formant des consonnes car c’est celui qui est le plus
influencé par la forme de la bouche. Une deuxième étude (Delattre et al., 1958) a
22
démontré que cette théorie est plus difficilement applicable au troisième formant.
Des expérimentations avec le modèle tendent à corroborer cette étude. Afin de
respecter la théorie du locus acoustique, les trajectoires d’amplitude doivent être
précisément ajustées en introduisant une période de silence au début de la transition
comme illustré sur la figure 1.14.
cale. Une syllabe ne prend son sens qu’en fonction de la syllabe qui l’a précédée et de
celle qui la suit. Généralement, il y a une continuité sonore entre deux sons articulés.
Reproduire ce phénomène est essentiel pour la génération de phrasés réalistes. Il est
possible, dans ce modèle, de spécifier qu’un événement doit être lié à l’événement
suivant, en lui donnant une durée négative (normalement exprimée en seconde).
Lorsque la prochaine note est appelée, le modèle n’exécute pas la phase d’initiali-
sation et débute les trajectoires à partir de l’endroit où l’événement précédent était
rendu (les valeurs de formant correspondant à une voyelle par exemple).
Fig. 1.15 – Une trajectoire typique de liaison entre deux événements pour un seul
formant.
La figure 1.15 illustre une trajectoire typique pour la fréquence centrale d’un seul
formant, débutant sur l’état stable d’une voyelle, suivi d’une syllabe comportant
une consonne plosive. La partie A correspond à la chute de la voyelle précédente,
d’une durée d’environ 30 ms. La partie B représente un temps de silence ou une
très faible résonance durant la production de la consonne (très important pour la
perception des consonnes plosives), juste avant l’attaque de la nouvelle note. Cette
durée peut varier de 20 à 100 ms selon la consonne désirée. La partie C corres-
pond à la trajectoire de formant de la consonne choisie et la partie D à la tenue
stable définie par les paramètres de la voyelle ciblée. Tous les paramètres de for-
mants (fréquence centrale, amplitude et largeur de bande) suivent des trajectoires
similaires, générées en fonction de la consonne et de la voyelle à synthétiser.
24
Le didjeridu étant un tuyau fermé à un des deux bouts, les modes de résonance
suivent une série composée des harmoniques impairs. Par contre, dû à la forme
conique du tuyau, le premier mode est particulièrement élevé en fréquence (Flet-
cher et al., 2001b). Comme le premier mode demeure la fondamentale perçue, le
deuxième mode paraı̂t considérablement au-dessous de l’intervalle de douzième cor-
respondant au troisième harmonique de la série du fondamental.
Fig. 2.1 – Dimensions dont dépend l’accord d’un tuyau de forme conique.
suit :
L0 = L + 0.3 d2 (2.2)
c
fn = (n − 0.5) (1 + 1) (2.3)
4L0
c
= (n − 0.5) 0 (2.4)
2L
Le tableau 2.2 illustre les fréquences théoriques d’un tuyau cylindrique d’une
longueur de 0,6 m, fermé à une extrémité, pour c = 340 m/s :
fn
mode (n) (fn =) fréquence (Hz) rapport f0
1 c/4L 141.66 1
2 3c/4L 425 3
3 5c/4L 708.33 5
4 7c/4L 991.66 7
5 9c/4L 1275 9
Tab. 2.2 – Calcul de la fréquence des modes d’un cylindre fermé à une extrémité.
Cette théorie est confirmée par un calcul théorique, effectué avec la formule
déterminant les résonances du didjeridu (Eq. 2.1), pour deux cônes ayant la même
longueur et le même diamètre d’entrée mais des diamètres de sortie d2 différents.
Pour un amincissement du cône, alors que la fréquence centrale du premier mode
est considérablement abaissée, plus on avance dans l’ordre des modes, moins la
différence est grande. En changeant l’ouverture de sortie pour que le cône se rap-
proche du cylindre, on constate que les modes supérieurs sont en rapport presque
juste avec le fondamental (Bélanger and Traube, 2005). Ceci implique que la qualité
28
différence
modes fréquence i1 fréquence i2 Hertz cents
1 84.5 Hz 72.67 Hz 11.83 261
2 203 Hz 197.7 Hz 5.3 46
3 329.7 Hz 326.4 Hz 3.3 17
4 458.2 Hz 455.8 Hz 2.4 9
5 587.3 Hz 585.4 Hz 1.9 5
6 716.65 Hz 715.1 Hz 1.55 3
7 846.2 Hz 844.9 Hz 1.3 2.6
8 975.8 Hz 974.7 Hz 1.1 2
9 1105.5 Hz 1104.5 Hz 1 1.5
10 1235.2 Hz 1234.3 Hz .9 1.25
Tab. 2.3 – Influence de la conicité sur la note fondamentale d’un cône tronqué.
Fig. 2.2 – Les lignes verticales indiquent l’emplacement des harmoniques pour
une série dont le fondamental serait le premier mode du tuyau. On constate que les
modes supérieurs sont de plus en plus graves, par rapport aux harmoniques impairs
théoriques.
Ceci étant dit, précisons que le spectre du didjeridu est strictement harmonique,
car la source d’excitation, c’est-à-dire la vibration des lèvres, est harmonique. Les
modes de résonance du tuyau ne font que filtrer le signal émis par la source. Le
fait que les modes supérieurs du tuyau ne soient pas harmoniquement justes influe
seulement sur la puissance de certains harmoniques, et non sur la justesse de ces
harmoniques. Si le second mode est excité à l’instar du fondamental, il apparaı̂t
avec sa propre série harmonique (Fletcher, 1996). En fait, les modes de résonance
du tuyau exercent une influence particulière au moment des transitions, là où se
trouve le bruit, car c’est aux moments où l’excitation est constituée de bruit que
l’on entend réellement les multiples résonances de l’instrument. À l’aide d’une FFT
à court terme aux fenêtres très larges (4096 échantillons), afin d’obtenir une bonne
résolution fréquentielle, on peut vérifier que le spectre d’un bourdon sur un didje-
ridu en ré est bel et bien harmoniquement juste. Sur le sonagramme de la figure
2.3, chaque ligne horizontale représente un harmonique du signal et la puissance
de l’harmonique est indiquée par le niveau de gris de la ligne (plus elle est foncée
30
sans embouchure, le musicien appuie sa propre bouche pour fermer la plus petite
extrémité de l’instrument, et fait vibrer ses lèvres, qui agissent comme une valve qui
s’ouvre et se ferme périodiquement, pour créer le signal d’excitation. Il exerce une
pression, avec son souffle, sur ses lèvres, et lorsque la pression dépasse un certain
seuil, déterminé par la tension musculaire des lèvres, qui elle-même dépend de la
hauteur de la note jouée, elles entrent en vibration et génèrent un signal oscillatoire,
presque sinusoı̈dal, qui fait vibrer la colonne d’air de l’instrument. Le joueur accorde
la tension de ses lèvres pour que la vitesse de vibration ainsi créée soit proche de
la fréquence du premier mode du tuyau. S’il veut exciter le second mode, il doit
augmenter la tension de ses lèvres, contraignant ainsi la pression de son souffle à
dépasser un seuil plus élevé. C’est pourquoi il ne peut s’attarder longtemps sur les
modes supérieurs car la pression à fournir est très exigeante. Voici la formule qui
permet de déterminer, en fonction de la pression du souffle et de la résistance des
lèvres et de l’instrument, la forme du flux d’air qui vient exciter la colonne d’air :
0 p2
p0 R3
U= − (2.5)
R (a0 + a sin(2πf t))2
où p0 représente la pression du souffle du musicien, et R la résistance à l’entrée
de l’instrument. a et a0 sont des constantes d’amplitude de la fonction sinusoı̈dale
(Fletcher, 1996). L’onde générée par la vibration des lèvres est de type sinusoı̈dal
lorsque la pression dépasse tout juste le seuil où les lèvres entrent en vibration.
Plus la pression est forte, plus la forme d’onde tend vers le trapèze, la partie large
du trapèze représentant le temps où les lèvres sont complètement fermées. Des
observations effectuées à l’aide d’un stroboscope sur la vibration des lèvres d’un
joueur de didjeridu, montrent que les lèvres sont complètement fermées durant une
grande fraction de chaque cycle (Fletcher et al., 2001b).
Une forme d’onde trapézoı̈dale contient beaucoup d’énergie aux harmoniques
supérieurs, ce qui permet à un bon joueur d’utiliser les variations de pression pour
32
Fig. 2.4 – Spectre des 100 premières millisecondes. Malgré le filtrage sélectif du
tuyau, on constate l’instabilité de la vibration.
Le fait est qu’un musicien qui contrôle bien son jeu peut, à n’importe quel
moment, créer ce type de variations en modifiant la fréquence de vibration de ses
lèvres pour générer de nouvelles combinaisons spectrales. C’est ce qui crée tout
l’intérêt du didjeridu : la gamme des effets spéciaux est très vaste et relativement
facile à contrôler. Comme l’excitation et le conduit vocal sont intimement liés l’un
33
toutes les modifications qu’il sait y apporter, provoquent des changements continus
dans le spectre acoustique de la source. Les formants sont plus prononcés dans le
cas du didjeridu que dans celui des cuivres car l’embouchure des trompettes, tuba
et autres, forme une cavité tampon entre la bouche et l’instrument et amoindrit
les pics formantiques. La voix n’est pas seulement un simple résonateur, mais un
générateur de sons complexes permettant une grande variabilité de contrôle. Les
cris, la parole et le chant modifient la colonne d’air de façon extrêmement subtile
et offrent une gamme d’effets spéciaux très intéressants lorsqu’utilisés en jouant
du didjeridu. L’oscillation des lèvres en soit ne provoque qu’un son constant sans
grande variation, mais lorsque le musicien utilise des sons vocaux tout en jouant,
une modulation d’amplitude s’opère entre la voix et l’excitation non linéaire des
lèvres et celle-ci est ensuite injectée dans l’instrument. La forme d’onde de l’ex-
citation est alors beaucoup plus complexe, comportant une grande quantité de
variations, le tout filtré par le résonateur qu’est le didjeridu.
Fig. 2.6 – Spectres d’amplitude d’un bourdon avec une voyelle prononcée.
Les nombres en petits caractères représentent les formants théoriques lorsqu’ils
coı̈ncident avec les maxima (caractères gras) observés à l’analyse.
f1 = 2.5f2
f1,2 = f1 − 2f2
= 2.5f2 − 2f2
= 0.5f2
ments, si ce n’est que de renforcer la région du spectre où se trouve cette harmo-
nique. Par contre, si le musicien possède une bonne maı̂trise de sa voix, il peut
s’éloigner légèrement de la note fondamentale, ce qui fait varier intensément le
contenu spectral du son, puisque le musicien modifie sa colonne et s’accorde sur
des fréquences très différentes du fondamental de l’instrument. C’est une autre
façon de provoquer des phénomènes de battements.
La figure 2.8 représente l’analyse spectrale des quatre régions indiquées sur le
sonagramme de la figure 2.7. La région A correspond à la partie stationnaire, le
bourdon juste avant les variations. En B, nous avons la montée lorsque le joueur
commence à chanter dans l’instrument. C et D nous donnent deux spectres obtenus
lorsque le joueur stabilise sa voix sur une note qui n’est pas celle du drone. Cette
analyse a été effectuée sur un didjeridu accordé en La.
Fig. 2.7 – On constate une montée et une descente lorsque la voix du musicien se
détache de la fréquence de l’excitation à laquelle elle vient s’ajouter. A = partie
stationnaire. B = montée de la note chantée. C et D = parties stationnaires avec
chant.
37
où le didjeridu n’agit pratiquement plus, c’est-à-dire les hautes fréquences. Les bons
joueurs de didjeridu respirent de façon régulière pour marquer rythmiquement leur
musique. Le sonagramme de la figure 2.9 démontre bien ce qui se passe. En se
contractant, les joues diminuent le volume de la cavité buccale, lui conférant ainsi
une fréquence de résonance plus élevée, ce qui vient renforcer certains harmoniques
au moment de la respiration.
Fig. 2.9 – Rythme respiratoire aux fréquences élevées et variations d’énergie aux
différents harmoniques au moment de la respiration.
Fig. 2.10 – Excitation des modes supérieurs : la note fondamentale reste toujours
présente mais l’énergie se déploie entre les harmoniques 7 et 30.
2.1.2.6 Cris
des résonances normalement excitées par la vibration des lèvres. Ils confèrent aussi
beaucoup d’énergie aux harmoniques déjà présents, ce qui se traduit par une montée
d’intensité spectaculaire. Le sonagramme de la figure 2.12 illustre les changements
dans le spectre du didjeridu lorsque le musicien pousse un cri dans l’instrument.
Fig. 2.12 – Crier dans le didjeridu tout en produisant un bourdon constant pro-
voque une montée subite d’énergie dans le registre médium (500 à 2000 Hz), ainsi
qu’une nouvelle zone d’énergie dans les hautes fréquences, qui apparaı̂t uniquement
lorsque l’excitation est très puissante.
Fig. 2.13 – Spectre d’amplitude du cri sur la voyelle [a] de la figure 2.12. On
remarque des formants bien prononcés.
À l’écoute du son produit par ce cri dans le didjeridu, on peut avoir une forte im-
pression que le joueur prononce la voyelle [a]. Effectivement, les formants théoriques
42
pour la voyelle [a], chantée par un ténor francophone, se trouvent autour de 760,
1450, 2600 et 3300 Hertz. Ce qui correspond aux formants observés sur le spectre
d’amplitude de la figure 2.13.
2.2 Synthèse
Fig. 2.15 – Train d’impulsions généré par les lèvres. En haut, la forme d’onde
générée et en dessous, le spectre d’amplitude correspondant. De gauche à droite,
pour des valeurs de pression de 1, 4 et 15 sur une échelle de 1 à 20.
44
maintenant développé.
" 2 #
π 2 d1 8f0 L0
d2 = d1 + −1 −1 (2.6)
16 c
2.3 Conclusion
OUNK
3.1 Objectifs
La création du logiciel Ounk (Bélanger, 2008) a été motivée par le besoin d’un
environnement de programmation musicale offrant une excellente qualité sonore ac-
compagnée d’un langage de haut niveau, simple et efficace. L’environnement doit
permettre à l’utilisateur d’arriver rapidement au résultat sonore souhaité. Le lan-
gage Csound1 comme moteur audio fut choisi pour plusieurs raisons. Premièrement,
Csound est un langage mature ayant une communauté de programmeurs très active.
En plus d’offrir une très large librairie d’opérateurs, la précision de l’interpolation
produit un rendu sonore d’excellente qualité. Csound permet aussi de calculer les
échantillons en temps réel ou en temps différé, en créant un fichier son sur le disque
dur, ce qui permet de construire des structures sonores dont la complexité n’est
pas limitée à la puissance du processeur.
Par contre, la syntaxe du logiciel Csound est un peu désuète et rébarbative.
Ounk nécessitait une syntaxe moderne, claire et efficace pour l’écriture des scripts.
Le choix du langage de programmation Python2 s’est imposé principalement pour
la simplicité de sa syntaxe, sa librairie de fonctions riche et variée, le fait qu’il
est multiplateforme et les facilités d’interfaçage qu’il fournit. Développé au début
des années 90, par Guido Van Rossum, Python est un langage dit de haut niveau
relativement jeune, en constant développement et bénéficiant du soutien d’une
communauté très active. Depuis quelques années, il est de plus en plus utilisé
dans le monde de la programmation de logiciels et d’interfaces web. Python est un
excellent langage pour construire des algorithmes puissants et versatiles.
1
http ://www.csounds.com
2
http ://www.python.org
49
3.2 Structure
Csound doit être configuré en fonction du système sur lequel il est installé afin
de fonctionner correctement. Il faut spécifier, entre autre, l’interface audio qui doit
être utilisée. D’autres paramètres importants sont la fréquence d’échantillonnage
et la fréquence de la boucle de contrôle qui indique à quel taux les données de
contrôle seront rafraı̂chies. Un fichier de configuration peut être édité afin d’opti-
miser les performances en fonction du système utilisé. Ce fichier est accessible via
le menu ’File’, puis ’Preferences...’. Des valeurs par défaut sont fournies en fonction
des différentes plates-formes. Il est aussi possible de modifier la configuration audio
localement à l’intérieur d’un script. Les valeurs par défaut ne seront pas modifiées
et le comportement des autres scripts ne sera donc pas affecté. Les fonctions setAu-
dioAttributes et setAudioDevice permettent de modifier localement la configuration
audio de Csound.
setAudioAttributes(samplingrate = 48000,
controlrate = 4800,
softbuffer = 256,
hardbuffer = 512,
audioDriver = ’jack’)
setAudioDevice(inumber = ’’, onumber = 3)
3
Le paramètre «pan» est présent pour toutes les fonctions générant une sortie audio.
52
setGlobalDuration(60)
playSound(sound = ’baseballmajeur.aif’, loop = True)
for i in range(100):
start = random.randint(0,59)
pitch = random.randint(250,4000)
sine(pitch = pitch, starttime = start, duration = .25)
playSound(sound=’/home/olipet/sons/baseballmajeur.aif’, loop=True)
Ainsi, pour faire jouer en même temps tous les sons contenus dans un dossier,
on exécuterait le code suivant :
Une fonction qui reçoit une liste comme valeur d’un de ses paramètres créera
autant d’instances de l’instrument qu’il est nécessaire pour calculer le rendu sonore.
Si, pour une même fonction, plus d’un paramètre reçoit une liste en entrée, la plus
longue liste sera utilisée pour générer le nombre d’instances nécessaires. Les valeurs
des listes plus courtes seront utilisées dans l’ordre, avec bouclage lorsque la fin de
la liste est atteinte. Utiliser des listes de différentes longueurs pour les paramètres
d’une fonction produira un résultat sonore riche et varié puisque les combinaisons
de paramètres seront différentes pour chaque instance de l’instrument.
Pour toutes les fonctions générant des échantillons audio, seul le paramètre
«out» n’accepte pas de liste. Ce paramètre permet de diriger le signal vers d’autres
fonctions et ne peut être décuplé à l’intérieur d’un appel de fonction. Pour assigner
la sortie d’une fonction sur plusieurs canaux audio, il suffit de réécrire la fonction,
ou de la placer dans une boucle, en changeant la valeur du paramètre «out».
Comme beaucoup de moteurs audio, Csound gère les échantillons et les données
de contrôle en deux vitesses différentes. La boucle de contrôle est généralement plus
lente que la fréquence d’échantillonnage, afin d’économiser des cycles de calcul. On
utilisera la boucle de contrôle pour faire évoluer les valeurs de certains paramètres
en cours d’exécution. Par exemple, un vibrato sera généré au taux de contrôle
et viendra modifier la fréquence d’un oscillateur. Ounk permet ces changements
de valeur dans le temps. Chaque paramètre de fonction qui accepte les change-
ments continus est accompagné d’un autre paramètre portant le même nom suivi
55
La valeur continue qui évolue sur le canal «pitchVar» sera alors multipliée à
la valeur fixe déclarée au paramètre «pitch». Le résultat sera rafraı̂chi à chaque
tour de la boucle de contrôle. Une seule exception à cette règle : si un canal est
déclaré au paramètre «panVar», la valeur du paramètre «pan» ne sera pas utilisé.
Cette exception a pour but de préserver la cohérence de la panoramisation lorsque
le nombre de canaux de sortie est modifié.
Le paramètre «bus» des générateurs de contrôle accepte les listes en entrée, ce
qui permet de créer une banque de générateurs en une seule ligne. Par exemple :
Dans l’exemple ci-dessus, une liste de 6 valeurs est affectée à la variable canaux.
Ensuite, une deuxième liste est créée avec 6 valeurs pigées aléatoirement entre 2 et
5 et est placée en mémoire dans la variable freqs. En affectant ces deux listes aux
paramètres «bus» et «rate» de la fonction randomi, 6 générateurs aléatoires, aux
fréquences différentes, seront créés.
Les échantillons audio sortant d’une fonction sont dirigés sur un canal défini
par la valeur du paramètre «out». Par défaut, ce paramètre est fixé à la valeur
«dac», ce qui signifie que le signal sonore sera acheminé de la sortie de Csound
à la carte de son. On peut assigner une valeur de notre choix à ce paramètre (de
préférence un chaı̂ne de caractères), et récupérer le signal dans une autre fonction
56
playSound(sound=’ounkmaster.aif’, out=’snd’)
lowpass(input=’snd’, cutoff=500)
4
Internet Protocol : protocole utilisé pour la transmission de data via un réseau internet.
57
def sin(x):
sendOscControl(value=x, adress=’/sin’, port=9000)
def fm(x):
sendOscControl(value=x, adress=’/fm’, port=9000)
def snd(x):
sendOscControl(value=x, adress=’/snd’, port=9000)
Csound permet le rendu en temps réel, c’est-à-dire que les échantillons calculés
sont envoyés directement à la carte de son, ou le rendu en temps différé, où un fichier
son est créé sur le disque dur. Le rendu en temps réel est soumis à la puissance
du processeur tandis que le rendu en temps différé prend le temps nécessaire pour
effectuer ses calculs et créer le fichier son. Dans l’environnement Ounk, il suffit
de spécifier un nom, au paramètre «file» de la fonction startCsound, pour faire
basculer le mode de rendu en temps différé.
Voici une technique de travail largement utilisée dans la création de mes mu-
siques. Au début du script, une variable «RES», pouvant prendre les valeurs «low»
ou «high», est définie. De la valeur de cette variable sera déduite la résolution so-
nore de Csound, c’est-à-dire le taux d’échantillonnage et le taux de contrôle spécifiés
avec la fonction setAudioAttributes, le mode de rendu et, potentiellement, la qualité
de la réverbération utilisée par le script. Donc, lors de la conception de la musique,
58
la variable est à «low», permettant une écoute rapide du résultat. Lorsqu’une ver-
sion haute fidélité est désirée, la variable est changée pour «high» et on laisse la
machine prendre son temps pour effectuer le calcul. Cette technique permet de
construire des musiques sans se soucier des capacités de l’ordinateur, et l’on peut
composer sans contrainte. Par exemple :
RES = ’low’
if RES == ’low’:
setAudioAttributes(samplingrate=22050, controlrate=2205)
else:
setAudioAttributes(samplingrate=48000, controlrate=12000)
...
if RES == ’low’:
startCsound()
else:
startCsound(file=’Modulo’)
Au moment où ces lignes sont écrites, le sujet de l’heure en informatique mu-
sicale est l’utilisation des ordinateurs multi-processeurs pour créer de la musique.
L’intégration de multiples processeurs dans les logiciels audio est beaucoup plus
complexe qu’on ne le suppose. Les processus audio intimement reliés entre eux,
le partage de la mémoire ainsi que le délai temporel introduit par la communica-
tion entre les processeurs sont autant de problèmes ne bénéficiant pas encore de
solution optimale (Wang, 2008, Wessel, 2008). La communauté Csound a entre-
pris le développement d’une nouvelle version incorporant le multi-threading5 , ce
qui permettrait le partage des tâches entre différents processeurs. Présentement,
cette version n’est pas encore au point. Une solution intermédiaire a été mise en
place dans l’environnement Ounk afin de tirer avantage des capacités qu’offrent
5
Le partage des calculs d’une tâche sur plusieurs processeurs travaillant en parallèle.
59
les ordinateurs d’aujourd’hui. Lorsque Csound est lancé plusieurs fois sur une ma-
chine, chaque instance du logiciel tente de prendre son propre processeur. Sur un
MacPro à huit processeurs, par exemple, il est possible de lancer huit fois Csound
et d’utiliser au maximum la puissance de calcul de la machine. Ounk a été conçu
de façon à pouvoir démarrer plusieurs scripts en parallèle, utilisant chacun leur
propre instance de Csound, donc leur propre processeur. Le temps de démarrage
de Csound n’étant jamais exactement le même, il est évidemment difficile d’as-
surer une parfaite synchronie entre les scripts. Il est alors possible d’envoyer des
messages de contrôle, ou même des échantillons audio, d’un script à l’autre par le
biais du protocole OSC, ce qui assure un certain contrôle sur la synchronisation
des événements.
Ounk propose des répertoires par défaut où seront directement accessibles cer-
tains documents tels les fichiers son, les fichiers MIDI, les réponses impulsionnelles
ou les soundfonts. Ces dossiers sont au même niveau hiérarchique que l’application
Ounk. Tous les documents contenus dans ces dossiers peuvent être appelés sans
donner le lien complet sur le disque, Ounk sachant déjà où chercher ce type de
fichier. Il est aussi possible de changer les liens vers d’autres dossiers afin de res-
pecter une organisation des fichiers déjà en place sur le système. Il suffit d’indiquer
un nouveau lien avec les fonctions set...Path.
setSoundPath(’/Users/Peanut/MyFavoritesSounds/’)
setMidiPath(’/Users/Peanut/MyFavoritesMIDI/’)
3.4 Environnements
de certains types de messages, par exemple, une note MIDI en provenance d’un
clavier. Les différents environnements sont expliqués en détail ci-dessous. La des-
cription de la tâche d’un environnement commence après une fonction beginXXX
et se termine avec la fonction endXXX correspondante.
6
Relâche de la note ou une note avec une vélocité de 0.
61
les échantillons du piano préparé de John Cage, avec trois niveaux de vélocité. Les
échantillons sonores sont sauvegardés dans un même dossier et sont nommés en
suivant la logique suivante :
setSoundPath(’/Users/olipet/sampler’)
beginMidiSynth(release=.05)
# boucle sur les 88 premières notes du clavier
for i in range(88):
# chaque région comprend une seule touche
splitKeyboard(firstnote=i, endnote=i, centralkey=i)
# boucle sur les 3 vélocités
for j in range(3):
# p = (0 -> .3), mf = (.3 -> .6), ff = (.6 -> 1)
splitVelocity(minthresh=[.6,.3,0][j], maxthresh=[1,.6,.3][j])
# nom du fichier son (numéro_vélocité.aif)
s = str(i) + ’_’ + [’ff’,’mf’,’p’][j] + ’.aif’
playSound(sound=s)
endMidiSynth()
chance qu’une nouvelle table soit choisie au début de chaque séquence. Les tables
sont alors choisies de façon aléatoire. Voici un exemple de séquenceur :
env = genAdsr(release=0.8)
amp = genDataTable([1,0,.5,0,1,0,.5,0,1,0,.5,0,1,0,.5,.5])
metro(bus=’metro’, tempo=132)
beginSequencer(input=’metro’, table=amp)
freqMod(pitch=250, modulator=.502, duration=.5, envelope=env)
endSequencer()
Dans ce script, une table d’amplitudes, pour une mesure à 16 pas, est créée
avec la fonction genDataTable et est mise en mémoire dans la variable «amp». Le
métronome fera avancer la séquence d’un pas dans la table à chaque nouveau clic.
Une note sera jouée et la valeur pigée dans la table servira d’amplitude pour toutes
les fonctions intégrées à la séquence.
La fonction sequencerPitchTable permet de spécifier une table de multiplica-
teurs de fréquence qui seront appliqués à tous les paramètres «pitch» présents
dans la séquence. De façon plus générale, la fonction seqParameterTable permet de
remplacer la valeur de n’importe quel paramètre d’une fonction faisant partie de la
séquence. Le pas de la séquence servira à spécifier quelle valeur dans la table doit
être utilisée pour remplacer la valeur initiale du paramètre.
ind = genDataTable([8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1])
pit = genDataTable([1,0,.5,0,1,0,.5,0,1,0,.5,0,1,0,.5,.5])
metro(bus=’metro’, tempo=132)
beginSequencer(input=’metro’, table=tt1)
# table de multiplicateurs, indexée par le pas, appliqués aux paramètres ’pitch’
sequencerPitchTable(pit)
beginSequencer(input=’metro’, table=tt1)
# table de valeurs, indexée par le pas, appliquées aux paramètres ’index’
seqParameterTable(’index’, ind)
freqMod(pitch=250, modulator=.502, duration=.5, index=4)
endSequencer()
lowpass(input=’fm’, cutoff=2000)
proc = startCsound()
def note()
dict = {’freqMod’: {}}
dict[’freqMod’][’pitch’] = random.randint(100,200)
sendEvent(voice=1, dict=dict, process=proc)
7
Dans l’environnement Python, le dictionnaire est une table de données, définie entre accolades
{}, sur base de paires clé - valeur. Les paires sont séparées par des virgules et la clé est séparée
de sa valeur par le symbole deux-points ’ :’.
66
est appelée, un dictionnaire est créé avec une nouvelle valeur de hauteur et un
événement est demandé à l’instrument Python.
La catégorie Patterns contient un certain nombre de fonctions permettant
de modifier le comportement de l’algorithme en cours d’exécution. Des fonctions
témoins telles que getBeat, getBar et getTime permettent de suivre l’évolution
temporelle du jeu, et de modifier la structure de l’algorithme en conséquence. Il
est possible de modifier en tout temps la vitesse de l’horloge ou la séquence ryth-
mique utilisée avec les fonctions changeTime et changePattern. Ce module contient
aussi certaines fonctions spécialisées dans la génération de rythmes originaux et
cohérents.
3.4.4 Boucleur
8
Toutes les fonctions possédant les paramètres «starttime» et «duration» peuvent être mises
en boucle.
67
env = genAdsr()
beginLoop(duration=30, legato=[1,.5], amplitude=[1,0])
sine(pitch=[300,400], duration=[.25,.5], envelope=env)
endLoop()
Il est pratiquement impossible de produire des fonctions pour toutes les possi-
bilités de chaı̂nes de traitement qu’offre Csound. Une solution devait être envisagée
qui ne limite pas la programmation aux seules fonctions offertes par Ounk. L’ins-
trument «Csound» à été créé afin de permettre à l’utilisateur d’écrire ses propres
instruments Csound et de les intégrer facilement à Ounk. Un instrument existant,
sous la forme d’un fichier texte, peut être appelé avec la fonction myInstrument, et
sera dès lors utilisé comme tout autre instrument produit par Ounk.
Une syntaxe spéciale permet de relier les paramètres d’initialisation des notes
ainsi que les canaux de contrôle de l’instrument Csound aux variables et aux «bus»
de Ounk. Le paramètre «argslist» de la fonction myInstrument attend une liste
de valeurs qui seront assignées, dans l’instrument Csound, aux paramètres d’ini-
tialisation p4 et les suivants. Les paramètres d’initialisation p1, p2 et p3, qui
représentent respectivement le numéro de l’instrument Csound, le temps de départ
et la durée de la note, sont pris en charge par Ounk, notamment par la biais
des paramètres «starttime» et «duration». Pour relier des canaux de contrôle, il
68
instr 1
kenv linseg 0,.1,1,p3-.1,0
asig oscili p4*kenv, p5*kpit, p6
out asig
endin
wave = genWaveform()
# variations de fréquence
randomi(bus=’pitch’, mini=.95, maxi=1.05, rate=5)
fichier = ’path_vers_mon_fichier.txt’
# p4 = 5000, p5 = 200, p6 = wave
myInstrument(fichier, duration=1, argslist=[5000,200,wave],
vardict={’pit’: ’pitch’}, out=’toRev’)
Dans cet exemple, la variable «kpit» de l’instrument Csound est asservie au canal
de contrôle «pitch» et les paramètres d’intialisation p4, p5 et p6 sont passés via
le paramètre «argslist». Comme pour les fonctions standards, on assigne la sortie
audio par le biais du paramètre «out».
Cette technique devient particulièrement utile lorsqu’utilisée à l’intérieur d’un
instrument Python. Par exemple, dans le script ci-dessous, un instrument Csound
est définit à l’intérieur d’un instrument Python et la fonction note servira à effec-
tuer les appels d’événements en modifiant les valeurs p3 et p5 à chaque nouvel
événement :
9
En Csound, une variable de contrôle débute obligatoirement par la lettre [k]. Dans l’exemple
suivant, la variable «kpit», qui multiplie la fréquence d’un oscillateur, sera référencée dans le
dictionnaire par la clé «pit».
69
beginPythonInst(voice=1)
myfile = os.getcwd() + ’/Resources/examples/myOrch.txt’
myInstrument(myfile, duration=1, argslist=[...], vardict={...})
endPythonInst()
def note():
dict = {’myInstrument’: {}}
dict[’myInstrument’][’p3’] = random.randint(2,8)
dict[’myInstrument’][’p5’] = random.randint(50,200)
sendEvent(voice=1, dict=dict, process=proc)
def onPlay():
sendOscTrigger(value=1, adress=’/play’, port=8000)
def handleSlider(val):
sendOscControl(value=val, adress=’/s1’, port=8000)
def handleSlider2(val):
sendOscControl(value=val, adress=’/s2’, port=8000)
frame = beginGUI(size=(260,300))
p1 = makeButton(frame, label=’Play’, pos=(90,20), function=onPlay)
s1(frame, mini=-24, maxi=24, pos=(50,50), function=handleSlider)
s2(frame, mini=-24, maxi=24, pos=(50,120), function=handleSlider2)
endGUI(frame)
70
4.1 Contexte
4.2 Musique
Le Cycle des voix est une suite musicale constituée de sept compositions consis-
tant chacune en un seul geste musical. Choeurs, la dernière pièce du cycle, est une
synthèse des gestes musicaux explorés explorés durant la composition du cycle et
regroupe presque tous les matériaux sonores utilisés dans les pièces précédentes.
Bien que les pièces aient été composées pour être diffusées dans un ordre précis
en fonction de l’évolution dramatique de l’oeuvre, chaque composition peut exister
indépendamment du cycle. Les sections suivantes expliquent la structure des pièces
constituant le Cycle des voix.
Drone
Drone est la pièce d’ouverture du cycle. Utilisant les deux modèles de synthèse
décrits dans le présent ouvrage (synthèse de la voix et du didjeridu), l’élément
principal de cette pièce est composé pour un didjeridu solo dont la source d’ex-
citation est une voix de synthèse. Explorant un univers très sobre et introspectif,
Drone ouvre le cycle avec une longue trame exploitant le côté organique des sons
graves générés par le didjeridu. La pièce évolue très lentement, s’attardant sur les
différentes textures résonantes générées par le chant dans le didjeridu.
La chaı̂ne de traitements dans ce processus est complexe et riche en possibilités.
La synthèse vocale est d’abord générée sur différentes hauteurs et différents timbres,
puis elle est modulée par l’action des lèvres à l’entrée du didjeridu. Le résultat de ce
traitement est ensuite transformé par les qualités spectrales du didjeridu, composé
de 45 modes de résonances. La fréquence centrale de chaque mode est en constante
évolution, simulant un didjeridu dont la longueur et la forme changent au cours du
temps. Une distorsion est également ajoutée à certains événements de la voix de
synthèse, ainsi qu’une modulation en anneau, permettant de simuler des cris dans
l’instrument. Ces événements servent d’une part à modifier la richesse du spectre
de façon marquée et, d’autre part, à moduler la dynamique générale de la pièce en
73
créant de grandes vagues entre les sections douces et les sections fortes.
La pièce est jouée en temps réel dans l’environnement Ounk car le jeu de la
synthèse vocale est produit par des algorithmes écrits en Python et transmis à
Csound sous la forme d’événements indépendants. En parallèle, des changements
continus sont appliqués aux paramètres du didjeridu. Le déplacement du formant
principal de la bouche crée une résonance qui balaie le spectre, la modification de
la longueur du tuyau déplace les résonances de l’instrument et une variation de la
pression des lèvres modifie la richesse harmonique du timbre.
Paysages
Paysages explore le paradoxe entre les sons de la nature et la synthèse sonore.
Dans cette pièce, des sons à connotation naturelle très forte, tels des grillons et
des rafales de vent, ont été simulés avec le modèle de synthèse de la voix. Ces
textures évoquant la nature cohabitent avec des sons purement synthétiques, tels
que la note de basse constituée d’une forme d’onde simple. Ce paysage sonore sert
de toile de fond à une exploration libre des possibilités timbrales offertes par le
modèle de synthèse de la voix. Pour la génération des voix principales de cette
pièce, les paramètres de contrôle sont explorés dans les registres extrêmes afin de
générer des textures sonores complètement différentes de la voix chantée.
Une version particulière du modèle de synthèse vocale, offrant la liberté de
modifier en temps réel certains paramètres de contrôle, a été créée spécialement
pour générer les voix solos de cette pièce. Par exemple, dans le modèle de synthèse
de la voix généralement utilisé, les fréquences centrales des formants sont générées
automatiquement en fonction de la voyelle à synthétiser. Dans cette version du
modèle, une variation aléatoire appliquée à chacun des formants permet de déplacer
les filtres selon des trajectoires complètement différentes de celles présentes dans
l’articulation de phonèmes. À certains moments de la pièce, la vitesse et l’amplitude
du vibrato sont modifiées de façon à obtenir des sons se situant entre la synthèse
74
Déphasages
Première de deux pièces influencées par la musique de Steve Reich, la pièce
Déphasages explore les effets des déphasages rythmiques dans un contexte poly-
phonique. Sept voix de polyphonie sont introduites à tour de rôle tout au long de
la pièce, augmentant progressivement la densité de l’harmonie. Chacune des voix
chante de courts motifs musicaux, en boucle, sur un tempo commun. Les rythmes
de la pièces sont constitués de cellules ternaires de 2, 4 ou 8 temps, avec la croche
comme plus petite valeur temporelle. De façon périodique, certaines voix décalent
leur temps d’entrée d’une double-croche par rapport à la pulsation de base. Cela a
pour effet de créer une sensation de tempo deux fois plus rapide et de générer des
roulements de notes lorsque deux voix décalées l’une par rapport à l’autre jouent
dans un même registre. Après une certaine durée, le décalage temporel est annulé
et la rythmique de base est rétablie. Les voix recommencent à chanter en phase les
unes avec les autres, créant une sensation de repos après un moment de grande ac-
tivité rythmique. Pour marquer le moment où les voix se synchronisent à nouveau,
les cellules rythmiques et l’harmonie changent, et une voix est ajoutée au groupe.
Une mélodie ajoutée au tiers de la pièce et chantée par des voix de basse vient
soutenir le tempo en marquant les temps. Cette voix n’est jamais décalée dans le
temps, assurant une présence sur les temps forts de la mesure afin de garder une
pulsation bien sentie. Cette ligne mélodique ajoute de la couleur à l’harmonie des
voix en imposant une note fondamentale très présente.
75
Modulo
La pièce Modulo est construite sur une harmonie constante de douze notes,
chantées par des voix de synthèse. Afin d’éliminer le caractère vocal des sons,
chaque voix est modulée par un oscillateur à basse fréquence, faisant graduellement
apparaı̂tre et disparaı̂tre la voix. Comme chaque oscillateur modulant possède une
fréquence différente, l’harmonie entendue est en mouvement constant selon les croi-
sements provoqués par les apparitions et les disparitions des différentes voix. Cette
toile de fond donne un caractère très aérien à la pièce. La dynamique de mouve-
ment est construite à partir de modules de distorsion, associés chacun à une voix,
et possédant chacun leur propre oscillateur à basse fréquence affectant leur ampli-
tude respective. Les douze voix et distorsions, réparties de façon fixe dans l’espace,
créent des effets de déplacement par l’apparition et la disparition des éléments.
Afin d’accentuer ce phénomène, les distorsions, dont les emplacements dans l’es-
pace sont associés à chacune des voix, reçoivent en entrée audio le total des douze
1
La suite de logiciels TamTam a été développée par une équipe de l’Université de Montréal,
sous la direction de Jean Piché, dans le cadre du projet One Laptop Per Child.
http ://tamtam4olpc.wordpress.com/
76
voix de synthèse. Ceci crée l’effet d’une voix entendue en un point de l’espace alors
que cette même voix, traitée, apparaı̂t en un autre point de l’espace, créant des
jeux de mouvement intéressants.
Chorus morph
La pièce Chorus morph explore le fondu progressif d’un timbre sonore vers
un autre. La musique commence avec une de très nombreuses voix, des sopranos
chantant des notes extrêmement aiguës et des basses chantant à des fréquences
fondamentales inférieures à 20 Hz, créant une masse sonore très dense, difficile
à associer à la voix chantée. Au fur et à mesure que la pièce évolue, les sons
s’identifient de plus en plus à la voix chantée, alors que de longs glissandos appliqués
aux fréquences fondamentales font converger les notes vers une fréquence médiane
où toutes les voix se rejoignent à la fin, créant un chorus sur une seule note. Chorus
morph est donc une masse sonore en constante transformation, partant d’un spectre
complexe vers un spectre simple.
Dans cette pièce, seuls les registres sont importants, les notes chantées doivent
être le plus éloignées possible d’une quelconque tonalité ou harmonie. Les fonda-
mentales sont obtenues à l’aide de générateurs de nombres aléatoires contrôlés de
type Weibull, illustré par l’équation 4.1, dont la distribution est fonction de deux
paramètres, λ, le centre de gravité et K, la forme de la distribution.
(1/K)
1
x = λ log (4.1)
1 − random(0, 1)
Les figures 4.1 et 4.2 illustrent les densités de distribution aux quatre endroits
pivots de la pièce.
Comme cette pièce nécessite une grande quantité de voix pour créer la masse
sonore, plusieurs processeurs sont requis pour générer la musique en temps réel.
Comme les algorithmes sont gérés dans l’environnement Python, qui envoie en
77
Fig. 4.1 – Densités des distributions Weibull pour les voix de basse.
Fig. 4.2 – Densités des distributions Weibull pour les voix de soprano.
78
temps réel des événements à jouer aux instruments Csound, le rendu en temps
différé ne peut être utilisé pour cette pièce. Les capacités multi-processeurs de
Ounk sont utilisées pour lancer, au même moment, plusieurs scripts semblables
mais possédant leurs propres générateurs de nombres aléatoires propres, générant
des masses légèrement différentes. Chaque script appelle une nouvelle instance de
Csound, qui prendra le premier processeur disponible. Les flux sonores de chacune
des instances sont enregistrées dans des fichiers séparés et sont ensuite mixées en
un seul fichier son.
Reich
Cette deuxième pièce influencée par l’oeuvre de Steve Reich est construite en
deux parties. La première partie, plus lente, installe un style musical constitué de
courtes cellules binaires chantées en boucle dans une harmonie à sept voix. Sept voix
sont utilisées afin d’obtenir une octophonie où chaque voix n’est pas exactement
située dans un haut-parleur, mais plutôt dans un espace situé entre deux haut-
parleurs. Une table de probabilité, qui gère la longueur des cellules rythmiques,
appelle une longueur métrique différente à chaque nouvelle mesure. Des cellules de
quatre notes ont la plus forte probabilité d’être pigées, tandis que des cellules de
huit ou seize notes viendront parfois étendre les lignes mélodiques, contrebalançant
l’effet de répétition. La deuxième section de la pièce applique le même principe
mais sur un tempo beaucoup plus rapide avec des changements d’harmonie plus
fréquents, créant une section plus dynamique. Une mélodie très présente à la basse
vient accompagner les mélodies aux voix supérieures.
Voici comment l’environnement Step sequencer de Ounk a été utilisé pour créer
les mélodies de la pièce Reich :
beginSequencer(input=’metro’, table=s1)
seqParameterTable([’pitch’, ’duration’, ’fadeout’],
[sop1, notedur, fadedur])
setVoice(vowel=0, amplitude=.4, voicetype=3, vibratoamp=0, out=’v1’)
endSequencer(starttime=SEQSTART, duration=SEQDUR)
Choeurs
Cette pièce incorpore presque tous les types de timbres possibles avec le modèle
de synthèse vocale. Choeurs a été composée en parallèle à la création du logiciel
Ounk. C’est la seule pièce du cycle qui a été mixée de façon traditionnelle dans
un séquenceur multipistes. Les matériaux utilisés proviennent principalement de
générateurs algorithmiques, que ce soit pour les motifs rythmiques, pour les motifs
mélodiques ou pour les contrôles des paramètres de sons vocalement impossibles.
Bien que la première version de cette pièce ait été composée avec Max/MSP, une
grande partie des matériaux ont été refaits avec Ounk.
Choeurs est construite en trois parties. La première section présente les matériaux
développés au cours de la pièce : des accords denses, des sons de vent créés avec le
modèle de synthèse de la voix et des événements très brefs dans le registre aigu.
La section centrale installe une trame rythmée comme fond sonore pour un choeur
de sopranos et fait le lien avec la section finale. Celle-ci est constituée d’un choeur
d’environ quarante voix, créant un fond harmonique dense, au dessus duquel se
80
démarque une voix de soprano solo. Cette section utilise plusieurs matériaux déjà
utilisés aux deux premières sections de la pièce afin de faire de brefs rappels. Pour
mener au point culminant du cycle, la finale propose une atmosphère très planante
composée d’une harmonie riche et complexe.
Choeurs profite de l’élimination de la contrainte de la génération en temps
réel pour exploiter des matériaux d’une grande densité. Par exemple, la section
rythmique a été générée dix fois, chaque génération incluant plusieurs voix aux
timbres et aux comportements différents, et mixée afin de produire une pulsation
en constante évolution.
Le but de cette pièce était d’utiliser au maximum les qualités expressives du
modèle de synthèse de la voix chantée sans aucune contrainte de programmation.
Les seuls effets audio-numériques utilisés dans cette composition consiste en une
réverbération par convolution ainsi que quelques filtres d’égalisation.
CONCLUSION
Bélanger, O., Traube, C., and Piché, J. (2007). Designing and controlling a source-
filter model for naturalistic and expressive singing voice synthesis. In Proc. Inter-
national Computer Music Conference, pages 328 – 331, Copenhagen, Danemark.
Coleman, R. (1971). Male and female voice quality and its relationship to vowel
formant frequencies. Journal of speech and hearing research, 14 :565–577.
D’Alessandro, N., d’Alessandro, C., Le Beux, S., and Doval, B. (2006). Real-time
calm synthesizer, new approaches in hands-controlled voice synthesis. In Proc.
International Conference on New Interfaces for Musical Expression, pages 266 –
271, Paris, France.
84
Delattre, P., Liberman, A., and Cooper, F. (1955). Acoustic loci and transitional
cues for consonants. Journal of the Acoustical Society of America, 27 :769–773.
Delattre, P., Liberman, A., Cooper, F., Harris, K., and Hoffman, H. (1958). Ef-
fect of third-formant transitions on the perception of the voiced stop consonants.
Journal of the Acoustical Society of America, 30 :122–126.
Delvaux, V., Demolin, D., Soquet, A., and Kingston, J. (2004). La perception
des voyelles nasales du français. In Proc. Journée d’Étude sur la Parole, pages
157–160, Fès, Maroc.
Everest, A. (1989). The Master Handbook of Acoustics. TAB BOOK Inc., second
edition.
Fletcher, N., Hollenberg, L., Smith, J., and Wolfe, J. (2001a). Didjeridu acoustics.
Technical report, University of New South Wales, Sydney, Australia.
Fletcher, N., Hollenberg, L., Smith, J., and Wolfe, J. (2001b). The didjeridu and
the vocal tract. In Proc. International Symposium on Musical Acoustics, pages
87–90, Perugia, Italie.
Henrich, N., Doval, B., and D’Alessandro, C. (2003). The voice source as a
causal/anticausal linear filter. In ISCA ITRW VOQUAL, pages 15–19, Geneva,
Suisse.
Jackson, P. (2001). Acoustic cues of voiced and voiceless plosives for determining
place of articulation. In Proc. Workshop on Consistent and Reliable Acoustic Cues
for Sound Analysis, pages 19–22, Aalborg, Denmark.
85
Joliveau, E., Smith, J., and Wolfe, J. (2004). Vocal tract resonances in singing :
The soprano voice. Journal of the Acoustical Society of America, 116 :2434–2439.
Lu, H.-L. (2002). Toward a high-quality singing synthesizer with vocal texture
control. Phd thesis, Stanford University.
Rodet, X., Potard, Y., and Barrière, J.-B. (1984). The chant project : From
synthesis of the singing voice to synthesis in general. Computer Music Journal,
8 :15–31.
Wessel, D. (2008). Reinventing audio and music computation for many-core pro-
cessors. In Proc. International Computer Music Conference, Belfast, Irlande du
Nord.
Wright, M. and Freed, A. (1997). Opensound control : A new protocol for commu-
nicating with sound synthesizers. In Proc. International Computer Music Confe-
rence, pages 101 – 104, San Francisco.
Annexe I
Catégorie Functions
Analysis attackDetector, centroid, pitchAmp, rms
Controls busMix, busScale, expsegr, keyPressed, lfo, lfo2, linsegr, metro, midiCtl,
midiTrigger, midiTriggerInc, mouse, oscReceive, oscSend, oscTriggerSend,
printMidiCtl, rando, randomChoice, randomh, randomi, readTable, spline,
trigEnvelope, trigRandom, vibrato, weightedRandomChoice
Custom Inst myInstrument
Effects compressor, delay, didjeridu, distortion, flanger, fold, harmonizer, phaser,
resonator, ringMod, vdelay, vocoder
Filters bandpass, bandreject, dcblock, eqFilter, highpass, lowpass, resFilter
GenTables genAdsr, genDataTable, genExpseg, genLineseg, genRhythmTable,
genSoundTable, genWaveform, genWindow, reGenAdsr, reGenDataTable,
reGenExpseg, reGenLineseg, reGenSoundTable, reGenWaveform,
reGenWindow, recordBuffer, tableMorphing
General clear, getAudioAttributes, getImpulsePath, getMidiPath, getSoundInfo,
getSoundList, getSoundPath, getSoundfontPath, onStop, setAudioAttributes,
setAudioDevice, setChannels, setGlobalDuration, setImpulsePath,
setMidiDevice, setMidiPath, setSoundPath, setSoundfontPath, speakersConfig
Loops beginLoop, endLoop
Midi Synth beginMidiSynth, endMidiSynth, midiSynthCtl, midiSynthGetBus,
readMidiFile, splitKeyboard, splitVelocity
Output createLadspaPlugin, directOut, getPid, recordPerf, route,
startCsound, stopCsound, toDac, udpAudioReceive, udpAudioSend
Python Inst beginPythonInst, endPythonInst
Reverbs convolveReverb, infiniteReverb, reverb, waveguideReverb
Sampling recordAndLoop
Sequencer beginSequencer, endSequencer, seqParameterTable, sequencerPitchTable
Sources bell, freqMod, inputMic, pinkNoise, playSound, pluckedString, sawtooth, sine,
soundfont, soundfontMidi, square, train, voiceSynth, waveform, whiteNoise
Spatialisation pan1to2, pan1to4, pan1to8, pan2to4, pan2to8, pan4to8, panner, spat1to4
Spectral arpegiator, blur, crossSynth, fftBandpass, fftBandreject, freeze,
maskFilter, reSynth, smooth, transpose
Table process granulator, granulator2, granulator3, looper, soundTableRead, warper
Trigged Inst beginTrigInst, endTrigInst
89
Catégorie Functions
Algorithmic chord, droneAndJump, drunk, getValue, line, loopseg, mapper, markov,
midiToHertz, midiToTranspo, mkChangeOrder, mkRecord, mkSetList,
mkStartPlayback, mkStartRecord, next, oneCall, repeater, scale
GUI beginGUI, endGUI, makeButton, makeCircleSlider, makeMenu,
makeMultiSlider, makeSlider, makeSpin, makeToggle, makeXYSlider
Patterns changePattern, changeTime, getBar, getBeat, getTime, pattern, regenerate,
rhythmPattern, sendCsoundMsg, sendEvent, sendOscControl, sendOscTrigger
Annexe III
Reich
########################################################################
########################################################################
### R E I C H ###
### Voice synthesis music ###
### Ounk script ###
### 2008, Olivier Belanger ###
########################################################################
########################################################################
import random
#setAudioDevice(onumber=3)
octoSetup(1,2,6,5,8,3,7,4)
RES = ’high’
CHANNELS = 8
DUR = 330
TAP = 16
setGlobalDuration(DUR)
if RES == ’low’:
setAudioAttributes(samplingrate=22050, controlrate=2205, sampleformat=16)
else:
setAudioAttributes(samplingrate=48000, controlrate=12000, sampleformat=24)
setChannels(1)
brilli = random.random() * .1 + .8
if voicetype == 2:
glotalres = 2
rough = .05
else:
glotalres = .3 #random.random() * .5 + .3
rough = random.random() * .05 + .1
voiceSynth(amplitude = amplitude, vowel = vowel, consonant = consonant,
fadeout = 0.05, duration = .25, voicetype = voicetype,
vowelarticulation = vowelarti, formantresonance = formantres,
brilliance = brilli, glotalresonance = glotalres,
vibratoamp = vibratoamp, roughness = rough, out = out)
# global amplitude
linsegr(’globalamp’, .85, DUR-41.570, .85, 10, 1.1, .01, 0, 32.429, 0)
# TIMES #
SEQSTART = 0
SEQDUR = DUR
SEQ1DUR = 182.1
SEQ2DUR = SEQDUR - SEQ1DUR
# Rhythm tables
s1 = setRhythm(1, TAP, 60,85,70)
s2 = setRhythm(2, TAP, 70,80,75)
a1 = setRhythm(3, TAP, 70,70,70)
a2 = setRhythm(4, TAP, 65,80,80)
t1 = setRhythm(5, TAP, 85,70,75)
t2 = setRhythm(6, TAP, 90,80,60)
b1 = setRhythm(7, TAP, 95,70,40)
# pitch generators
seq = loopseg(37, 43) # soprano
seq2 = loopseg(35, 40) # alto
dro = loopseg(28,36) # tenor
rep = loopseg(40, 45) # bass
pitalto2 = []
pittenor1 = []
pittenor2 = []
pitbass1 = []
for i in range(10):
scnum = random.randint(0,2)
pitsop1.append(genDataTable([scl[scnum][seq.next()] for i in range(TAP)]))
pitsop2.append(genDataTable([scl[scnum][seq.next()] for i in range(TAP)]))
pitalto1.append(genDataTable([scl[scnum][seq2.next()] for i in range(TAP)]))
pitalto2.append(genDataTable([scl[scnum][seq2.next()] for i in range(TAP)]))
pittenor1.append(genDataTable([scl[scnum][dro.next()] for i in range(TAP)]))
pittenor2.append(genDataTable([scl[scnum][dro.next()] for i in range(TAP)]))
pitbass1.append(genDataTable([scl[scnum][rep.next()] for i in range(TAP)]))
randomChoice(bus=[’pitvar’, ’pitvar’],
choice=[0,.111,.222,.333,.444,.555,.666,.777,.888,.999],
rate=[0,.05], starttime=[SEQSTART, SEQSTART+SEQ1DUR],
duration=[SEQ1DUR,SEQ2DUR])
notedur1 = genDataTable([.5]*TAP)
notedur2 = genDataTable([.2]*TAP)
notedur = tableMorphing(tablelist=[notedur1, notedur2], indexVar=’notedur’,
length=TAP, starttime=SEQSTART, duration=SEQDUR)
fadedur1 = genDataTable([.075]*TAP)
fadedur2 = genDataTable([.075]*TAP)
fadedur = tableMorphing(tablelist=[fadedur1, fadedur2], indexVar=’notedur’,
length=TAP, starttime=SEQSTART, duration=SEQDUR)
93
# metronome
linsegr(bus=’tempVar’, i1=.5, dur1=SEQ1DUR, i2=.5, dur2=0, i3=1,
dur3=SEQ2DUR, i4=1, starttime=SEQSTART, duration=SEQDUR)
randomChoice(bus=’tapVar’, choice=[.125,.25,.25,.25,.25, 1], rate=.2)
# SEQUENCES
# soprano voices
beginSequencer(input=’metro’, table=s1)
seqParameterTable([’pitch’, ’duration’, ’fadeout’], [sop1, notedur, fadedur])
setVoice(vowel=0, amplitude=.5, voicetype=3, vibratoamp=0, out=’v1’)
endSequencer(starttime=SEQSTART, duration=SEQDUR)
beginSequencer(input=’metro’, table=s2)
seqParameterTable([’pitch’, ’duration’, ’fadeout’], [sop2, notedur, fadedur])
setVoice(vowel=0, amplitude=.5, voicetype=3, vibratoamp=0, out=’v2’)
endSequencer(starttime=SEQSTART, duration=SEQDUR)
# alto voices
beginSequencer(input=’metro’, table=a1)
seqParameterTable([’pitch’, ’duration’, ’fadeout’], [alto1, notedur, fadedur])
setVoice(vowel=0, amplitude=.7, voicetype=1, vibratoamp=0, out=’v3’)
endSequencer(starttime=SEQSTART, duration=SEQDUR)
beginSequencer(input=’metro’, table=a2)
seqParameterTable([’pitch’, ’duration’, ’fadeout’], [alto2, notedur, fadedur])
setVoice(vowel=0, amplitude=.7, voicetype=1, vibratoamp=0, out=’v4’)
endSequencer(starttime=SEQSTART, duration=SEQDUR)
# tenor voices
beginSequencer(input=’metro’, table=t1)
seqParameterTable([’pitch’, ’duration’, ’fadeout’], [tenor1, notedur, fadedur])
setVoice(vowel=4, amplitude=1.5, voicetype=0, vibratoamp=0, out=’v5’)
endSequencer(starttime=SEQSTART, duration=SEQDUR)
beginSequencer(input=’metro’, table=t2)
seqParameterTable([’pitch’, ’duration’, ’fadeout’], [tenor2, notedur, fadedur])
setVoice(vowel=4, amplitude=1.5, voicetype=0, vibratoamp=.01, out=’v6’)
endSequencer(starttime=SEQSTART, duration=SEQDUR)
# EFFECTS #
# harmonic pad
PADSTART = SEQSTART
PADDUR = SEQ1DUR - .1
pit = [scl[0][i] for i in range(20, 56, 5)]
amp = [.2,.15,.12,.09,.05,.03,.02,.01]
typ = [2,2,0,0,1,1,3,3]
vib = [.01,.01,.005,.005,.003,.003,.001]
linsegr(bus=’sinusbass’, i1=0, dur1=.01, i2=1, dur2=SEQ1DUR-.02,
i3=1, dur3=.01, i4=0, starttime=PADSTART, duration=PADDUR)
for i in range(7):
voiceSynth(pitch=pit[i], amplitude=amp[i]*.85, duration=PADDUR,
starttime=PADSTART, fadein=0.0001, fadeout=.1, brilliance=.8,
voicetype=typ[i], vibratoamp=vib[i], out=str(i+1))
sine(pitch=[32.7033, 48.9997], amplitude=[.03,.009],
amplitudeVar=’sinusbass’, out=str(i+1))
# bass drone
DRONESTART = SEQSTART + SEQ1DUR - .02
DRONEDUR = SEQ2DUR
basspit = [32.7033,32.7087,65.4068,65.4013,32.7011,32.6999,65.41]
bassmu = bassmult[j]
voiceSynth(pitch=basspit[i]*bassmu, amplitude=2.5, voicetype=2, fadein=.04,
fadeout=fade, brilliance=.8, starttime=bstart, glotalresonance=1,
duration=bdur, out=’bass%d’ % (i+1))
expsegr(’sinamp’, 0.001, .04, 1, bdur - .23, 1, .2, 0.0001,
starttime=bstart, duration=bdur)
pit = random.uniform(.997, 1.003) * 32.7033
sine(pitch = pit*bassmu, amplitude = .07, starttime=bstart, duration=bdur,
amplitudeVar=’sinamp’, out=’bass%d’ % (i+1))
lowpass(input=’bass%d’ % (i+1), amplitude=1, cutoff=1000,
starttime=bstart, duration=bdur, out=str(i+1))
# Noisy
NOISEDUR = SEQ1DUR
noisetable = genLineseg([0,1,1,5,1,20,.2,1000,.1, 1000, 0])
randomi(bus=’lfo’, mini=.5, maxi=1.4, rate=.2, duration=NOISEDUR)
lfo2(bus=’noise’, table=noisetable, frequency=.1136363636,
offset=0, frequencyVar=’lfo’, duration=NOISEDUR)
for i in range(7):
voiceSynth(amplitude=1.25, voicetype=random.randint(0,3),
vowel=random.randint(0,6), fadein=.001, fadeout=10,
roughness=1, formantresonance=.15, vibratoamp=0.0005,
duration=NOISEDUR, out=’noisy%d’ % (i+1))
route(input=’noisy%d’ % (i+1), amplitudeVar=’noise’,
duration=NOISEDUR, out=str(i+1))
# Amplitudes
randomh(bus=[’var1’,’var2’,’var3’,’var4’,’var5’,’var6’,’var7’],
mini=0.5, maxi=1.3, portamento=0.25, rate=[.2,.28,.23,.43,.47,.52,.58])
for i in range(7):
route(input=str(i+1), amplitude=.4, out=’rev%d’ % (i+1))
elif CHANNELS == 8:
for i in range(7):
convolveReverb(input=str(i+1), impulse=’ORTFFloorR10_m48.wav’,
amplitude=.8, mix=.025, out=’rev%d’ % (i+1))
if CHANNELS == 2:
pan1to2(input=’rev1’, pan=0)
pan1to2(input=’rev2’, pan=0.166)
pan1to2(input=’rev3’, pan=0.333)
pan1to2(input=’rev4’, pan=0.5)
pan1to2(input=’rev5’, pan=0.666)
pan1to2(input=’rev6’, pan=0.833)
pan1to2(input=’rev7’, pan=1)
elif CHANNELS == 8:
pan1to8(input=’rev1’, pan=0)
pan1to8(input=’rev2’, pan=0.166)
pan1to8(input=’rev3’, pan=0.333)
pan1to8(input=’rev4’, pan=0.5)
pan1to8(input=’rev5’, pan=0.666)
pan1to8(input=’rev6’, pan=0.833)
pan1to8(input=’rev7’, pan=1)
if RES == ’low’:
startCsound()
else:
startCsound(file=’Reich’)
Annexe IV
Chorus Morph
########################################################################
########################################################################
### C H O R U S M O R P H ###
### Voice synthesis music ###
### Ounk script (part 1) ###
### 2008, Olivier Belanger ###
########################################################################
########################################################################
if chorus_setup.RES == ’low’:
setAudioAttributes(samplingrate=44100, controlrate=4410, sampleformat=16)
elif chorus_setup.RES == ’high’:
setAudioAttributes(samplingrate=48000, controlrate=12000, sampleformat=24)
setGlobalDuration(-1)
beginPythonInst()
voiceSynth(pitch=220, duration=45, vowel=4, fadeout=5, pitchglissando=20,
vowelglissando=20, brilliance=.96, glotalresonance=1,
vibratoamp=0.001, roughness=0, out=’voice’)
endPythonInst()
if chorus_setup.RES == ’low’:
reverb(input=’voice’, revtime=1.5, mix=.3, amplitude=.5, out=’rev’)
elif chorus_setup.RES == ’high’:
convolveReverb(input=’voice’, mix=.03, out=’rev’)
if chorus_setup.CHANNELS == 2:
toDac(input=’rev’, amplitude=1.7)
elif chorus_setup.CHANNELS == 8:
pan2to8(input=’rev’, pan=0)
setChannels(8)
99
if chorus_setup.RECORD:
recordPerf(’Chorus_Morph-1’)
proc = startCsound()
# soprano voices
numv1 = chorus_setup.NUMHIGH
v1 = 1
def voice1():
global v1
proc
curtime = pat1.getTime()
pat1.changeTime(random.randint(5000,10000)*0.001)
if curtime <= 60:
p1 = 10
p2 = mapper(curtime,0,60,40,10)
elif curtime <= 200:
p1 = mapper(curtime,60,200,10,1)
p2 = mapper(curtime,60,200,10,20)
elif curtime <= 220:
p1, p2 = 1, 40
elif curtime <= 260:
p1 = mapper(curtime,220,260,1,.89)
p2 = mapper(curtime,220,260,20,80)
elif curtime <= 280:
p1, p2 = .89, 80
else:
p1, p2 = .89, 80
pat1.play(False)
pat2.play(False)
pat3.play()
return
pitch = random.weibullvariate(p1,p2) * 250
if pitch < 500: amp = .3
else: amp = .03
dict = {}
dict[’voiceSynth’] = {}
dict[’voiceSynth’][’duration’] = -1
dict[’voiceSynth’][’voicetype’] = 1
dict[’voiceSynth’][’amplitude’] = amp
dict[’voiceSynth’][’pitch’] = pitch
100
dict[’voiceSynth’][’vowel’] = random.randint(0,11)
dict[’voiceSynth’][’voicenumber’] = v1
dict[’voiceSynth’][’vowelglissando’] = random.uniform(2,5)
dict[’voiceSynth’][’pitchglissando’] = random.uniform(2,5)
dict[’voiceSynth’][’formantresonance’] = random.uniform(.75,1)
dict[’voiceSynth’][’brilliance’] = random.uniform(.9,.96)
dict[’voiceSynth’][’vibratospeed’] = random.uniform(2.,6.)
dict[’voiceSynth’][’vibratoamp’] = random.random() * 0.015
dict[’voiceSynth’][’pan’] = sc(v1,1,numv1)
sendEvent(1, dict, proc)
v1 += 1
if v1 > numv1: v1 = 1
# bass voices
numv2 = chorus_setup.NUMBASS
v2 = 1
def voice2():
global v2
curtime = pat2.getTime()
pat2.changeTime(random.randint(5000,10000)*0.001)
if curtime <= 80:
p1 = 0.03
p2 = 20
elif curtime <= 140:
p1 = mapper(curtime,80,140,.03,.3)
p2 = 20
elif curtime <= 220:
p1 = .3
p2 = 20
elif curtime <= 260:
p1 = mapper(curtime,220,260,.3,.89)
p2 = mapper(curtime,220,260,20,80)
elif curtime <= 300:
p1 = .89
p2 = 80
else:
pass
pitch = random.weibullvariate(p1,p2) * 250
if pitch < 30:
amp = 1.5
rough = .99
gliss = .05
elif pitch < 60:
amp = 1.2
101
rough = .8
gliss = 1
elif pitch < 100:
amp = .9
rough = .3
gliss = 2
else:
amp = .7
rough = .05
gliss = 3
dict = {}
dict[’voiceSynth’] = {}
dict[’voiceSynth’][’duration’] = -1
dict[’voiceSynth’][’voicetype’] = 2
dict[’voiceSynth’][’amplitude’] = amp
dict[’voiceSynth’][’pitch’] = pitch
dict[’voiceSynth’][’vowel’] = random.randint(0,6)
dict[’voiceSynth’][’voicenumber’] = v2 + 100
dict[’voiceSynth’][’fadein’] = 10
dict[’voiceSynth’][’vowelglissando’] = gliss
dict[’voiceSynth’][’pitchglissando’] = 5
dict[’voiceSynth’][’roughness’] = rough
dict[’voiceSynth’][’formantresonance’] = random.uniform(.75,1)
dict[’voiceSynth’][’glotalresonance’] = 1
dict[’voiceSynth’][’brilliance’] = random.uniform(.9,.96)
dict[’voiceSynth’][’vibratoamp’] = 0.015
dict[’voiceSynth’][’pan’] = 1 - sc(v2,1,numv2)
sendEvent(1, dict, proc)
v2 += 1
if v2 > numv2: v2 = 1
# final
v3 = 1
def final():
global v3
if v3 <= numv1:
voix = v3
vtype = 1
amp = .3
pan = sc(voix,1,numv1)
else:
voix = v3 - numv1 + 100
vtype = 2
amp = .7
102
pan = 1 - sc(v3-numv1,1,numv2)
dict = {}
dict[’voiceSynth’] = {}
dict[’voiceSynth’][’voicenumber’] = voix
dict[’voiceSynth’][’voicetype’] = vtype
dict[’voiceSynth’][’amplitude’] = amp
dict[’voiceSynth’][’pan’] = pan
sendEvent(1, dict, proc)
v3 += 1
if v3 == numv1 + numv2 + 1:
pat3.play(False)
voice1()
voice2()