Csound Csound-dev Csound-tekno Search About

Re: 3D Sound Opcode?

Date1997-04-14 05:17
FromStephen Barrass
SubjectRe: 3D Sound Opcode?
hi hans and csound

>It might be nice to have an opcode which would generate a stereo pair of =
>audio signals given coordinates (x,y,z) for a source and a listener, the =
>direction the listener is facing and optionally the direction of the sour=
>ce and an audio source.  Considerations could be made for left/right volu=
>me, filtering effects and doppler effects and possibly others.  This woul=
>d allow for functions which generate complex orbits to move sounds throug=
>h space.

well here is an orchestra for spatial audio through stereo
pan that takes polar coords (azimuth, elevation, distance)

it does a pseudo hrtf by roughly simulating a head shadow attenuation of
loudness and high freqs, ear directions, and inter-aural delay
it works ok - but the sounds always seem to be behind your head
instead of in front ... a common problem in spatial displays i believe

i know that hrtf code has been added to recent versions of csound
but i havent tried that yet - i guess it is much better than this
anyway it might interest some people so here it is
(btw it requires whittles zak opcodes)

stephen

--------------------------------------------------------------------------------
stephen.barrass@cmis.csiro.au                                     @   *     ~
ftp://ftp.cbr.dit.csiro.au/staff/stephen/stephen.html           whiz pop splash

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
; headspins.orc
; s.barrass july 95
; 
;
; 24 tracks of 3d sound
; uses binaural delay, low-pass filter and amplitude
; to provide rough position and distance cues
;
; uses the zak gen to do array routing
;
sr = 22050
kr = 22050
ksmps = 1
nchnls = 2

; global        ------------------------------------------------
ginyq = sr*0.4
gipi = 3.14159265
giattack = 0.005
girelease = 0.005

; channels
gichannels = 24
zakinit gichannels,gichannels

; pseudo HRTF
gidelaymax = 0.001
gidelaymid = gidelaymax/2.0
gidelaymin = 0.0001
gifmin = 2.0/gidelaymax
gifscale = ginyq/2.171
; pinnae notch cue
ginotchf = 11000
ginotchw = 200

giamplut = 90                   ; distance-to-amplitude lookup table

; angle of the ear relative to the side of the head (in degrees)
giearangle = 10
; ellipse
gie = 0.6                       ; eccentricity
gik = (1-gie)/gie               ; normalise

;
; cable
; plug a sound into a channel
; instr start   dur     channel patch   pitch
;
;=======================================================
; channel                                                                 
instr   1

; input parameters              ---------------------------------------------
idur = p3                                                                    
ich = p4                        ; channel
ipatch = p5                     ; patch                                      
ipitch = p6                     ; pitch octave.class format 8.00 = middle C  
; derived parameters            ---------------------------------------------
ifroot = cpspch(ipitch)         ; root frequency in hz                       
print idur, ich, ipatch, ipitch, ifroot                                               
        
kamp    linen  1, giattack, idur, girelease ; declicking envelope
ivib    iunirand 20		; random vibrato frequency
print 	ivib
avib    oscil  4,ivib+20,91         ; vibrato
ach     oscil  1, ifroot+avib, ipatch
zaw     ach, ich                ; route to the z channel
endin

; this placer uses the declick envelope
; placer
; place a channel in the scene
; and write to stereo output
;
;
; instr start   dur     channel distance        angle   height

instr   3

; input parameters              ----------------------------------------
idur = p3                                                               
ach      zar p4                 ; channel to play
idistance = p5                  ; distance 0 to 127 metres              
iangle = p6                     ; angle 0_360 degrees where 0 = right hand
iheight = p7                    ; height -10_10 below_level_above       
print idur,idistance,iangle,iheight                                     

; derived parameters            ----------------------------------------
idb     table   idistance, giamplut     ; convert distance-to-amplitude 
iamp = ampdb(idb)                                                       
irevtime = idistance/5                  ; reverb in seconds
iradians = iangle*2*gipi/360            ; convert degreees-to-radians   
print idb, iamp, iradians, irevtime                                               

; delay                                                                 
ix = cos(iradians)                                                      
idelay = abs(ix)*gidelaymax + gidelaymin

irdelay = (ix < 0 ? idelay : gidelaymin)
ildelay = (ix < 0 ? gidelaymin : idelay)
						 
print ix, idelay, ildelay, irdelay                                              
; approx HRTF using elliptical functions for each ear                   
; right ear                                                             
irearangle = iangle-giearangle                                          
irhrtf = gik*gie/(1-gie*cos(irearangle*2*gipi/360))                     

; left ear                                                              
ilearangle = iangle-180+giearangle                                      
ilhrtf = gik*gie/(1-gie*cos(ilearangle*2*gipi/360))                     

print ilhrtf,irhrtf                                                     

; k-rate                ------------------------------------------------ 
; de-clicking envelope 
kamp linen iamp, giattack, idur, girelease

; a-rate                ------------------------------------------------

; distance related reverb
;arev   reverb ach, irevtime

; angle positioning by binaural delay                                  
; note : there really should be frequency dependence here...            
; used fixed delay lines because deltap is stuffed !
al0 = ach*ilhrtf
al1   delay   al0, ildelay
ar0 = ach*irhrtf                                                  
ar1   delay   ar0, irdelay                                           

; attenuate upper frequencies for head shadow                           
al2  tone    al1, exp(ilhrtf)*gifscale                                  
ar2  tone    ar1, exp(irhrtf)*gifscale                                 

; put in a frequency notch as a pinnae cue
;al3    areson al0, ginotchf, ginotchw
;ar3    areson ar0, ginotchf, ginotchw

dispfft al2, 0.3, 1024
dispfft ar2, 0.3, 1024

outs    al2*kamp, ar2*kamp                       

endin

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
; headspins.sco
; s.barrass july 95
; 
;
f1  0 2049 11 8			; buzz
f90 0 128 -5 100 126 30 1	; loudness exponential
f91 0 1025 10 1			; sin

; source
; start up each sound source
;i1	start	dur	channel	  ftable   pitch
;                         1..24    1..16    octave.class
;
;=======================================================
i1      0        3      1         1       6.00
;i1      0        3      2         1       7.01

; spin each sound source around
;instr	start	dur	channel	dist	angle	height

i3	0	0.3	2	30	0	0
i3	+	.	.	.	>	0
i3	+	.	.	.	>	0
i3	+	.	.	.	>	0
i3	+	.	.	.	>	0
i3	+	.	.	.	>	0
i3	+	.	.	.	>	0
i3	+	.	.	.	>	0
i3	+	.	.	.	>	0
i3	+	.	.	.	360	0
e