spat3d
Prev | Opcodes et opérateurs de l'orchestre | Next

## spat3d

spat3d — Positionne le son d'entrée dans un espace 3D et permet de déplacer le son au taux-k.

## Description

Cet opcode positionne le son d'entrée dans un espace 3D, avec simulation facultative d'un espace acoustique, dans différents formats de sortie. spat3d permet de déplacer le son au taux-k (ce mouvement est interpolé en interne pour éliminer le bruit de transition (“zipper noise”) si sr n'est pas égal à kr).

## Syntaxe

    aW, aX, aY, aZ spat3d ain, kX, kY, kZ, idist, ift, imode, imdel, iovr [, istor]

## Initialisation

idist -- Pour les modes 0 à 3, idist est la distance du cercle unité en mètres. Pour le mode 4, idist est la distance entre les microphones.

Les formules suivantes décrivent l'amplitude et le retard comme une fonction de la distance entre la source sonore et le(s) microphone(s) :

amplitude = 1 / (0.1 + distance)

delai = distance / 340 (en secondes)

La distance peut être calculée par :

distance = sqrt(iX^2 + iY^2 + iZ^2)

Dans le mode 4, la distance est calculée par :

distance au micro de gauche = sqrt((iX + idist/2)^2 + iY^2 + iZ^2)
distance au micro de droite = sqrt((iX - idist/2)^2 + iY^2 + iZ^2)

Avec spat3d la distance entre la source sonore et un microphone doit valoir au moins (340 * 18) / sr mètres. Les distances inférieures fonctionneront mais pourront produire des artefacts dans certains cas. Cette limitation n'existe pas pour spat3di et spat3dt.

Les changements brusques et les discontinuités dans le positionnement de la source sonore peuvent donner des pops ou des clics. Un mouvement très rapide peut aussi dégrader la qualité.

ift -- Table de fonction contenant les paramètres spatiaux (pour une spatialisation en milieu ouvert, mettre zéro ou une valeur négative). La taille de la table est 54. Les valeurs dans la table sont :

Paramètre Spatial | Fonction
--- | ---
0 | Profondeur de récursion des premières réflexions (0 est la source sonore, 1 est la première réflexion, etc.) pour spat3d et spat3di. Le nombre d'échos pour quatre murs (avant, arrière, droit, gauche) est : N = (2*R + 2) * R. Si les six murs sont pris en compte : N = (((4*R + 6)*R + 8)*R) / 3
1 | Profondeur de récursion des réflexions secondaires (utilisé seulement par spat3dt). spat3dt passe les premières réflexions et restitue des échos jusqu'à ce niveau. Si la profondeur des premières réflexions est négative, spat3d et spat3di donneront zéro en sortie, tandis que spat3dt commencera sa restitution depuis la source sonore.
2 | imdel pour spat3d. Remplace le paramètre de l'opcode s'il est non négatif.
3 | irlen pour spat3dt. Remplace le paramètre de l'opcode s'il est non négatif.
4 | valeur de idist. Remplace le paramètre de l'opcode si elle est >= 0.
5 | Graine aléatoire (0 - 65535). -1 fait prendre le temps courant comme graine.
6 - 53 | paramètre de mur (w = 6 : plafond, w = 14 : plancher, w = 22 : avant, w = 30 : arrière, w = 38 : droite, w = 46 : gauche)
w + 0 | Active les réflexions depuis ce mur (0 : non, 1 : oui)
w + 1 | Distance entre le mur et l'auditeur (en mètres)
w + 2 | Variation aléatoire de la distance du mur (0 à 1) (en unités de 1 / (distance du mur))
w + 3 | Niveau de réflexion level (-1 à 1)
w + 4 | Fréquence de l'égaliseur paramétrique en Hz.
w + 5 | Niveau de l'égaliseur paramétrique (1.0 : pas de filtrage)
w + 6 | Q de l'égaliseur paramétrique (0.7071 : pas de résonnance)
w + 7 | Mode de l'égaliseur paramétrique (0 : peak EQ, 1 : low shelf, 2 : high shelf)

imode -- Mode de sortie.

- 0 : format B avec sortie W seulement (mono)

  aout = aW

- 1 : format B avec sorties W et Y (stéréo)

  aleft = aW + 0.7071*aY
  aright = aW - 0.7071*aY

- 2 : format B avec sorties W, X et Y (2D). Peut être converti au format UHJ :

  aWre, aWim hilbert aW
  aXre, aXim hilbert aX
  aYre, aYim hilbert aY
  aWXr = 0.0928*aXre + 0.4699*aWre
  aWXiYr = 0.2550*aXim - 0.1710*aWim + 0.3277*aYre
  aleft = aWXr + aWXiYr
  aright = aWXr - aWXiYr

- 3 : format B avec toutes les sorties (3D)

- 4 : Simule une paire de microphones (sortie stéréo)

  aW butterlp aW, ifreq ; les valeurs recommendées pour ifreq
  aY butterlp aY, ifreq ; se situent autour de 1000 Hz
  aleft = aW + aX
  aright = aY + aZ

Le mode 0 est le moins couteux en capacité de calcul, tandis que le mode 4 est le plus gourmand.

Dans le mode 4, les filtres passe-bas facultatifs peuvent changer la réponse en fréquence en fonction de la direction. Par exemple, si la source sonore se situe à gauche de l'auditeur, les fréquences élevées sont atténuées dans le canal droit et légèrement augmentées dans le canal gauche. Si l'on utilise pas de filtre, cet effet n'a pas lieu. On peut expérimenter avec d'autres filtres (tone, etc.) pour un meilleur effet.

Noter que le mode 4 est plutôt destiné à une écoute au casque et qu'il est aussi plus coûteux en calcul que les modes du format B (0 à 3). Dans ce cas, le paramètre idist fixe la distance entre les microphones gauche et droit ; pour le casque, des valeurs comprises entre 0.2 et 0.25 sont recommandées, bien que l'on puisse utiliser des valeurs plus grandes, jusqu'à 0.4, pour des effets stéréo larges.

On peut trouver plus d'information sur le format B ici : http://www.york.ac.uk/inst/mustech/3d_audio/ambis2.htm

imdel -- Retard maximum pour spat3d en secondes. Doit être plus long que le retard de la dernière réflexion (qui dépend des dimensions de la pièce, de la distance à la source et de la profondeur de récursion) ; la formule suivante donne une valeur sûre (bien que parfois surestimée) :

imdel = (R + 1) * sqrt(W*W + H*H + D*D) / 340.0

où R est la profondeur de récursion, W, H et D sont respectivement la largeur, la hauteur et la profondeur de la pièce).

