vosim — Simulation vocale simple basée sur des pulsations glottales avec des caractéristiques de formant.
Cet opcode produit une simulation vocale simple basée sur des pulsations glottales avec des caractéristiques de formant. La sortie est une suite d'évènements sonores dans laquelle chaque élément est composé d'une explosion de pulsations sinusoïdales élevées au carré suivies par un silence. La méthode de synthèse VOSIM (VOcal SIMulation) fut développée par Kaegi et Tempelaars dans les années 1970.
ifn - une table sonore contenant normalement une demie-période d'une onde sinusoïdale, élévée au carré (voir les notes ci-dessous).
iskip - (facultatif) L'initialisation est ignorée, pour les notes liées.
ar - signal en sortie. Noter que les sortie est habituellement unipolaire - seulement positive.
kamp - amplitude de la sortie, l'amplitude de crête de la première pulsation dans chaque explosion.
kFund - hauteur fondamentale, en Hz. Chaque évènement dure 1/kFund secondes.
kForm - fréquence du formant central. La longueur de chaque pulsation dans l'explosion vaut 1/kForm secondes.
kDecay - facteur d'amortissement d'une pulsation à l'autre. Il est soustrait de l'amplitude à chaque nouvelle pulsation.
kPulseCount - nombre de pulsations dans la partie explosive de chaque évènement.
kPulseFactor - la largeur de pulsation est multipliée par cette valeur à chaque nouvelle pulsation. Cela provoque un glissement de formant. Si le factor est < 1.0, le formant monte, s'il est > 1.0 chaque nouvelle pulsation est plus longue et ainsi le format descend. La hauteur finale du formant vaut kForm * pow(kPulseFactor, kPulseCount)
La sortie de vosim est une suite d'évènements sonores, dans laquelle chaque évènement est composé d'une explosion de pulsations sinusoïdales élevées au carré suivies par un silence. La durée totale des évènements détermine la fréquence fondamentale. La longueur de chaque impulsion individuelle dans l'explosion de sinus au carré produit une bande de fréquence formantique. La largeur du formant est déterminée par le taux de silence par rapport aux pulsations (voir ci-dessous). Le résultat final est aussi modelé par le facteur d'atténuation entre pulsations.
Le fait qu'aucune fonction GEN ne crée une onde sinusoïdale élevée au carré telle quelle pose un petit problème dans l'utilisation de cet opcode. On peut créer la table appropriée depuis la partition en utilisant quelque chose comme ce qui suit.
; use GEN09 to create half a sine in table 17 f 17 time size 9 0.5 1 0 ; run instr 101 on table 17 for a single init-pass i 101 0 0 17
On peut aussi le faire avec un instrument qui remplit une ftable dans l'orchestre :
; square each point in table #p4. This should be run as init-only, just once in the performance. instr 101 index tableng p4 index = index - 1 ; start from last point loop: ival table index, p4 ival = ival * ival tableiw ival, index, p4 index = index - 1 if index < 0 igoto endloop igoto loop endloop: endin
Limites de Paramètre | |
---|---|
Le nombre de pulsations multiplié par la largeur de pulsation doit être inclus dans la longueur de l'évènement (1/kFund). Si ce n'est pas le cas, l'algorithme fonctionne quand même, mais les pulsations qui se trouveraient en dehors de l'évènement ne sont pas démarrées. Cela peut introduire un silence à la fin de l'évènement même s'il n'est pas désiré. En conséquence, kForm doit être supérieur à kFund, sinon il n'y aura que du silence en sortie. |
Vosim a été créé pour émuler des sons vocaux en modélisant des impulsions glottales. On peut créer des sons riches en combinant plusieurs instances de vosim avec différents paramètres. Le fait que le signal ne soit pas à bande limitée est un inconvénient. Mais comme les auteurs le souligne, l'atténuation des composants aigus est de -60 dB à six fois la fréquence fondamentale. On peut également modifier le signal en changeant le signal source dans la table de lecture. La technique a un intérêt historique et peut produire des sons riches à moindre frais (chaque échantillon ne nécessite qu'une lecture dans la table suivie d'une seule multiplication pour l'atténuation).
Comme indiqué, la largeur de bande du formant dépend du rapport entre l'explosion de pulsation et le silence dans un évènement. Mais ce n'est pas un paramètre indépendant : la fondamentale fixe la longueur de l'évènement tandis que le centre du formant définit la longueur de la pulsation. Il est ainsi impossible de garantir un rapport explosion/silence spécifique, car la longueur de l'explosion doit être un multiple entier de la longueur de la pulsation. La chute des pulsations peut être utilisée pour lisser la transition de N à N+/-1 pulsations, mais il y aura toujours des paliers dans le profil spectral de la sortie. L'exemple de code ci-dessous montre une telle approche.
Tous les paramètres en entrée sont de taux-k. Les paramètres en entrée ne sont utilisés que pour déterminer chaque nouvel évènement (ou grain). L'amplitude de l'évènement est fixée pour chaque évènement à l'initialisation. Pour les valeurs usuelles des paramètres, lorsque ksmps <500, les paramètres de taux-k sont mis à jour plus souvent que les évènements ne sont créés. Dans tous les cas, il n'y aura pas de bruit à large bande injecté dans le système à cause d'entrées de taux-k mises à jour moins souvent qu'elles ne sont lues, mais quelques artefacts peuvent être créés.
L'opcode devrait se comporter raisonnablement pour toutes les entrées. Quelques détails :
kFund < 0 : il est forcé à une valeur positive - pas de points dans des évènements "inversés".
kFund == 0 : cela conduit à un évènement de longueur "infinie", c'est-à-dire une explosion de pulsation suivie par un très long silence indéfini.
kForm == 0 : cela conduit à une pulsation de longueur infinie, ainsi aucune pulsation n'est générée (c'est-à-dire silence).
kForm < 0 : la table est lue à l'envers. Si la table est symétrique, kform et -kformdonneront des sortie identiques bit à bit.
kPulseFactor == 0 : la seconde pulsation en avant est zéro. Voir (c).
kPulseFactor < 0 : les pulsations lisent la table alternativement à l'endroit et à l'envers.
Avec une table de pulsation asymétrique, un kForm ou un kPulseFactor négatifs peuvent être utiles.
Voici un exemple de l'opcode vosim. Il utilise le fichier vosim.csd.
Exemple 1193. Exemple de l'opcode vosim.
Voir les sections Audio en Temps Réel et Options de la Ligne de Commande pour plus d'information sur l'utilisation des options de la ligne de commande.
<CsoundSynthesizer> <CsOptions> ; Select audio/midi flags here according to platform ; Audio out Audio in ;-odac -iadc ;;;RT audio I/O ; For Non-realtime ouput leave only the line below: -o vosim.wav -W ;;; for file output any platform </CsOptions> <CsInstruments> sr = 44100 ksmps = 100 nchnls = 1 ;################################################# ; By Rasmus Ekman 2008 ; Square each point in table #p4. This should only be run once in the performance. instr 10 index tableng p4 index = index - 1 ; start from last point loop: ival table index, p4 ival = ival * ival tableiw ival, index, p4 index = index - 1 if index < 0 igoto endloop igoto loop endloop: endin ;################################################# ; vosim instrument. Sweeps kfund and kform between start-end values. ; Attempts to smooth spectral transitions as pulse count changes ; p4: amp ; p5, p6: fund beg-end ; p7, p8: form beg-end ; p9: amp decay (ignored) ; p10: pulse count (ignored - calc internally) ; p11: pulse length mod ; p12: skip (for tied events) ; p13: don't fade out (if followed by tied note) instr 1 kamp init p4 ; freq start, end kfund line p5, p3, p6 ; formant start, end kform line p7, p3, p8 ; Get many pulses as we can fit kPulseCount = (kform / kfund) ;init p10 ; Attempt to smooth steps between formant bandwidth, ; matching decay to the current pulse count and remaining silent part kPulseREM = kPulseCount - int(kPulseCount) ; Pulse remainder (empty samples after last pulse) kDroprate = kPulseREM / (kPulseCount-1) ; Decay per pulse (after the 1st) kDecay = kamp - kDroprate ; Guard against kamp going negative (since kDecay is subtracted from each pulse) if (kDecay * (kPulseCount-1)) > kamp then kDecay = kamp / kPulseCount endif ; Try this to get more bumpy spectral changes when pulse count changes ;kDecay = p9 kPulseFactor init p11 ; ar vosim kamp, kFund, kForm, kDecay, kPulseCount, kPulseFactor, ifn [, iskip] ar1 vosim kamp, kfund, kform, kDecay, kPulseCount, kPulseFactor, 17, p12 ; scale amplitude for 16-bit files, with quick fade out amp init 20000 if (p13 != 0) goto nofade amp linseg 20000, p3-.02, 20000, .02, 0 nofade: out ar1 * amp endin </CsInstruments> <CsScore> f1 0 32768 9 1 1 0 ; sine wave f17 0 32768 9 0.5 1 0 ; half sine wave i10 0 0 17 ; init run only, square table 17 ; Vosim score ; Picking some formants from the table in Csound manual ; p4=amp fund form decay pulses pulsemod [skip] nofade ; tenor a -> e i1 0 .5 .5 280 240 650 400 .03 5 1 0 0 i1 . . .3 . . 1080 1700 .03 5 . . . i1 . . .2 . . 2650 2600 .03 5 . . . i1 . . .15 . . 2900 3200 .03 5 . . . ; tenor a -> o i1 0.6 .2 .5 300 210 650 400 .03 5 1 0 1 i1 . . .3 . . 1080 800 .03 5 . . . i1 . . .2 . . 2650 2600 .03 5 . . . i1 . . .15 . . 2900 2800 .03 5 . . . ; tenor o -> aah i1 .8 .3 .5 210 180 400 650 .03 5 1 1 1 i1 . . .3 . . 800 1080 .03 5 . . . i1 . . .2 . . 2600 2650 .03 5 . . . i1 . . .15 . . 2800 2900 .03 5 . . . ; tenor aa -> i i1 1.1 .2 .5 180 250 650 290 .03 5 1 1 1 i1 . . .3 . . 1080 1870 .03 5 . . . i1 . . .2 . . 2650 2800 .03 5 . . . i1 . . .15 . . 2900 3250 .03 5 . . . ; tenor i -> u i1 1.3 .3 .5 250 270 290 350 .03 5 1 1 0 i1 . . .3 . . 1870 600 .03 5 . . . i1 . . .2 . . 2800 2700 .03 5 . . . i1 . . .15 . . 3250 2900 .03 5 . . . e </CsScore> </CsoundSynthesizer>