# Digital Effects

## Lecture Slides

A series of gif images of the lecture slides... (only accesible from within Stanford University)

### Spatialization

Some reverberators included in clm...

### dlocsig.lisp

A dynamic moving source unit generator for clm: dlocsig.

There are three components that make up the dlocsig package:

#### Paths

A path is a structure that represents the path along which the moving sound object will move. A path can be created by using cartesian or polar coordinates through the following structure creation functions:

make-path
creates a new path that specified through cartesian coordinates. make-path has a required parameter :path which needs a list of points in two dimentional space through which the object will move (specified as x y pairs).

```  (setf xx (make-path :path '(-10 10 0 5 10 10)))
```
will create a special variable named xx that will hold a path that will move an object in front of the listener from left to right. The actual path is a linear approximation to a fit of Bezier cuves to the supplied points. A couple of parameter can specify global behavior in the conversion process. :error will define the maximum allowed error between the linear segment approximation and the real bezier curve. Lower values result in a closer approximation and more points are generated. I would suggest using at least :error 0.01 when you create a new path. :curvature will affect the length of the Bezier control point handles and thus will change the curvature around the supplied points. Try values greater than one for more abrupt changes in direction.

At any point you can plot some parameters of the path by using the following functions:

(plot path structure)
plots the two dimensional rendered curve (the user supplied points plus the rendered Bezier curve approximation)
(plot-velocity path structure)
will plot the velocity at which the object will move.
(plot-acceleration path structure)
will plot the acceleration at which the object will move.
(plot-doppler path structure)
will plot the doppler frequency shift that the sound will experience due to radial velocity changes.

make-polar-path
creates a new path that is specified through polar coordinates. make-polar-path has a required parameter :path which needs a list of points in two dimentional space through which the object will move (specified as distance angle pairs).

```  (setf xx (make-polar-path :path '(10 0 5 90 10 180)))
```
"0" degrees is right in front of the listener's position.

make-closed-path
creates a new closed path. The last point of a closed path has to have the same coordinates as the first point (otherwise an error is signalled). You need at least five points to specify a closed due to restrictions in the algorithm that fits the Bezier curves to the points.

make-spiral-path
creates a new spiral path. See the make-spiral-path function in the dlocsig.lisp code for more details on parameters. make-spiral-path is one instance of a class of paths I've named geometrical paths. Geometrical paths are not rendered through Bezier curve fitting. The function that creates the path has to supply _all_ the points.

#### dlocsig

This is a new unit generator that has the capability of dynamically moving objects in two dimensional space. It has been coded to create four channel soundfiles. If you create a stereo soundfile the back channels are mixed with the front channels so you will loose the back to front movements and most of the lateral movements. All the samples will be there, though, so you can experiment in stereo and then render in quad for the final soundfile.

As in any clm unit generator, dlocsig has a pair of functions:

make-dlocsig
create a structure that holds all the data that represents the movement. This structure is then used by the dlocsig macro to render the movement inside the run loop of an instrument.

make-dlocsig accepts the following parameters:

start-time 0
start time in seconds for the note
duration 1
duration in seconds of the note
path dlocsig-path
path structure (as defined by a previous make-path)
scaler dlocsig-scaler
a scaling coefficient that is applied to amplitude
power dlocsig-power
the rate of change of attenuation with distance of the direct sound
rev-power dlocsig-reverb-power
the rate of change of attenuation with distance of the reverberated sound
reverb-amount dlocsig-reverb-amount
amount of global reverberation added to the sound
initial-delay dlocsig-initial-delay
if "t" the initial delay is included in the soundfile, otherwise it is ignored and the onset of the sound will be instantaneuos.
normalize-gain dlocsig-normalize-gain
if "t" the minimum distance between the object and the listener will be defined as the gain=1 distance. If "nil" then the attenuation of signal can be very significant due to the distance attenuation.
aspect-ratio dlocsig-speaker-aspect-ratio
controls how "square" is the distribution of speakers, see the source for details...

make-dlocsig returns three values, the structure that holds all the parameters and the starting and ending sample numbers for the note (those should be used when defining the limits of the outermost run loop loop). A typical call to make-dlocsig should be made as follows:

```    (multiple-value-bind (dloc dbeg dend)
(make-dlocsig :path path
:start-time start-time
:duration in-file-dur
:reverb-amount reverb-amount
:scaler amp)
```

Where dloc will contain the dlocsig structure, dbeg the starting sample of the run loop and dend the ending sample. A typical run loop would be:

```      (run
(loop for i from dbeg to dend do
(dlocsig dloc i sample)))
```

dlocsig
this is the run time macro that will localize the samples.

```   (dlocsig dlocsig_structure sample_number sample_to_be_localized)
```

#### dlocnrev

This is a four channel version of the nrev reverberator. If you want to use reverberation the specify dlocnrev as the name of the reverberator in with-sound.

The examples directory also includes a move-sound.ins instrument that dynamically moves a mono soundfile. It will let you play around with dlocsig without having to build your own instrument.

### hrtf.ins

A Head Related Transfer Function instrument for clm.

The hrtf measurements were done by Bill Gardner and Keith Martin at MIT, here's a pointer to the home page of the measurements. Take a look if you want the details (or wish to see a picture of Kemar the dummy). The hrtf data lives in /usr/ccrma/snd/nando/hrtf. The "diffuse" subdirectory (which is the one being used by the instrument). Each subdirectory inside "diffuse" contains data for a particular elevation (that is, the elev40 subdirectory holds all the hrtf data sets corresponding to +40 degrees of elevation. Inside that directory you will find the actual impulse responses for a collection of azimut angles. Each impulse response is a stereo soundfile (without header) that includes the responses for both ears. If you want to take a look at how the impulse response looks open the .dat file in snd, you will be prompted to enter some information regarding the file as it has no header: Fill the panel with chans: 2 (stereo) and "16 bit big-endian". You will get two channels showing with the impulse response for the left and right ears.

The data in the directory structure is parsed and loaded into lisp by the function load-hrtf-data, which is called automatically the first time you try to use the instrument. Same thing happens with the fir filter coefficients that are use to do crosstalk cancellation in the case of loudspeaker reproduction.

The instrument accepts the following parameters:

start-time [mandatory parameter]
start time in seconds in the output soundfile
amplitude [mandatory parameter]
amplitude multiplier
file [mandatory parameter]
path name of the soundfile to be processed
elevation
elevation angle in degrees. The dataset includes point for elevations that go from a minimum of -40 degreed to a maximum of +90 degrees.
azimut
azimut angle in degrees.
reverb-amount
global reverberation amount. The enclosing with-sound has to specifiy a reverb instrument for this to work.
The default value is "t", which will not include the crosstalk cancellation fir filter. If you want to listen through loudspeakers set this to "nil".

Here is a very simple example of a percussive sound being convolved with the impulse responses for some azimut angles:

```(with-sound(:channels 2 :statistics t)
(loop
for time from 0 by 0.3
for az from 0 by 5 below 181 do
(hrtf time 0.25 "/usr/ccrma/snd/nando/hrtf/knife-11.snd" :azimut az :headphones t)))
```

The instrument will select the impulse response that is closest to the elevation and azimut angles specified. It will not try to interpolate between impulse responses (although I've tested this myself and seems to work).