an open-source digital signal processing and sound synthesis language
about · links · contact


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.


    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().


    #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();
    		out[0] = theDelay->getsamp(22050.0); // 0.5 second delay