sr = 44100
kr = 4410
ksmps = 10
nchnls = 2 ; set to 2 channels for listening, set to 9 channels for encoding the files
; setting it to 9 generates ambisonic encoded files only to be decoded later.
zakinit 49, 60 ; isizea, isizek
#define FILE #Filename-# ;insert filename here
#define HEADER #aif# ;insert filetype here
gifrontwall= 1.6 ; position of frontwall at the x-axis [units]
gisidewall=1.3 ; position of sidewall at the y-axis [units]
giceiling= 1.1 ; height of the ceiling measured from the zero-point of the coordinate-system [units]
giunit= 4 ; radius of the "unit- sphere" (distance of the speaker from the center- point [m])
girescale= 1 ; no amplitude scaling for test decoding
; girescale= ; amplitude scaling for 2chnl decoding
; girescale= ; amplitude scaling for 9-chnl encoding
giformat= 2 ; 1 = 16 bit integers without header (binary PCM multichannel file) for "fout"
; 2 = 16-bit integers with a header. The header type depends on the render format. The default header type is the IRCAM format.
; If the user chooses the AIFF format (using the -A flag), the header format will be a AIFF type. If the user chooses the WAV
; format (using the -W flag), the header format will be a WAV type. For "fout".
; 4 = 16-bit short integers for soundout.
; 8 = 24 bit integer with header like specified in options . For "fout".
; *******************************************************************************************************************************
; Version 1.1 , Mar 2006 coded 1999-2006 by Jan Jacob Hofmann
; jjh@sonicarchitecture.de +++ http://www.sonicarchitecture.de
; Comments and suggestions welcome.
; For non-comercial, artistic, scientific and educational use only - all rights reserved
; *******************************************************************************************************************************
; This is a sequence of instruments for periphonic spatialisation of any sound input using the 2nd order Ambisonics
; and the Furse- Malham set of equations. It was conceived and coded 1999-2005 by Jan Jacob Hofmann.
; The Instrument is able to spatialize up to 20 soundsources simultaneously (this can be enhanced). To each
; source a trajectory is assigned, so independent movement of the sounds is possible.
; Besides assigning a position in space via Ambisonics, several distance clues are coded separately to enhance
; the perception of distance and depth. These are: lowpassfiltering according to distance, attenuation
; according to distance, ratio of global and local reverb, ratio of reverberated and direct sound, first 6 specular
; early reflections with position and energy of reflections changing according to the position of the sound in space,
; first 6 diffuse early reflections with position and energy of reflections changing according to the position of the sound in space.
; The early reflections also do increase the transparency of the perceived image. Also Doppler Frequency Shift is
; applied to the source.
; Remember that distribution of the sound works best with multi- speaker arrays. You do definitely need more than
; two speakers, this is not binauralisation, which would work with headphones and only two channels. Minimum for panphony
; is 4 speakers, although 5 are recomended. For periphony the minimum is an eight speakers cube, but twelve speakers
; are highly recomended. The speakers have to be same type, in-phase, and at the exact geometric location for which the decoding
; was made for.
; Setting up the test
; To get a quick overview please use the soundfile "test1" (e.g. Dr. Boulangers Speech)
; and put them into the "Sound Sample Directory". Now make 7 copies of the file "Test1" and
; name them "test2" through "test8". They represent your audio tracks to be fed into the "Soundfile Reader". Then set the number
; of decoding- channels ("nchnls ") to "2" for stereo listening .
; make sure that you specify for every track a continouus trajectory in Instr. 42/46
; Now render. If you have chosen more speakers than two, it is important to pass the generated encoded files to the decoder (see "Ambidec.orc")
; and decode according to your listening conditions (stereo? eight speakers? sixteen?). it shoud generate files that
; can be read by your sound editor. Import them into your editor and assign the channels to the speakers according to the position
; of the speaker. See "Ambidec.orc" for correct assignment. Now play the soundfiles simultaneously, each feeding one speaker.
; How to use this orchestra
; This orchestra works in several steps:
; - First a trajectory is generated (xyz is converted to angle, elevation and distance automatically by instr. 42)
; - Optional: trajectory may be modulated (instr 47 +48)
; - the soundfile is read, Doppler shift is applied (instr 50)
; - Local reverb is generated (instr 60)
; - The sound is spatially encoded, local reverb is added to the sound (instr 72)
; - Global reverb is added
; - Early reflections are added (instr 74+75)
; - Sound is collected and written to disk (instr 80)
; You may read up to 16 tracks into the orchestra simultaneously. The name of the track has to be specified in instr 50.
; To each track you have to generate a trajectory by using either Cartesian coordinates (instr. 40) or polar co-ordinates (instr 46).
; You may divide up the total time of the soundfile for several trajectories and positions in space, but these must sum up at the end to
; an equivalent to the total duration of the track processed. There must be neither overlaps nor gaps in the sequence of trajectories generated,
; one trajectory should follow the other. you may modulate any trajectory by any amount using the "Modulator" (instr. 47) or the
; Randomiser (instr. 48) This modulation may be used at any time. Also multiple instances of this modulations are possible to generate
; complex movements in space automatically by the sum of the modulating waveforms. Instr. 50 is the soundfile reader, you can specify the
; duration and track -number of the soundfile to be processed. This Instrument also triggers the local reverb and the first reflections (Instr. 74 and 75)
; adjust the parameters to taste.
; Instr. 73 is the Global Spatial Reverb. Reverberation occurs from 12 different positions in space, equaly distributed at the unit-sphere. It also
; triggers the output (Instr. 80), so make sure it is running all the time.
; Instr 74 and 75 do add specular and diffuse early reflections, also spatially distributed to each track independently. To save computing
; time these instruments should be activated only for the final rendering.
; Note: The output soundfiles may distort. You can scale them by dividing 32768 by the highest peak of them and put the result into
; "girescale", close to the header.
; **************************************************************************************
; Please send comments and bug reports to jjh@sonicarchitecture.de on http://www.sonicarchitecture.de you will also find a small Ambisonic-tutorial.
; More info:
; To find out more about Ambisonics, see
; http://www.ambisonic.net/
; http://www.york.ac.uk/inst/mustech/3d_audio/ambison.htm (University of York)
; http://www.york.ac.uk/inst/mustech/3d_audio/ambison.htm (Richard Furse's pages)
; Credits:
; Thanks to Richard Furse and Dave Malham for the wonderful 2nd order equations. Also special thanks to Nora Bluhme,
; Ingo Herwig and Christoph Schuller for helping me with the math. Last not least thanks to all csounders who made this
; possible by their contribution of work and thoughts!!!
; **************************************************************************************
instr 40 ; x,y,z -READER coded 1999-2001 by Jan Jacob Hofmann.
; **************************************************************************************
itracknr= p4
ixstart = p5
ixend = p6
ixmodfn = abs(p6) ; modulation function input
ixmoddir = p6 / ixmodfn ; negative fn causes backwards reading
ixmovefn = abs(p7) ; x movement function nr
ixmovedir = p7 / ixmovefn ; negative fn causes backwards reading
ixmodfn = abs (p8) ; fn for modulation
ixmoddir = p8 / ixmodfn ; negative fn causes backwards reading
ixmodfncps = p9 ; x movement function cps
ixmodfactor = p10 ; x ammount of movement
iystart = p11
iyend = p12
iymovefn = abs(p13) ; y movement function nr
iymovedir = p13 / iymovefn ; negative fn causes backwards reading
iymodfn = abs(p14) ; fn for modulation
iymoddir = p14 / iymodfn ; negative fn causes backwards reading
iymodfncps = p15 ; y movement function cps
iymodfactor = p16 ; y ammount of movement
izstart = p17
izend = p18
izmovefn = abs(p19) ; z movement function nr
izmovedir = p19 / izmovefn ; negative fn causes backwards reading
izmodfn = abs(p20) ; fn for modulation
izmoddir = p20 / iymodfn ; negative fn causes backwards reading
izmodfncps = p21 ; z movement function cps
izmodfactor = p22 ; z ammount of movement
schedule 42, 0, p3, itracknr ; instrument invocation of the x,y,z- converter
kdclck linseg 0 , 0.05, 1, p3 -0.1, 1, 0.05, 0 ; smooth out abrupt change of position
; reading unit
ixdiff = ixend - ixstart
kxpos oscil ixdiff, ixmovedir * (1/p3), ixmovefn ; x position change during note
kxpos = ixstart + kxpos
kxmod oscil ixmodfactor * kdclck, ixmoddir * ixmodfncps, ixmodfn ; reads the function table
kx = kxpos + kxmod
iydiff = iyend - iystart
kypos oscil iydiff, iymovedir * (1/p3), iymovefn ; y position change during note
kypos = iystart + kypos
kymod oscil iymodfactor * kdclck,iymoddir * iymodfncps, iymodfn ; reads the function table
ky = kypos+ kymod
izdiff = izend - izstart
kzpos oscil izdiff, izmovedir *(1/p3), izmovefn ; z position change during note
kzpos = izstart + kzpos
kzmod oscil izmodfactor * kdclck, izmoddir * izmodfncps, izmodfn ; reads the function table
kz = kzpos + kzmod
; global output unit
zkw kx, itracknr ; read global x-value
zkw ky, itracknr + 20 ; read global y-value
zkw kz, itracknr + 40 ; read global z-value
endin
; ************************************************************************************************
instr 42 ; x, y, z -CONVERTER coded 1999-2001 by Jan Jacob Hofmann. Thanks to Christoph
; ************************************************************************************************
itracknr = p4
; input unit:
kx zkr itracknr ; read global x-value
ky zkr itracknr + 20 ; read global y-value
kz zkr itracknr + 40 ; read global z-value
kx = (kx < 0.01 && kx > -0.01 ? 0.01 : kx) ; fix for that strange y-axis noise
; Distance calculation
kD = sqrt( kx^2 + ky^2 + kz^2) ; calculates the distance
kx = kx / kD ; this operation generates a vector equivalent at the unit sphere
ky = ky / kD ; this operation generates a vector equivalent at the unit sphere
kz = kz / kD ; this operation generates a vector equivalent at the unit sphere
kD = (kD < 0.3 ? 0.3 : kD) ; limits kD to a minimum of 0.3 unit to prevent overflow
; Elevation calculation
kE = cosinv ( sqrt( 1 - kz^2)) ; calculation of Elevation
kE = ( kz < 0 ? -kE : kE) ; if z is negative make Elevation- vector negative too
; Angle calculation
kA = sininv (ky/ cos (kE)) ; calculation of Angle
kA = (kx >= 0 ? kA : 3.1415 - kA) ; distinction of positive and negative y
kA = (ky <= 0 && kx >= 0 ? 6.2831 + kA : kA) ; distinction of positive and negative y and x
; global output unit
zkw kA, itracknr ; sends out global A value
zkw kE, itracknr + 20 ; sends out global E value
zkw kD, itracknr + 40 ; sends out global D value
endin
; *****************************************************************************************
instr 46 ; A,E,D - MOVEMENT SCORE READER coded 1999-2001 by Jan Jacob Hofmann
; *****************************************************************************************
itracknr = p4
iAstart = p5 * (6.283 / 360) ; convert 0-360 degrees to ¹-expression
iAend = p6 * (6.283 / 360) ; convert 0-360 degrees to ¹-expression 2¹= 6.28318530717959648
iAdiff = iAend - iAstart
iAmovefn = abs(p7) ; A movement function nr
iAmovedir = p7 / iAmovefn ; negative fn causes backwards reading
iAmodfn = abs(p8)
iAmoddir = p8 / iAmodfn ; negative fn causes backwards reading
iAfncps = p9 ; A movement function cps
iAfactor = (p10 < 6.29 ? p10 : p10 * (6.283 /360)) ; A ammount of movement
iEstart = p11 * ( 3.1415/180) ; convert 90- (-90)degrees to ¹-expression
iEend = p12 * ( 3.1415/180) ; convert 90- (-90)degrees to ¹-expression
iEdiff = iEend - iEstart
iEmovefn = abs(p13)
iEmovedir = p13 / iEmovefn
iEmodfn = abs(p14) ; E movement function nr
iEmoddir = p14 / iEmodfn ; negative fn causes backwards reading
iEmodfncps = p15 ; E movement function cps
iEfactor = ( abs(p16) < 3.15 ? p16 : p16 * ( 3.1415/180)) ; E ammount of movement as a factor or in degrees
iDstart = p17
iDend = p18
iDdiff = iDend - iDstart
iDmovefn = abs(p19)
iDmovedir = p19 / iDmovefn ; negative fn causes backwards reading
iDmodfn = abs(p20)
iDmoddir = p20 / iDmodfn
iDfncps = p21
iDfactor = p22
kdclck linseg 0 , 0.05, 1, p3 -0.1, 1, 0.05, 0 ; smooth out abrupt change of position
kA oscil iAdiff, iAmovedir * (1/p3), iAmovefn ; Angle position change during note
kA = iAstart + kA ; calculates the way from point a to point b
kAmod oscil iAfactor * kdclck, iAmoddir * iAfncps, iAmodfn ; reads the function table
kA = kA+ kAmod ; modulates the way of the source from a to b
kE oscil iEdiff, iEmovedir * (1/p3), iEmovefn ; Elevation position change during note
kE = iEstart + kE ; calculates the way from point a to point b
kEmod oscil iEfactor * kdclck, iEmoddir * iEmodfncps, iEmodfn ; reads the function table
kE = kE + kEmod
kD oscil iDdiff, iDmovedir*(1/p3), iDmovefn ; generates the movement of kD
kD = iDstart + kD
kDmod oscil iDfactor * kdclck, iDmoddir * iDfncps, iDmodfn ; reads the function table
kD = kD + kDmod ; modulates the way of the source from a to b
kD = abs(kD) ; kD may only be positive
kD = (kD < 0.3 ? 0.3 : kD) ; limits kD to a minimum of 0.3 unit to prevent overflow
; global output unit
zkw kA, itracknr ; sends out global A value
zkw kE, itracknr + 20 ; sends out global E value
zkw kD, itracknr + 40 ; sends out global D value
endin
; **************************************************************************************
instr 47 ; AED- MODULATOR coded 1999-2001 by Jan Jacob Hofmann.
; **************************************************************************************
; mode1 = Angle modulation
; mode2 = Elevation modulation
; mode3 = Distance modulation
itracknr = p4
imode = p5
imodfn = abs(p6) ; AED-movement function nr
imoddir = p6 / imodfn ; negative fn causes backwards reading
imodfncps = p7 ; AED movement function cps
imodamt = (imode = 3 ? p8 : p8 * (6.283 / 360)) ; convert 0-360 degrees to ¹-expression if it is an A or D value
itracknr = itracknr + (imode * 20 - 20)
kdclck linseg 0 , 0.05, 1, p3 -0.1, 1, 0.05, 0 ; smooth out abrupt change of position
kmod oscil imodamt * kdclck,imoddir * imodfncps,imodfn ; create a modulating source
kAED zkr itracknr ; read angle, elevation, distance from the global output
; of the movement score reading instrument or xyz-converter
; according to mode: 1= kA, 2=kE, 3=kD
zkw kmod, 0 ; send modulation source to k-channel 0
kAED zkmod kAED, 0 ; apply modulation from k-channel 0 on kAED
kAED = (imode = 2 && kAED > 90 ? 90 : kAED) ; limit elevation to a maximum of 90 degree
kAED = (imode = 2 && kAED < -90 ? -90 : kAED) ; limit elevation to a maximum of 90 degree
kAED = (imode = 3 && kAED < 0.3 ? 0.3 : kAED) ; limit Distance to a minimum of 0.3unit
zkw kAED, itracknr ; sends out global A, E or D value,
endin
; **************************************************************************************
instr 48 ; AED RANDOMIZER coded 1999-2001 by Jan Jacob Hofmann.
; **************************************************************************************
itracknr = p4
imode = p5
; mode1 = Angle modulation
; mode2 = Elevation modulation
; mode3 = Distance modulation
imodamt = (imode = 3 ? p6 : p6 * (6.283 /360)) ; convert 0-360 degrees to ¹-expression if it is an A or D value
imodamtfn = abs(p7) ; AED-movement function nr
imodamtdir = p7 / imodamtfn ; negative fn causes backwards reading
irandcps = p8 ; AED movement function cps
imodcpsfn = abs(p9)
imodspedir = p9 / imodcpsfn ; negative fn causes backwards reading
iseed = p10
itracknr = itracknr + (imode * 20 - 20)
kdclck linseg 0 , 0.05, 1, p3 - 0.1, 1, 0.05, 0 ; smooth out abrupt change of position
kmodamt oscil imodamt * kdclck, imodamtdir * (1 / p3), imodamtfn ; change modulationamount during note
kmodcps oscil irandcps, imodspedir * (1 / p3), imodcpsfn ; change random speed during note
krand randi kmodamt,kmodcps, iseed ; create a modulating source
krand = krand -.5 * kmodamt ; shift the range also to the negative
kAED zkr itracknr ; read angle, elevation, distance from the global output
; of the movement score reading instrument or xyz-converter
; according to mode: 1= kA, 2=kE, 3=kD
zkw krand, 0 ; send modulation source to k-channel 0
kAED zkmod kAED, 0 ; apply modulation from k-channel 0 on kAED
kAED = (imode = 2 && kAED > 90 ? 90 : kAED) ; limit elevation to a maximum of 90 degree
kAED = (imode = 2 && kAED < -90 ? -90 : kAED) ; limit elevation to a maximum of 90 degree
kAED = (imode = 3 && kAED < 0.3 ? 0.3 : kAED) ; limit Distance to a minimum of 0.3
zkw kAED, itracknr ; sends out global A, E or D value
endin
; ****************************************************************************************
instr 50 ; SOUNDFILE READER (with processing unit) coded 1999-2001 by Jan Jacob Hofmann
; ****************************************************************************************
itracknr = p4
igainfactor = p5
iskiptime = p6
ireverbsend = p7 ; amount of direct signal sent to local + global reverb
girvbdecay = p8 ; reverbdecay for local + global reverb
girandpchmod = p9 ; randomized pitch modulation for local + global reverb
gicutofffreq = p10 ; cutofffreq for local + global reverb
ilocalrev = p11
idiffref = p12
ispecref = p13
kA zkr itracknr ; take angle from the global output of the movement score reading instrument or other
kE zkr itracknr + 20 ; take elevation from the global output of the movement score reading instrument or other
kD zkr itracknr + 40 ; take distance from the global output of the movement score reading instrument or other
kDrev = 1 / kD
kDrev = (kD < 1 ? 1 : kDrev ) ; keeps 1/kD < 1
kpitch init 1.00 ; initialisation of kpitch($T.) at i-time-pass
; INSTRUMENT INVOCATION UNIT
schedule 70, 0, p3 + iskiptime, itracknr ; invocation of the sound encoder
if ilocalrev == 0 goto diffref ; skip (switch off) the local reverb
schedule 60, 0, p3 + iskiptime, itracknr ; invocation of the local reverb
diffref:
if idiffref == 0 goto specref ; skip (switch off) the diffuse reflections
schedule 74, 0, p3 + iskiptime, itracknr ; invocation of diffuse early reflections
specref:
if ispecref == 0 goto reading ; skip (switch off) the specular reflections
schedule 75, 0, p3 + iskiptime, itracknr ; invocation of specular early reflections
reading:
;READING UNIT ; the mono soundfiles from the editor are imported here
#define READING(T) # ; define macro for the reader
kpitch limit kpitch, 0.3, 2 ; prevent clicks and pops
adry diskin "$FILE$T.", kpitch, iskiptime ; importing monotrack ($T.)
goto contin
#
if itracknr = 1 goto track1
if itracknr = 2 goto track2
if itracknr = 3 goto track3
if itracknr = 4 goto track4
if itracknr = 5 goto track5
if itracknr = 6 goto track6
if itracknr = 7 goto track7
if itracknr = 8 goto track8
if itracknr = 9 goto track9
if itracknr = 10 goto track10
if itracknr = 11 goto track11
if itracknr = 12 goto track12
if itracknr = 13 goto track13
if itracknr = 14 goto track14
if itracknr = 15 goto track15
if itracknr = 16 goto track16
if itracknr = 17 goto track17
if itracknr = 18 goto track18
if itracknr = 19 goto track19
if itracknr = 20 goto track20
track1:
$READING(1) ; import the source
track2:
$READING(2) ; import the source
track3:
$READING(3) ; import the source
track4:
$READING(4) ; import the source
track5:
$READING(5) ; import the source
track6:
$READING(6) ; import the source
track7:
$READING(7) ; import the source
track8:
$READING(8) ; import the source
track9:
$READING(9) ; import the source
track10:
$READING(10) ; import the source
track11:
$READING(11) ; import the source
track12:
$READING(12) ; import the source
track13:
$READING(13) ; import the source
track14:
$READING(14) ; import the source
track15:
$READING(15) ; import the source
track16:
$READING(16) ; import the source
track17:
$READING(17) ; import the source
track18:
$READING(18) ; import the source
track19:
$READING(19) ; import the source
track20:
$READING(20) ; import the source
contin:
#undef READING(T)
; SCALING AND DELAYING UNIT
; this unit is based upon the example in the Charles Dodge/Thomas Jerse book, Computer Music, page 320
; attenuation according to distance and ratio of reverberation/direct signal according to distance is applied to the sound material of each track.
adry = adry * igainfactor * girescale ; scaling of dry signal
arevsend = adry * sqrt(kDrev) * ireverbsend ; scaling according to distance and gaincontrol
irevdel = giunit * gifrontwall * 0.00293255132 ; caculation of time of a reflection (reverb) traveling from the wall to the center [s]
arevsend delay arevsend, irevdel ; feeding a delayed signal to global reverbsend to simulate the size of the room
; by delaying the response of the room according to its size
aglrevsend = arevsend * kDrev ; ratio between global and local reverb
zaw aglrevsend, 0 ; global reverb send gets written to Zak-channel 0
if ilocalrev = 0 goto processing ; no local reverb send if localreverb is switched off
arev = arevsend * (1 - kDrev) ; ratio between global and local reverb
zaw arev, itracknr + 20 ; local reverb send to Zak- channel 21-40
processing:
; FILTERING UNIT [distance]
adry = adry * kDrev ; scaling of dry signal acording to distance
afilt butterlp adry, 22000 * sqrt(kDrev) ; filtering according to distance
afilt balance afilt, adry
zaw afilt, itracknr ; audio zak-output
; DOPPLER SHIFT CALCULATION
; calculation of velocity
; Note: giunit = distance from a listener in the middle to the unit sphere in meters
aD interp kD
aDdelayed delay aD, 0.01 ; delay distance - amount for 100 ms
kV downsamp aDdelayed - aD ; calculate the difference of distances
kV = (kV * giunit) * 100 ; speed in m/s
; calculation of doppler
kpitch = 345 / (345 - kV)
endin
; **************************************************************************************
#define LocalGlobalREVERB ; define LOCAL ( TRACK APPLIED) and GLOBAL REVERB #
; 8 delay line FDN reverb, with feedback matrix based upon
; physical modeling scattering junction of 8 lossless waveguides
; of equal characteristic impedance. Based on Julius O. Smith III,
; "A New Approach to Digital Reverberation using Closed Waveguide
; Networks," Proceedings of the International Computer Music
; Conference 1985, p. 47-53 (also available as a seperate
; publication from CCRMA), as well as some more recent papers by
; Smith and others.
;
; Coded by Sean Costello, October 1999/ modified by Jan Jacob Hofmann August 2005
; Note: arevsig is the global input to the reverb.
afilt1 init 0
afilt2 init 0
afilt3 init 0
afilt4 init 0
afilt5 init 0
afilt6 init 0
afilt7 init 0
afilt8 init 0
afilt9 init 0
afilt10 init 0
afilt11 init 0
afilt12 init 0
; Delay times chosen to be prime numbers.
; Works with sr=44100/ sr=48000 ONLY. If you wish to
; use a different delay time, find some new
; prime numbers that will give roughly the
; same delay times for the new sampling rate.
; Or adjust to taste.
if sr = 48000 goto delaytime48000 ; delaytime chosen for sr=44100
idel1 = (1237.000 / sr)
idel2 = (1381.000 / sr)
idel3 = (1609.000 / sr)
idel4 = (1777.000 / sr)
idel5 = (1951.000 / sr)
idel6 = (2063.000 / sr)
idel7 = (1069.000 / sr)
idel8 = ( 967.000 / sr)
idel9 = (1889.000 / sr)
idel10 = (1693.000 / sr)
idel11 = (1453.000 / sr)
idel12 = (1291.000 / sr)
goto contin
delaytime48000: ; delaytime for sr=48000
idel1 = (1361.000/sr)
idel2 = (1499.000/sr)
idel3 = (1753.000/sr)
idel4 = (1933.000/sr)
idel5 = (2129.000/sr)
idel6 = (2243.000/sr)
idel7 = (1163.000/sr)
idel8 = (1051.000/sr)
idel9 = (2053.000/sr)
idel10 = (1693.000/sr)
idel11 = (1847.000/sr)
idel12 = (1409.000/sr)
contin:
igain = girvbdecay ; gain of reverb. Adjust empirically
; for desired reverb time. .6 gives
; a good small "live" room sound, .8
; a small hall, .9 a large hall,
; .99 an enormous stone cavern.
ipitchmod = girandpchmod ; amount of random pitch modulation
; for the delay lines. 1 is the "normal"
; amount, but this may be too high for
; held pitches such as piano tones.
; Adjust to taste.
itone = gicutofffreq ; Cutoff frequency of lowpass filters
; in feedback loops of delay lines,
; in Hz. Lower cutoff frequencies results
; in a sound with more high-frequency
; damping.
; k1-k8 are used to add random pitch modulation to the
; delay lines. Helps eliminate metallic overtones
; in the reverb sound.
k1 randi .001, 3.1, .06
k2 randi .0011, 3.5, .9
k3 randi .0017, 1.11, .7
k4 randi .0006, 3.973, .3
k5 randi .001, 2.341, .63
k6 randi .0011, 1.897, .17
k7 randi .0017, 0.891, .19
k8 randi .0006, 3.221, .44
k9 randi .001, 1.891, .88
k10 randi .0011, 2.317, .95
k11 randi .0017, 1.091, .36
k12 randi .0006, 2.821, .41
; apj is used to calculate "resultant junction pressure" for
; the scattering junction of e.g. 8 lossless waveguides
; of equal characteristic impedance. If you wish to
; add more delay lines, simply add them to the following
; equation, and replace the .25 by 2/N, where N is the
; number of delay lines.
apj = .16666666667 * (afilt1 + afilt2 + afilt3 + afilt4 + afilt5 + afilt6 +afilt7 + afilt8 + afilt9 + afilt10 +afilt11 + afilt12)
adum1 delayr 1
adel1 deltapi idel1 + k1 * ipitchmod
delayw arevsig + apj - afilt1
adum2 delayr 1
adel2 deltapi idel2 + k2 * ipitchmod
delayw arevsig + apj - afilt2
adum3 delayr 1
adel3 deltapi idel3 + k3 * ipitchmod
delayw arevsig + apj - afilt3
adum4 delayr 1
adel4 deltapi idel4 + k4 * ipitchmod
delayw arevsig + apj - afilt4
adum5 delayr 1
adel5 deltapi idel5 + k5 * ipitchmod
delayw arevsig + apj - afilt5
adum6 delayr 1
adel6 deltapi idel6 + k6 * ipitchmod
delayw arevsig + apj - afilt6
adum7 delayr 1
adel7 deltapi idel7 + k7 * ipitchmod
delayw arevsig + apj - afilt7
adum8 delayr 1
adel8 deltapi idel8 + k8 * ipitchmod
delayw arevsig + apj - afilt8
adum9 delayr 1
adel9 deltapi idel9 + k9 * ipitchmod
delayw arevsig + apj - afilt9
adum10 delayr 1
adel10 deltapi idel10 + k10 * ipitchmod
delayw arevsig + apj - afilt10
adum11 delayr 1
adel11 deltapi idel11 + k11 * ipitchmod
delayw arevsig + apj - afilt11
adum12 delayr 1
adel12 deltapi idel12 + k12 * ipitchmod
delayw arevsig + apj - afilt12
; 1st order lowpass filters in feedback
; loops of delay lines.
afilt1 tone adel1 * igain, itone
afilt2 tone adel2 * igain, itone
afilt3 tone adel3 * igain, itone
afilt4 tone adel4 * igain, itone
afilt5 tone adel5 * igain, itone
afilt6 tone adel6 * igain, itone
afilt7 tone adel7 * igain, itone
afilt8 tone adel8 * igain, itone
afilt9 tone adel9 * igain, itone
afilt10 tone adel10 * igain, itone
afilt11 tone adel11 * igain, itone
afilt12 tone adel12 * igain, itone
; The outputs of the delay lines are summed
; and sent to the stereo outputs. This could
; easily be modified for a 4 or 8-channel
; sound system.
arevsig sum afilt1 , afilt2 , afilt3 , afilt4 , afilt5 , afilt6 , afilt7 , afilt8, afilt9 , afilt10 , afilt11 , afilt12
#
; **************************************************************************************
; **************************************************************************************
instr 60 ; LOCAL ( TRACK APPLIED) REVERB with track nr as argument
; **************************************************************************************
p3 = p3 + 2 ; prolong duration to keep the reverb - tail
itracknr = p4
arevsig zar itracknr + 20
$LocalGlobalREVERB.
zaw arevsig, itracknr + 20
endin
; ******************************************************************************************************
instr 70 ;SOUND 9-CHNL ENCODING UNIT, 2nd ORDER AMBISONICS coded 1999-2005 by Jan Jacob Hofmann,
;using the Furse-Malham-Set (FMH) of encoding equations. Thanks to Dave Malham and Richard Furse
; ******************************************************************************************************
p3 = p3 + 2 ; prolong duration to keep the reverb - tail
itracknr = p4
kA zkr itracknr ; take angle from the global output of the movement score reading instrument or other
kE zkr itracknr + 20 ; take elevation from the global output of the movement score reading instrument or other
asig zar itracknr ; zak audio input
arevsig zar itracknr + 20 ; zak localreverb input
asig = asig + arevsig ; mixing asig with local reverb
;2nd order Ambisonics encoding equations
kchnlx = cos(kA) * cos(kE)
kchnly = sin(kA) * cos(kE)
kchnlz = sin(kE)
kchnlr = 1.5 * sin(kE) * sin(kE) -0.5
kchnls = cos(kA) * sin(2 * kE)
kchnlt = sin(kA) * sin(2 * kE)
kchnlu = cos(2 * kA) * cos(kE) * cos(kE)
kchnlv = sin(2 * kA) * cos(kE) * cos(kE)
kchnlw = 1 - 0.293 *(kchnlx^ 2 + kchnly^ 2 + kchnlz^2) ; fix w that it will remain constant
; SOUND ENCODING UNIT ASIG 1- ASIG n (encoding of the audio signal)
aw = asig * kchnlw ;(A,E)
ax = asig * kchnlx ;(A,E)
ay = asig * kchnly ;(A,E)
az = asig * kchnlz ;(A,E)
ar = asig * kchnlr ;(A,E)
as = asig * kchnls ;(A,E)
at = asig * kchnlt ;(A,E)
au = asig * kchnlu ;(A,E)
av = asig * kchnlv ;(A,E)
zawm aw, 41 ; rewrite and mix zak-location 41 with ambisonics w-channel output of Track 1-20
zawm ax, 42 ; rewrite and mix zak-location 42 with ambisonics x-channel output of Track 1-20
zawm ay, 43 ; rewrite and mix zak-location 43 with ambisonics y-channel output of Track 1-20
zawm az, 44 ; rewrite and mix zak-location 44 with ambisonics z-channel output of Track 1-20
zawm ar, 45 ; rewrite and mix zak-location 45 with ambisonics r-channel output of Track 1-20
zawm as, 46 ; rewrite and mix zak-location 46 with ambisonics s-channel output of Track 1-20
zawm at, 47 ; rewrite and mix zak-location 47 with ambisonics t-channel output of Track 1-20
zawm au, 48 ; rewrite and mix zak-location 48 with ambisonics u-channel output of Track 1-20
zawm av, 49 ; rewrite and mix zak-location 49 with ambisonics v-channel output of Track 1-20
endin
; **************************************************************************************
instr 73 ; SPATIAL GLOBAL REVERB conceived and coded 1999-2005 by Jan Jacob Hofmann
; using the Furse-Malham-Set (FMH) of encoding equations.
; **************************************************************************************
p3= p3+2 ; prolong duration to keep the reverb - tail
schedule 80, 0, p3 ; invocation of mixing and output
arevsig zar 0 ; reading global reverb send as written to Zak-channel 0 in instr. 50
$LocalGlobalREVERB.
; kA1-kA12 are the angles pointing to the 12 corners of an ikosaeder
; kE1-kE12 is the elevation pointing to the 12 corners of an ikosaeder
iA1 = 0 ; angle reverberant point 1
iA2 = 0.6238 ; angle reverberant point 2
iA3 = 1.2566 ; angle reverberant point 3
iA4 = 1.8849 ; angle reverberant point 4
iA5 = 2.5132 ; angle reverberant point 5
iA6 = 3.1415 ; angle reverberant point 6
iA7 = 3.7699 ; angle reverberant point 7
iA8 = 4.3982 ; angle reverberant point 8
iA9 = 5.0265 ; angle reverberant point 9
iA10 = 5.6548 ; angle reverberant point 10
iA11 = 0 ; angle reverberant point 11
iA12 = 0 ; angle reverberant point 12
iE1 = 0.463646 ; height reverberant point 1 ( 26.565¡)
iE2 = -0.463646 ; height reverberant point 2 ( -26.565¡)
iE3 = 0.463646 ; height reverberant point 3 ( 26.565¡)
iE4 = -0.463646 ; height reverberant point 4 ( -26.565¡)
iE5 = 0.463646 ; height reverberant point 5 ( 26.565¡)
iE6 = -0.463646 ; height reverberant point 6 ( -26.565¡)
iE7 = 0.463646 ; height reverberant point 7 ( 26.565¡)
iE8 = -0.463646 ; height reverberant point 8 ( -26.565¡)
iE9 = 0.463646 ; height reverberant point 9 ( 26.565¡)
iE10 = -0.463646 ; height reverberant point 10 ( -26.565¡)
iE11 = 1.570796 ; height reverberant point 11 ( 90¡)
iE12 = -1.570796 ; height reverberant point 12 ( -90¡)
#define GLOBALREVERBENCODING(W) #
kchnlx = cos(iA$W.) * cos(iE$W.)
kchnly = sin(iA$W.) * cos(iE$W.)
kchnlz = sin(iE$W.)
kchnlr = 1.5 * sin(iE$W.) * sin(iE$W.) -0.5
kchnls = cos(iA$W.) * sin(2 * iE$W.)
kchnlt = sin(iA$W.) * sin(2 * iE$W.)
kchnlu = cos(2 * iA$W.) * cos(iE$W.) * cos(iE$W.)
kchnlv = sin(2 * iA$W.) * cos(iE$W.) * cos(iE$W.)
kchnlw = 1 - 0.293 *(kchnlx^ 2+ kchnly^ 2)
aw = afilt$W. * kchnlw ;(A,E)
ax = afilt$W. * kchnlx ;(A,E)
ay = afilt$W. * kchnly ;(A,E)
az = afilt$W. * kchnlz ;(A,E)
ar = afilt$W. * kchnlr ;(A,E)
as = afilt$W. * kchnls ;(A,E)
at = afilt$W. * kchnlt ;(A,E)
au = afilt$W. * kchnlu ;(A,E)
av = afilt$W. * kchnlv ;(A,E)
zawm aw, 41 ; rewrite and mix zak-location 1 with ambisonics w-channel output of Track 1-16
zawm ax, 42 ; rewrite and mix zak-location 2 with ambisonics x-channel output of Track 1-16
zawm ay, 43 ; rewrite and mix zak-location 3 with ambisonics y-channel output of Track 1-16
zawm az, 44 ; rewrite and mix zak-location 4 with ambisonics z-channel output of Track 1-16
zawm ar, 45 ; rewrite and mix zak-location 5 with ambisonics r-channel output of Track 1-16
zawm as, 46 ; rewrite and mix zak-location 6 with ambisonics s-channel output of Track 1-16
zawm at, 47 ; rewrite and mix zak-location 7 with ambisonics t-channel output of Track 1-16
zawm au, 48 ; rewrite and mix zak-location 8 with ambisonics u-channel output of Track 1-16
zawm av, 49 ; rewrite and mix zak-location 9 with ambisonics v-channel output of Track 1-16
#
$GLOBALREVERBENCODING(1)
$GLOBALREVERBENCODING(2)
$GLOBALREVERBENCODING(3)
$GLOBALREVERBENCODING(4)
$GLOBALREVERBENCODING(5)
$GLOBALREVERBENCODING(6)
$GLOBALREVERBENCODING(7)
$GLOBALREVERBENCODING(8)
$GLOBALREVERBENCODING(9)
$GLOBALREVERBENCODING(10)
$GLOBALREVERBENCODING(11)
$GLOBALREVERBENCODING(12)
#undef GLOBALREVERBENCODING(W)
endin
#undef LocalGlobalREVERB
; **************************************************************************************************************************
instr 74 ; DIFFUSE EARLY REFLECTIONS conceived and coded 1999-2001 by Jan Jacob Hofmann, using the Furse-Malham-Set (FMH) of encoding equations.
; Thanks to Dave Malham and Richard Furse. Thanks to Ingo.
; Based on a Paper by David Griesinger published in the Proceedings of the 19th AES International Conference, June 2001.
; **************************************************************************************************************************
p3 = p3 + 0.5 ; prolong duration to keep the reverb - tail
itracknr = p4
; gifrontwall= position of frontwall at the x-axis
; gisidewall=position of sidewall at the y-axis
; giceiling =height of the ceiling measured from the zero-point of the coordinate-system
idamp = 0.1 ; damping factor of the reflecting surface (gain of reverb)
ihighdamp = 15000 ; absorbtion characteristics of the wall in respect to high frequencies: frequencies above ihighdamp get filtered out
ilfboost = 1 ; low frequency boost for sources near a wall
kA zkr itracknr ; take angle from the global output of the movement score reading instrument or other
kE zkr itracknr + 20 ; take elevation from the global output of the movement score reading instrument or other
kD zkr itracknr + 40 ; take distance from the global output of the movement score reading instrument or other
asig zar itracknr ; zak audio input
kA = (kA < 0 ? kA + 6.283185 : kA) ; prevent negative angle kA
kA = (kA > 6.283185 ? kA - 6.283185 : kA) ; prevent angle kA > 360¡
; Polar converter -source as cartesian representation
kx = kD * cos(kA) * cos(kE) ; Position of sound in kartesian coordinates
ky = kD * sin(kA) * cos(kE) ; Position of sound in kartesian coordinates
kz = kD * sin(kE) ; Position of sound in kartesian coordinates
kx = (kx < 0.01 && kx > -0.01 ? 0.01 :kx) ; fix for that strange y-axis noise
asig tone asig, ihighdamp ; filtering of high frequencies due to absorbtion characteristics of the wall
#define DIFFREFLECTION(R)#
icnt = $R.
; calculation of points of reflection
; frontwall= 1
; backwall = 2
; left sidewall =3
; right sidewall = 4
; ceiling = 5
; floor = 6
krefx = ( icnt= 1 ? gifrontwall : kx) ; asigning a position of the reflection at the x-axis
if icnt = 1 kgoto yrefcalc$R.
krefx = ( icnt= 2 ? -gifrontwall: kx) ; asigning a position of the reflection at the x-axis
yrefcalc$R.:
krefy = ( icnt= 3 ? gisidewall : ky) ; asigning a position of the reflection at the y-axis
if icnt = 3 kgoto zrefcalc$R.
krefy = ( icnt= 4 ? -gisidewall : ky) ; asigning a position of the reflection at the y-axis
zrefcalc$R.:
krefz = ( icnt= 5 ? giceiling : kz) ; asigning a position of the reflection at the z-axis
if icnt = 5 kgoto refout$R.
krefz = ( icnt= 6 ? -giceiling : kz) ; asigning a position of the reflection at the z-axis
refout$R.:
; A, E, D - calculation of the reflecting point
kDref = sqrt(krefx^2+ krefy^2+ krefz^2) ; calculates the distance of the reflection
kxref = krefx / kDref ; this operation generates a vector equivalent at the unit sphere
kyref = krefy / kDref ; this operation generates a vector equivalent at the unit sphere
kzref = krefz / kDref ; this operation generates a vector equivalent at the unit sphere
; Elevation calculation
kEref = cosinv ( sqrt( 1- kzref^2)) ; calculation of Elevation
kEref = (kzref < 0 ? - kEref : kEref) ; if z is negative make Elevation- vector negative too
; Angle calculation
kAref = sininv (kyref/ cos (kEref)) ; calculation of Angle
kAref = (kxref >= 0 ? kAref : 3.1415 - kAref) ; distinction of positive and negative y
kAref = (kyref <= 0 && kxref >= 0 ? 6.2831 + kAref : kAref) ; distinction of positive and negative y and x
; calculation of distance- difference (m/s) and delaytime
kDdiff = sqrt((kx-krefx)^2 + (ky-krefy)^2 + (kz-krefz)^2 ) ; calculation of the difference of kreflection and ksound
kDist = kDdiff + kDref ; distance sourceÑsurface + distance surfaceÑ listener
kDmtr = kDist * giunit ; calculation of difference in meters
kdel = kDmtr / 0.345 ; calculation of the delaytime [ms]
; reflection behind the source
kAdist = abs(kA - kAref)
kEdist = abs(kE - kEref)
kAdist = (kAdist > 6.2831 ? kAdist-6.2831 : kAdist) ; reduces the angle kAdist to values between 0 and 6,2831
kmute = kAdist + kEdist
kmute = ( kmute < 1.5707 ? sin (kmute) : 1 ) ; if the reflection gets behind the source, it is muted
; calculation of attenuation (gain of delay)
kgain = 1/kDist * idamp * kmute ; gain of early reflection according calculation of attenuation
; FILTERING UNIT
kDdiff = ( kDdiff< 0.05 ? 0.05 : kDdiff) ; limit the distance sourceÑ reflection
klfboost = (sqrt(1 / kDdiff ) + kD) * ilfboost
afilt tone asig, (sqrt(1/kDist)) * sr ; filtering of high frequencies according to distance
afilt pareq afilt, 174, klfboost, 0.7071, 1 ; boosting low frequencies for souces near the wall
afilt balance afilt, asig ; balancing the output
; REFLECTING UNIT
; girandpchmod ; amount of random pitch modulation
; for the delay lines. 1 is the "normal"
; amount, but this may be too high for
; held pitches such as piano tones.
; Adjust to taste.
a$R. randi 2, 3.973, $R.
adel interp kdel
adel = adel + a$R. *girandpchmod
asigref vdelay3 afilt, adel, 200 ; creating a reflection
asigref = asigref * kgain ; assigning a gain
;ENCODE
;2nd order Ambisonics encoding equations
kchnlx = cos(kAref) * cos(kEref)
kchnly = sin(kAref) * cos(kEref)
kchnlz = sin(kEref)
kchnlr = 1.5 * sin(kEref) * sin(kEref) -0.5
kchnls = cos(kAref) * sin(2*kEref)
kchnlt = sin(kAref) * sin(2*kEref)
kchnlu = cos(2*kAref) * cos(kEref) * cos(kEref)
kchnlv = sin(2*kAref) * cos(kEref) * cos(kEref)
;kchnlw= 0.707107
;kchnlw= 1- 0.29289 * (kchnlx^ 2+kchnly^2+kchnlz^ 2+kchnlr^ 2+kchnls^2+ kchnlt^2 +kchnlu^2 +kchnlv^2) ; fix w that it will remain constant
kchnlw = 1 - 0.293 *(kchnlx^ 2+ kchnly^ 2+ kchnlz^2) ;?
; encoding unit asig1- asign
; encoding of the global reverb signal
aw = asigref * kchnlw ;(A,E)
ax = asigref * kchnlx ;(A,E)
ay = asigref * kchnly ;(A,E)
az = asigref * kchnlz ;(A,E)
ar = asigref * kchnlr ;(A,E)
as = asigref * kchnls ;(A,E)
at = asigref * kchnlt ;(A,E)
au = asigref * kchnlu ;(A,E)
av = asigref * kchnlv ;(A,E)
zawm aw, 41 ; mix zak-location 41 with ambisonics w-channel output of Track 1-20
zawm ax, 42 ; mix zak-location 42 with ambisonics x-channel output of Track 1-20
zawm ay, 43 ; mix zak-location 43 with ambisonics y-channel output of Track 1-20
zawm az, 44 ; mix zak-location 44 with ambisonics z-channel output of Track 1-20
zawm ar, 45 ; mix zak-location 45 with ambisonics r-channel output of Track 1-20
zawm as, 46 ; mix zak-location 46 with ambisonics s-channel output of Track 1-20
zawm at, 47 ; mix zak-location 47 with ambisonics t-channel output of Track 1-20
zawm au, 48 ; mix zak-location 48 with ambisonics u-channel output of Track 1-20
zawm av, 49 ; mix zak-location 49 with ambisonics v-channel output of Track 1-20
#
$DIFFREFLECTION(1)
$DIFFREFLECTION(2)
$DIFFREFLECTION(3)
$DIFFREFLECTION(4)
$DIFFREFLECTION(5)
$DIFFREFLECTION(6)
endin
#undef DIFFREFLECTION(R)
; *********************************************************************************************************************************
instr 75 ; SPECULAR EARLY REFLECTIONS conceived and coded 1999-2001 by Jan Jacob Hofmann,
; using the Furse-Malham-Set (FMH) of encoding equations. Thanks to Dave Malham and Richard Furse. Thanks to Nora.
; Also thanks to Peter Lennox for inspitation and pushing me in the right direction.
;
; Based on a Paper by David Griesinger published in the Proceedings of the 19th AES International Conference, June 2001.
; *********************************************************************************************************************************
p3 = p3+0.5 ; prolong duration to keep the reverb - tail
itracknr = p4
; gifrontwall - position of frontwall at the x-axis
; gisidewall - position of sidewall at the y-axis
; giceiling - height of the ceiling measured from the zero-point of the coordinate-system
; giunit - radius of the unit- sphere[m]
ilfboost = 1 ; low frequency boost for sources near a wall
idamp = 0.2 ; damping factor of the reflecting surface
ihighdamp = 15000 ; absorbtion characteristics of the wall in respect to high frequencies: frequencies above ihighdamp get filtered out
kA zkr itracknr ; take angle from the global output of the movement score reading instrument or other
kE zkr itracknr + 20 ; take elevation from the global output of the movement score reading instrument or other
kD zkr itracknr + 40 ; take distance from the global output of the movement score reading instrument or other
asig zar itracknr ; zak audio input
kA = (kA < 0 ? kA + 6.283185 : kA) ; prevent negative angle kA
kA = (kA > 6.283185 ? kA - 6.283185 : kA) ; prevent angle kA > 360¡
; Polar converter -source as cartesian representation
kx = kD * cos(kA) * cos(kE) ; convert polar to carthesian representation
ky = kD * sin(kA) * cos(kE) ; convert polar to carthesian representation
kz = kD * sin(kE) ; convert polar to carthesian representation
kx = (kx < 0.01 && kx > -0.01 ? 0.01 : kx) ; fix for that strange y-axis noise
iwall1 = gifrontwall ;assign distance of the wall
iwall2 = -gifrontwall ;assign distance of the wall
iwall3 = gisidewall ;assign distance of the wall
iwall4 = -gisidewall ;assign distance of the wall
iwall5 = giceiling ;assign distance of the wall
iwall6 = -giceiling ;assign distance of the wall
kdiff1 = iwall1 - kx ; distance of reflection to the frontwall
kdiff2 = iwall2 - kx ; distance of reflection to the backwall
kdiff3 = iwall3 - ky ; distance of reflection to the left sidewall
kdiff4 = iwall4 - ky ; distance of reflection to the right sidewall
kdiff5 = iwall5 - kz ; distance of reflection to the ceiling
kdiff6 = iwall6 - kz ; distance of reflection to the floor
asig tone asig, ihighdamp ; filtering of high frequencies due to absorbtion characteristics of the wall
#define SPECREFLECTION(R)#
; calculation of points of reflection
icnt = $R.
ksum$R. = abs(iwall$R.) + abs(kdiff$R.) ; distance source Ñ wall Ñ listener (x,y,z-component)
krefx = (kx / ksum$R. ) * abs(iwall$R.) ; x- position of the reflection
krefy = (ky / ksum$R. ) * abs(iwall$R.) ; y- position of the reflection
krefz = (kz / ksum$R. ) * abs(iwall$R.) ; z- position of the reflection
; assignment of x-,y-,z- component at the wall
; frontwall= 1
; backwall = 2
; left sidewall =3
; right sidewall = 4
; ceiling = 5
; floor = 6
krefx = ( icnt = 1 ? iwall1 : krefx) ; asigning a position of the reflection at the x-axis
if icnt = 1 igoto ycalc$R.
krefx = ( icnt = 2 ? iwall2 : krefx) ; asigning a position of the reflection at the x-axis
ycalc$R.:
krefy = ( icnt = 3 ? iwall3 : krefy) ; asigning a position of the reflection at the y-axis
if icnt = 3 igoto zcalc$R.
krefy = ( icnt = 4 ? iwall4 : krefy) ; asigning a position of the reflection at the y-axis
zcalc$R.:
krefz = ( icnt = 5 ? iwall5 : krefz) ; asigning a position of the reflection at the z-axis
if icnt = 5 igoto labelout$R.
krefz = ( icnt = 6 ? iwall6 : krefz) ; asigning a position of the reflection at the z-axis
labelout$R.:
krefx = (krefx < 0.001 && krefx > -0.001 ? 0.001 : krefx) ; avoid zero to avoid division by zero error (NaN) later
krefy = (krefy < 0.001 && krefy > -0.001 ? 0.001 : krefy) ; avoid zero to avoid division by zero error (NaN) later
krefz = (krefz < 0.001 && krefz > -0.001 ? 0.001 : krefz) ; avoid zero to avoid division by zero error (NaN) later
; A, E, D - calculation of the reflecting point
kDref = sqrt (krefx^2+ krefy^2+ krefz^2) ; calculates the distance of the reflection
kxref = krefx / kDref ; this operation generates a vector equivalent at the unit sphere
kyref = krefy / kDref ; this operation generates a vector equivalent at the unit sphere
kzref = krefz / kDref ; this operation generates a vector equivalent at the unit sphere
; Elevation calculation
kEref = cosinv ( sqrt( 1-kzref^2)) ; calculation of Elevation
kEref = (kzref < 0 ? -kEref : kEref) ; if z is negative make Elevation- vector negative too
; Angle calculation
kAref = sininv (kyref/ cos (kEref)) ; calculation of Angle
kAref = (kxref >= 0 ? kAref : 3.1415 - kAref) ; distinction of positive and negative y
kAref = (kyref <= 0 && kxref >= 0 ? 6.2831 + kAref : kAref) ; distinction of positive and negative y and x
; calculation of distance- difference (m/s) and delaytime
kDdiff = sqrt((kx - krefx)^2 + (ky-krefy)^2 + (kz - krefz)^2 ) ; calculation of the difference of kreflection and ksound
kDist = kDdiff + kDref ; distance sourceÑsurface + distance surfaceÑ listener
kDmtr = kDist * giunit ; calculation of difference in meters
kdel = kDmtr / 0.345 ; calculation of the delaytime [ms]
; calculation of attenuation (gain of delay)
kgain = 1/kDist * idamp ; gain of early reflection according calculation of attenuation
; reflection behind the source
kAdist = abs(kA - kAref)
kEdist = abs(kE - kEref)
kAdist = (kAdist > 6.2831 ? kAdist-6.2831 : kAdist) ; reduces the angle kAdist to values between 0 and 6,2831
kmute = kAdist + kEdist
kmute = ( kmute < 1.5707 ? sin (kmute) : 1 ) ; if the reflection gets behind the source, it is muted
; filtering unit
kDdiff = ( kDdiff< 0.05 ? 0.05 : kDdiff) ; limit the distance sourceÑ reflection
klfboost = sqrt(1 / kDdiff) * ilfboost
afilt tone asig, (sqrt(1 / kDist)) * sr ; filtering of high frequencies according to distance
afilt pareq afilt, 174, klfboost, 0.7071, 1 ; boosting low frequencies for souces near the wall
afilt balance afilt, asig ; balancing the output
; reflecting unit
; girandpchmod ; amount of random pitch modulation
; for the delay lines. 1 is the "normal"
; amount, but this may be too high for
; held pitches such as piano tones.
; Adjust to taste.
a$R. randi 2, 3.973, $R.
adel interp kdel
adel = adel + a$R. * girandpchmod
asigref vdelay3 afilt, adel, 200 ; creation of a reflection
asigref = asigref * kgain * kmute ; assigning a gain
;ENCODE
;2nd order Ambisonics encoding equations
kchnlx = cos(kAref) * cos(kEref)
kchnly = sin(kAref) * cos(kEref)
kchnlz = sin(kEref)
kchnlr = 1.5 * sin(kEref) * sin(kEref) -0.5
kchnls = cos(kAref) * sin(2*kEref)
kchnlt = sin(kAref) * sin(2*kEref)
kchnlu = cos(2*kAref) * cos(kEref) * cos(kEref)
kchnlv = sin(2*kAref) * cos(kEref) * cos(kEref)
;kchnlw= 0.707107
;kchnlw= 1- 0.29289 * (kchnlx^ 2+kchnly^2+kchnlz^ 2+kchnlr^ 2+kchnls^2+ kchnlt^2 +kchnlu^2 +kchnlv^2) ; fix w that it will remain constant
kchnlw = 1 - 0.293 * (kchnlx^ 2+ kchnly^ 2+ kchnlz^2) ;?
; encoding unit asig1- asign
; encoding of the audio signal
aw = asigref * kchnlw ;(A,E)
ax = asigref * kchnlx ;(A,E)
ay = asigref * kchnly ;(A,E)
az = asigref * kchnlz ;(A,E)
ar = asigref * kchnlr ;(A,E)
as = asigref * kchnls ;(A,E)
at = asigref * kchnlt ;(A,E)
au = asigref * kchnlu ;(A,E)
av = asigref * kchnlv ;(A,E)
zawm aw, 41 ; mix zak-location 41 with ambisonics w-channel output of Track 1-20
zawm ax, 42 ; mix zak-location 42 with ambisonics x-channel output of Track 1-20
zawm ay, 43 ; mix zak-location 43 with ambisonics y-channel output of Track 1-20
zawm az, 44 ; mix zak-location 44 with ambisonics z-channel output of Track 1-20
zawm ar, 45 ; mix zak-location 45 with ambisonics r-channel output of Track 1-20
zawm as, 46 ; mix zak-location 46 with ambisonics s-channel output of Track 1-20
zawm at, 47 ; mix zak-location 47 with ambisonics t-channel output of Track 1-20
zawm au, 48 ; mix zak-location 48 with ambisonics u-channel output of Track 1-20
zawm av, 49 ; mix zak-location 49 with ambisonics v-channel output of Track 1-20
#
$SPECREFLECTION(1)
$SPECREFLECTION(2)
$SPECREFLECTION(3)
$SPECREFLECTION(4)
$SPECREFLECTION(5)
$SPECREFLECTION(6)
endin
#undef SPECREFLECTION(R)
; *****************************************************************************************************************
instr 80 ; MIXING, OUTPUT & 9-CHNL DECODING UNIT, 2nd ORDER AMBISONICS coded 1999-2001 by Jan Jacob Hofmann.
; FURSE - MALHAM - SET OF EQUATIONS Thanks to Richard Furse and Dave Malham
; More sets of speaker- layouts may be discovered at
; http://www.muse.demon.co.uk/ref/speakers.html
; *****************************************************************************************************************
aw zar 41 ; zak ambisonics w-channel input
ax zar 42 ; zak ambisonics x-channel input
ay zar 43 ; zak ambisonics y-channel input
az zar 44 ; zak ambisonics z-channel input
ar zar 45 ; zak ambisonics s-channel input
as zar 46 ; zak ambisonics t-channel input
at zar 47 ; zak ambisonics u-channel input
au zar 48 ; zak ambisonics v-channel input
av zar 49 ; zak ambisonics w-channel input
zacl 0, 49 ; clear all a-rate channels
zkcl 0, 60 ; clear all k-rate channels
if nchnls == 2 goto stereo ; goto 2chnl decode
; UNIT FOR WRITING 9 2ND ORRDER AMBISONIC ENCODED SOUNDFILES
; **************************************************************************************
kpeak1 peak aw
kpeak2 peak ax
kpeak3 peak ay
kpeak4 peak az
kpeak5 peak ar
kpeak6 peak as
kpeak7 peak at
kpeak8 peak au
kpeak9 peak av
printk p3, kpeak1,0
printk p3, kpeak2,3
printk p3, kpeak3,6
printk p3, kpeak4,9
printk p3, kpeak5,12
printk p3, kpeak6,15
printk p3, kpeak7,18
printk p3, kpeak8,21
printk p3, kpeak9,24
fout "$FILEw.$HEADER.", giformat,aw ; output of a soundfile with header as specified in the options
fout "$FILEx.$HEADER.", giformat,ax ; output of a soundfile with header as specified in the options
fout "$FILEy.$HEADER.", giformat,ay ; output of a soundfile with header as specified in the options
fout "$FILEz.$HEADER.", giformat,az ; output of a soundfile with header as specified in the options
fout "$FILEr.$HEADER.", giformat,ar ; output of a soundfile with header as specified in the options
fout "$FILEs.$HEADER.", giformat,as ; output of a soundfile with header as specified in the options
fout "$FILEt.$HEADER.", giformat,at ; output of a soundfile with header as specified in the options
fout "$FILEu.$HEADER.", giformat,au ; output of a soundfile with header as specified in the options
fout "$FILEv.$HEADER.", giformat,av ; output of a soundfile with header as specified in the options
; soundout aw, "$FILEw.$HEADER.", giformat ; output for headerless mono- files
; soundout ax, "$FILEx.$HEADER.", giformat ; output for headerless mono- files
; soundout ay, "$FILEy.$HEADER.", giformat ; output for headerless mono- files
; soundout az, "$FILEz.$HEADER.", giformat ; output for headerless mono- files
; soundout ar, "$FILEr.$HEADER.", giformat ; output for headerless mono- files
; soundout as, "$FILEs.$HEADER.", giformat ; output for headerless mono- files
; soundout at, "$FILEt.$HEADER.", giformat ; output for headerless mono- files
; soundout au, "$FILEu.$HEADER.", giformat ; output for headerless mono- files
; soundout av, "$FILEv.$HEADER.", giformat ; output for headerless mono- files
if nchnls == 9 goto skipend ; just encode the sound -comment this out if encoded+decoded files are wanted
; ********************************************************************************************************
stereo: ; 2chnl (stereo ) decode, 2nd order Ambisonics (second order controlled opposites) output
; ********************************************************************************************************
;Rig `Controlled Opposites' Decode Matrix (second Order)
; w x y z r s t u v
; Speaker1 <0.0000,1.0000,0.0000>
achnl1 sum aw*0.7071, ay*0.5000
; Speaker2 <0.0000,-1.0000,0.0000>
achnl2 sum aw*0.7071, ay*-0.5000
kpeak1 peak achnl1
kpeak2 peak achnl2
printk p3, kpeak1, 0
printk p3, kpeak2, 3
outs achnl1, achnl2
; fout "$FILE-stereo.$HEADER.", giformat, achnl1, achnl2
; soundout achnl1, "$FILE.left.$HEADER.",giformat
; soundout achnl2, "$FILE.right.$HEADER.",giformat
skipend:
endin
/* f1 0 8192 10 1
/* f7 0 32768 14 1 1 0 1 0 0.6 0 0.4 0 0.1 /* hyperbolid */
/* f8 0 8192 19 0.5 0.5 270 0.5 /* sigmoid rising */
/* f9 0 8192 19 0.5 1 180 1 /* paraboloid */
/* f10 0 8192 20 2 1 /* hanning */
/*f11-f20=straight lines */
f11 0 4 7 0 4 0
/* f12 0 4 7 0.1 4 0.1
f13 0 4 7 0.2 4 0.2
f14 0 4 7 0.4 4 0.4
f15 0 4 7 0.5 4 0.5
f16 0 4 7 0.6 4 0.6
f17 0 4 7 0.8 4 0.8
f18 0 4 7 0.9 4 0.9
f19 0 4 7 1 4 1
f20 0 4 -7 10 4 10
/*f21-f30=slopes and linsegs*/
f21 0 8192 7 0 8192 1
/* f22 0 8192 7 0 8192 -1
f23 0 4 7 0 1 0 0 1 2 1 0 0 1 0
f25 0 256 7 0 128 1 128 0 /* triangle unipolar*/
/* f27 0 256 7 0 128 1 0 -1 128 0
f28 0 256 7 0 64 1 128 -1 64 0 /* tiangle bipolar */
/* f29 0 1024 7 0 100 1 824 1 100 0 /* enveloped 19*/
/*f31-f40=exponentials */
/* f31 0 8192 5 0.001 8192 1
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/*instr 40 x,y,z -READER */
/*instr 42 x, y, z -CONVERTER*/
/*instr 46 A,E,D -MOVEMENT-SCORE READER*/
/*instr 47 AED- MODULATOR*/
/*instr 48 AED RANDOMIZER*/
/*instr 50 SOUNDFILE READER*/
/*instr 60 LOCAL (TRACK-APPLIED) REVERB*/
/*instr 72 9-CHNL ENCODING UNIT FOR SOUND, 2ND ORDER AMBISONICS*/
/*instr 73 SPATIAL GLOBAL REVERB */
/*instr 74 DIFFUSE EARLY REFLECTIONS */
/*instr 75 SPECULAR EARLY REFLECTIONS */
/*instr 80 MIXING, OUTPUT & 9-CHNL DECODING UNIT, 2nd ORDER AMBISONICS */
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/* instr 40 x,y,z -READER */
/**********************************************************************************************************************************/
/* p1= instr p8= xmodulatorfn p15= ymodfncps p22= zmodfactor */
/* p2= start p9= xmodfncps p16= ymfnfactor */
/* p3= dur p10= xmodfnfactor p17= zstart */
/* p4= track [1-20] p11= ystart p18= zend */
/* p5= xstart p12= yend p19= zmovefn */
/* p6= xend p13= ymove fn p20= zmodfn */
/* p7= xmovefn p14= ymodulatorfn p21= zmodfncps */
/* p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 */
/**********************************************************************************************************************************/
/* instr 46 A,E,D - MOVEMENT SCORE READER */
/**********************************************************************************************************************************/
/* p1= instr p8= Amodfn p15= Efncps p22= Dmodfnfactor */
/* p2= start p9= Amodfncps p16= Emfnfactor */
/* p3= dur p10= Amodfnfactor p17= Dstart */
/* p4= track [1-20] p11= Estart p18= Dend */
/* p5= Astart p12= Eend p19= Dmovefn */
/* p6= Aend p13= Emove fn p20= Dmodfn */
/* p7= Amovefn p14= Emodfn p21= Dmodfncps */
/*p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 */
i46 0 8 1 0 0 21 11 0 0 0 0 21 11 0 0 8 1 21 11 0 0
i46 4 8 2 0 0 21 11 0 0 0 0 21 11 0 0 4 1 21 11 0 0
/**********************************************************************************************************************************/
/*instr 47 AED- MODULATOR */
/**********************************************************************************************************************************/
/*mode1 = Angle modulation */
/*mode2 = Elev. modulation */
/*mode3 = Distance modulation */
/* p1= instr p5= mode */
/* p2= start p6= AEDmodfn */
/* p3= dur p7= AEDmodfncps */
/* p4= track[1-20] p8= AEDmodfnfactor */
/* p1 p2 p3 p4 p5 p6 p7 p8 */
/* i47 0 7.58 1 2 1 0.131926121 60 */
/**********************************************************************************************************************************/
/*instr 48 AED RANDOMIZER */
/**********************************************************************************************************************************/
/*mode1 = Angle modulation */
/*mode2 = Elev. modulation */
/*mode3 = Distance modulation */
/* p1 = instr p6= rnddevamt */
/* p2 = start p7= rnddevamtfn */
/* p3 = dur p8= rndspeedcps */
/* p4 = track[1-20] p9= rndspeedfn */
/* p5 = mode p10= seed */
/*p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 */
/*i48 0 7.58 1 1 40 -31 0.131926121 -31 0 */
/**********************************************************************************************************************************/
/* instr 50 SOUNDFILE READER */
/**********************************************************************************************************************************/
/* p1 = instr p6= skiptime p11= localreverb on/off [1/0] */
/* p2 = start p7= reverbsend (local+global) p12= diffuse reflection on/off [1/0] */
/* p3 = dur p8= rvbdecay (local+global) p13= specular reflection on/off [1/0] */
/* p4 = track [1-20] p9= randpchmod (local+global) */
/* p5 = gainfactor p10=lp-cutofffreq (local+global) */
/* p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 */
i50 0 8 1 1 0 0.2 0.4 1 8000 1 1 1
i50 4 8 2 1 0 0.2 0.4 1 8000 1 1 1
/**********************************************************************************************************************************/
/*instr 73 SPATIAL GLOBAL REVERB ( has to run all of the total duration, else instr. 80 (output) is not invocated) */
/**********************************************************************************************************************************/
/* p1 = instr */
/* p2 = start */
/* p3 = dur */
/* p1 p2 p3 */
i73 0 12
e
Version: 3
Render: File
Ask: Yes
Functions: Window
WindowBounds: 45 62 1021 734
Options: -b1024 -A -o/Users/janjacobhofmann/Documents/Audiofiles/Csd -s -m7 -K
ioView nobackground {65535, 65535, 65535}
ioListing {10, 10} {400, 500}