Odelay/Odelayi
INSTRUMENT design -- general delay-line objects
The Odelay and Odelayi objects are used to create
and use delay-lines for samples. Odelay is non-interpolating,
so that requests for delays that translate into a fractional point
between two samples will be 'rounded' to the nearest sample value.
This fractional delaying can happen quite often with
dynamically-changing delay lines, which makes Odelayi
a better choice in those cases. Odelayi is slightly less
efficient because of the interpolation math to calculate a fractional
sample-point.
There are two different ways of using the Odelay/Odelayi
objects. The first is based on the older RTcmix delay techniques using the
delset/delput/delget/dliget approach, where
delayed samples are retrieved from the delay line based upon
a time- or sample-amount of delay specified in the corresponding
delget or dliget function call. Samples are put 'into'
the delay line using delput. Because the delay amount is determined
when samples are retreived from the delay line, multiple taps (i.e. multiple
calls to the sample-retrieving function) are allowed for each
sample-generating cycle.
The second way of using the Odelay/Odelayi objects is based
on approach used in the
Synthesis ToolKit (STK)
delay line implementation (DLineL). Samples are placed into and retrieved
from the delay line simultaneously, with the length of the delay determined
by a separate function call. It is prabably best not to mix the two
different approaches, because the delay line pointer-updating is handled
slightly differently in each case.
Constructors
Odelay(long defaultLength)
Odelayi(long defaultLength)
-
creates a new delay line.
defaultLength is the initial length of the delay line
(in samples, so time should be converted to samples using SR*seconds).
If a delay length is requested during note execution that is longer
than this initial length, then the delay line will be resized to accommodate
the additional delay length.
Access Methods
void Odelay::clear()
void Odelayi::clear()
-
will clear (zero) the current delay line of all samples.
void Odelay::fill(double val)
void Odelayi::fill(double val)
-
will fill the entire delay line with the number val.
void Odelay::putsamp(float samp)
void Odelayi::putsamp(float samp)
-
will place the sample samp into the delay line. This method should
be used with the getsamp() method below.
float Odelay::getsamp(double delaysamps)
float Odelayi::getsamp(double delaysamps)
-
returns a floating-point sample value corresponding to a sample
that was placed into the delay line delaysamps samples ago.
Odelayi::getsamp() will interpolate between sample values
if delaysamps has a fractional part; Odelay::getsamp()
will 'round' to the nearest sample location in the delay line.
getsamp() is used with putsamp() above.
void Odelay::setdelay(double delaysamps)
void Odelayi::setdelay(double delaysamps)
-
sets the delay line to return samples that are delaysamps samples
(SR*seconds seconds) old. This is to be used to set
the delay for the next() method described below.
Odelayi::setdelay() will cause next() to
interpolate fractional sample values if delaysamps has a
fractional part; Odelay::setdelay()
will catse next() to
'round' to the nearest sample location in the delay line.
float Odelay::next(float samp)
float Odelayi::next(float samp)
-
returns a floating-point sample value delayed by the number of samples
set in a preceding setdelay() call, as well as putting the sample
samp into the delay line for subsequent retrieval by next).
float Odelay::last()
float Odelayi::last()
-
returns the last sample value retrieved from the delay line by either a
getsamp() call or a next() call.
long Odelay::length()
long Odelayi::length()
-
returns the current length (in samples) of the delay line.
float Odelay::delay()
float Odelayi::delay()
-
returns the current delay (in samples) of the delay line. Note that a
delay line may be longer than the current delay. This reports the delay
length as established by setdelay().
Examples
#include <Ougens.h>
Odelay *theDelay;
// this instrument has a delay line
int MYINSTRUMENT::init(float p[], int n_args)
{
...
theDelay = new Odelay(22050.0); // 0.5 second initial delay line
...
}
int MYINSTRUMENT::run()
{
float out[2];
float sample;
...
for (i = 0; i < framesToRun(); i++)
{
sample = someSampleGeneratingProcess();
theDelay->putsamp(sample);
out[0] = theDelay->getsamp(22050.0); // 0.5 second delay
}
...
}