iovr -- Facteur de suréchantillonnage pour spat3d (1 à 8). Les valeurs supérieurs augmentent la qualité au prix d'une consommation plus importante de la mémoire et du processeur. La valeur recommendée est 2.

istor (facultatif, 0 par défaut) -- S'il est différent de zéro, la phase d'initialisation est ignorée.

## Exécution

aW, aX, aY, aZ -- Signaux de sortie.

| mode 0 | mode 1 | mode 2 | mode 3 | mode 4
--- | --- | --- | --- | --- | ---
aW | sortie W | sortie W | sortie W | sortie W | canal gauche / basses fréq.
aX | 0 | 0 | sortie X | sortie X | canal gauche / hautes fréq.
aY | 0 | sortie Y | sortie Y | sortie Y | canal droit / basses fréq.
aZ | 0 | 0 | 0 | sortie Z | canal droit / hautes fréq.

ain -- Signal d'entrée.

kX, kY, kZ -- Coordonnées de la source sonore en (mètres).

Si l'on constate un fort ralentissement (jusqu'à 100 fois plus lent), la cause peut venir des nombres dénormalisés (nombres de magnitude trop faible). Ceci vaut aussi pour d'autres opcodes RII comme butterlp, pareq, hilbert, et bien d'autres. Ces déficits de capacité peuvent être évités en :

- utilisant l'opcode denorm sur ain avant spat3d.

- ajoutant au signal d'entrée une composante continue de faible niveau ou du bruit, par exemple

  atmp rnd31 1/1e24, 0, 0

  aW, aX, aY, aZ spa3di ain + atmp, ...

  ou

  aW, aX, aY, aZ spa3di ain + 1/1e24, ...

- réduisant irlen dans le cas de spat3dt (qui n'a pas de signal en entrée). Une valeur de 0.005 convient à la plupart des cas, bien que cela dépende aussi des réglages EQ. Si l'on utilise pas l'égaliseur, “irlen” peut rester être mis à 0.

## Exemples

Voici un exemple de l'opcode spat3d qui produit une sortie stéréo. Il utilise le fichier spat3d_stereo.csd.

Example 833. Exemple stéréo de l'opcode spat3d.

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    No messages
    -odac           -iadc     -d     ;;;RT audio I/O
    ; For Non-realtime ouput leave only the line below:
    ; -o spat3d_stereo.wav -W ;;; for file output any platform
    </CsOptions>
    <CsInstruments>

    /* Written by Istvan Varga */
    sr      =  48000
    kr      =  1000
    ksmps   =  48
    nchnls  =  2

    /* room parameters */

    idep    =  3    /* early reflection depth       */

    itmp    ftgen   1, 0, 64, -2,                                           \
    		/* depth1, depth2, max delay, IR length, idist, seed */ \
    		idep, 48, -1, 0.01, 0.25, 123,                          \
    		1, 21.982, 0.05, 0.87, 4000.0, 0.6, 0.7, 2, /* ceil  */ \
    		1,  1.753, 0.05, 0.87, 3500.0, 0.5, 0.7, 2, /* floor */ \
    		1, 15.220, 0.05, 0.87, 5000.0, 0.8, 0.7, 2, /* front */ \
    		1,  9.317, 0.05, 0.87, 5000.0, 0.8, 0.7, 2, /* back  */ \
    		1, 17.545, 0.05, 0.87, 5000.0, 0.8, 0.7, 2, /* right */ \
    		1, 12.156, 0.05, 0.87, 5000.0, 0.8, 0.7, 2  /* left  */

    	instr 1

    /* some source signal */

    a1      phasor 150              ; oscillator
    a1      butterbp a1, 500, 200   ; filter
    a1      =  taninv(a1 * 100)
    a2      phasor 3                ; envelope
    a2      mirror 40*a2, -100, 5
    a2      limit a2, 0, 1
    a1      =  a1 * a2 * 9000

    kazim   line 0, 2.5, 360        ; move sound source around
    kdist   line 1, 10, 4           ; distance

    ; convert polar coordinates
    kX      =  sin(kazim * 3.14159 / 180) * kdist
    kY      =  cos(kazim * 3.14159 / 180) * kdist
    kZ      =  0

    a1      =  a1 + 0.000001 * 0.000001     ; avoid underflows

    imode   =  1    ; change this to 3 for 8 spk in a cube,
    		; or 1 for simple stereo

    aW, aX, aY, aZ  spat3d a1, kX, kY, kZ, 1.0, 1, imode, 2, 2

    aW      =  aW * 1.4142

    ; stereo
    ;
    aL     =  aW + aY              /* left                 */
    aR     =  aW - aY              /* right                */

    ; quad (square)
    ;
    ;aFL     =  aW + aX + aY         /* front left           */
    ;aFR     =  aW + aX - aY         /* front right          */
    ;aRL     =  aW - aX + aY         /* rear left            */
    ;aRR     =  aW - aX - aY         /* rear right           */

    ; eight channels (cube)
    ;
    ;aUFL   =  aW + aX + aY + aZ    /* upper front left     */
    ;aUFR   =  aW + aX - aY + aZ    /* upper front right    */
    ;aURL   =  aW - aX + aY + aZ    /* upper rear left      */
    ;aURR   =  aW - aX - aY + aZ    /* upper rear right     */
    ;aLFL   =  aW + aX + aY - aZ    /* lower front left     */
    ;aLFR   =  aW + aX - aY - aZ    /* lower front right    */
    ;aLRL   =  aW - aX + aY - aZ    /* lower rear left      */
    ;aLRR   =  aW - aX - aY - aZ    /* lower rear right     */

    	outs aL, aR

    	endin

    </CsInstruments>
    <CsScore>

    /* Written by Istvan Varga */
    i 1 0 10
    e

    </CsScore>
    </CsoundSynthesizer>

Voici un exemple de l'opcode spat3d qui produit une sortie UHJ. Il utilise le fichier spat3d_UHJ.csd.

Example 834. Exemple UHJ de l'opcode spat3d.

    <CsoundSynthesizer>
    <CsOptions>
    ; Select audio/midi flags here according to platform
    ; Audio out   Audio in    No messages
    -odac           -iadc     -d     ;;;RT audio I/O
    ; For Non-realtime ouput leave only the line below:
    ; -o spat3d_UHJ.wav -W ;;; for file output any platform
    </CsOptions>
    <CsInstruments>

    /* Written by Istvan Varga */
    sr	=  48000
    kr	=  750
    ksmps	=  64
    nchnls	=  2

    itmp    ftgen   1, 0, 64, -2,                                           \
    		/* depth1, depth2, max delay, IR length, idist, seed */ \
    		3, 48, -1, 0.01, 0.25, 123,				\
    		1, 21.982, 0.05, 0.87, 4000.0, 0.6, 0.7, 2, /* ceil  */ \
    		1,  1.753, 0.05, 0.87, 3500.0, 0.5, 0.7, 2, /* floor */ \
    		1, 15.220, 0.05, 0.87, 5000.0, 0.8, 0.7, 2, /* front */ \
    		1,  9.317, 0.05, 0.87, 5000.0, 0.8, 0.7, 2, /* back  */ \
    		1, 17.545, 0.05, 0.87, 5000.0, 0.8, 0.7, 2, /* right */ \
    		1, 12.156, 0.05, 0.87, 5000.0, 0.8, 0.7, 2  /* left  */

    	instr 1

    p3	=  p3 + 1.0

    kazim	line 0.0, 4.0, 360.0		; azimuth
    kelev	line 40, p3 - 1.0, -20		; elevation
    kdist	=  2.0				; distance
    ; convert coordinates
    kX	=  kdist * cos(kelev * 0.01745329) * sin(kazim * 0.01745329)
    kY	=  kdist * cos(kelev * 0.01745329) * cos(kazim * 0.01745329)
    kZ	=  kdist * sin(kelev * 0.01745329)

    ; source signal
    a1	phasor 160.0
    a2	delay1 a1
    a1	=  a1 - a2
    kffrq1	port 200.0, 0.8, 12000.0
    affrq	upsamp kffrq1
    affrq	pareq affrq, 5.0, 0.0, 1.0, 2
    kffrq	downsamp affrq
    aenv4	phasor 3.0
    aenv4	limit 2.0 - aenv4 * 8.0, 0.0, 1.0
    a1	butterbp a1 * aenv4, kffrq, 160.0
    aenv	linseg 1.0, p3 - 1.0, 1.0, 0.04, 0.0, 1.0, 0.0
    a_	=  4000000 * a1 * aenv + 0.00000001

    ; spatialize
    a_W, a_X, a_Y, a_Z	spat3d a_, kX, kY, kZ, 1.0, 1, 2, 2.0, 2

    ; convert to UHJ format (stereo)
    aWre, aWim	hilbert a_W
    aXre, aXim	hilbert a_X
    aYre, aYim	hilbert a_Y

    aWXre	=  0.0928*aXre + 0.4699*aWre
    aWXim	=  0.2550*aXim - 0.1710*aWim

    aL	=  aWXre + aWXim + 0.3277*aYre
    aR	=  aWXre - aWXim - 0.3277*aYre

    	outs aL, aR

    	endin

    </CsInstruments>
    <CsScore>

    /* Written by Istvan Varga */
    t 0 60

    i 1 0.0 8.0
    e

    </CsScore>
    </CsoundSynthesizer>

Voici un exemple de l'opcode spat3d qui produit une sortie quadraphonique. Il utilise le fichier spat3d_quad.csd.

Example 835. Exemple quadraphonique de l'opcode spat3d.

    <CsoundSynthesizer>
    <CsOptions>
    ; Select audio/midi flags here according to platform
    ; Audio out   Audio in    No messages
    -odac           -iadc     -d     ;;;RT audio I/O
    ; For Non-realtime ouput leave only the line below:
    ; -o spat3d_quad.wav -W ;;; for file output any platform
    </CsOptions>
    <CsInstruments>

    /* Written by Istvan Varga */
    sr      =  48000
    kr      =  1000
    ksmps   =  48
    nchnls  =  4

    /* room parameters */

    idep    =  3    /* early reflection depth       */

    itmp    ftgen   1, 0, 64, -2,                                           \
    		/* depth1, depth2, max delay, IR length, idist, seed */ \
    		idep, 48, -1, 0.01, 0.25, 123,                          \
    		1, 21.982, 0.05, 0.87, 4000.0, 0.6, 0.7, 2, /* ceil  */ \
    		1,  1.753, 0.05, 0.87, 3500.0, 0.5, 0.7, 2, /* floor */ \
    		1, 15.220, 0.05, 0.87, 5000.0, 0.8, 0.7, 2, /* front */ \
    		1,  9.317, 0.05, 0.87, 5000.0, 0.8, 0.7, 2, /* back  */ \
    		1, 17.545, 0.05, 0.87, 5000.0, 0.8, 0.7, 2, /* right */ \
    		1, 12.156, 0.05, 0.87, 5000.0, 0.8, 0.7, 2  /* left  */

    	instr 1

    /* some source signal */

    a1      phasor 150              ; oscillator
    a1      butterbp a1, 500, 200   ; filter
    a1      =  taninv(a1 * 100)
    a2      phasor 3                ; envelope
    a2      mirror 40*a2, -100, 5
    a2      limit a2, 0, 1
    a1      =  a1 * a2 * 9000

    kazim   line 0, 2.5, 360        ; move sound source around
    kdist   line 1, 10, 4           ; distance

    ; convert polar coordinates
    kX      =  sin(kazim * 3.14159 / 180) * kdist
    kY      =  cos(kazim * 3.14159 / 180) * kdist
    kZ      =  0

    a1      =  a1 + 0.000001 * 0.000001     ; avoid underflows

    imode   =  2    ; change this to 3 for 8 spk in a cube,
    		; or 1 for simple stereo

    aW, aX, aY, aZ  spat3d a1, kX, kY, kZ, 1.0, 1, imode, 2, 2

    aW      =  aW * 1.4142

    ; stereo
    ;
    ;aL     =  aW + aY              /* left                 */
    ;aR     =  aW - aY              /* right                */

    ; quad (square)
    ;
    aFL     =  aW + aX + aY         /* front left           */
    aFR     =  aW + aX - aY         /* front right          */
    aRL     =  aW - aX + aY         /* rear left            */
    aRR     =  aW - aX - aY         /* rear right           */

    ; eight channels (cube)
    ;
    ;aUFL   =  aW + aX + aY + aZ    /* upper front left     */
    ;aUFR   =  aW + aX - aY + aZ    /* upper front right    */
    ;aURL   =  aW - aX + aY + aZ    /* upper rear left      */
    ;aURR   =  aW - aX - aY + aZ    /* upper rear right     */
    ;aLFL   =  aW + aX + aY - aZ    /* lower front left     */
    ;aLFR   =  aW + aX - aY - aZ    /* lower front right    */
    ;aLRL   =  aW - aX + aY - aZ    /* lower rear left      */
    ;aLRR   =  aW - aX - aY - aZ    /* lower rear right     */

    	outq aFL, aFR, aRL, aRR

    	endin

    </CsInstruments>
    <CsScore>

    /* Written by Istvan Varga */
    t 0 60
    i 1 0 10
    e

    </CsScore>
    </CsoundSynthesizer>

## Voir aussi

spat3di, spat3dt

## Crédits

Auteur : Istvan Varga
2001

Nouveau dans la version 4.12

Mis à jour en avril 2002 par Istvan Varga

Prev | Up | Next
space | Home | spat3di