Digital Music Programming II: mydelayline~




This lab demonstrates how to create a delayline which delays audio signals by a specific number of samples.


Source Code Example Usage
mydelayline.c


#include "ext.h"
#include "z_dsp.h"

typedef struct {
   t_pxobject msp_data;  
   float* data;          
   long   index, allocsize, size;          
} MyObject;

void* object_data;        

void   main               (void);
void*  create_object      (long maxsize);
void   destroy_object     (MyObject* mo);
void   InputSize          (MyObject* mo, long newsize);
void   MessageDSP         (MyObject* mo, t_signal** signal, short* count);
void   MessageClear       (MyObject* mo);
t_int* Perform            (t_int *parameters);
float  incrementDelayline (MyObject* mo, float value);

void main(void) {
   setup((t_messlist**)&object_data, (method)create_object,
         (method)destroy_object, (short)sizeof(MyObject),
         NULL, A_LONG, A_NOTHING);
   addinx((method)InputSize, 1);          
   addmess((method)MessageDSP, "dsp", A_CANT, A_NOTHING);
   addmess((method)MessageClear, "clear", A_NOTHING);
   dsp_initclass();
}

void* create_object(long maxsize) {
   MyObject *mo = (MyObject*)newobject(object_data);  
   dsp_setup((t_pxobject*)mo, 1);           
   outlet_new((t_pxobject*)mo, "signal");   
   intin(mo, 1);                            
   if (maxsize < 1) {
      post("Error: buffer size too small, setting it to 1000 samples.");
      maxsize = 1000;
   }
   mo->data = (float*)malloc(maxsize * sizeof(float));
   mo->allocsize = mo->size = maxsize;
   MessageClear(mo);
   return mo;                               
}

void destroy_object(MyObject* mo) {
   dsp_free(&(mo->msp_data));
   free(mo->data);
   mo->data = NULL;
   mo->allocsize = mo->size = mo->index = 0;
}

void InputSize(MyObject* mo, long value) {
   if (value < 0) {
      post("Size too small, setting size to default value.");
      value = mo->allocsize;
   } else if (value > mo->allocsize) {
      post("Size too large, setting size to default value.");
      value = mo->allocsize;
   }
   mo->size = value;
   MessageClear(mo);
}

void MessageDSP(MyObject* mo, t_signal** signal, short* count) {
   #pragma unused(count)
   int paramcount = 5;
   dsp_add(Perform, paramcount, paramcount, mo, signal[0]->s_vec, 
         signal[1]->s_vec, signal[0]->s_n);
}

void MessageClear(MyObject* mo) {
   int i;
   for (i=0; i<mo->allocsize; i++)  mo->data[i] = 0.0;
   mo->index = 0;
}

t_int* Perform(t_int *parameters) {
   long      paramcount = (long)     (parameters[1]);
   MyObject *mo         = (MyObject*)(parameters[2]);
   t_float  *input      = (t_float*) (parameters[3]);
   t_float  *output     = (t_float*) (parameters[4]);
   long      count      = (long)     (parameters[5]);
   long i;

   for (i=0; i<count; i++)  output[i] = incrementDelayline(mo, input[i]);
   
   return parameters+paramcount+1;   
}

float incrementDelayline(MyObject* mo, float value) {
   float output;
   if (mo->size == 0)  return value;
   output = mo->data[mo->index];
   mo->data[mo->index] = value;
   mo->index++;
   if (mo->index >= mo->size)  mo->index = 0; 
   return output;
}


Exercises

  1. Compile and test the mydelayline~ object.

  2. Psychoacoustic Experiment: create the following Max/MSP patch:

    Set the delay amount to 0 and listen to the output sound with headphones. The noise should sound monophonic since it is the same signal in each ear. Now increase the delay amount to 1 sample. Listen to the signal now that the signal is slightly delayed in one ear. Increase the delayamount gradually up to 30 samples. What happens to the sound? Why does this happen?

  3. Listen to the sound of the noise from the previous patch with headphones using the following delays:
    1. 100
    2. 200
    3. 300
    4. 400
    5. 500
    6. 600
    7. 700
    8. 800
    9. 900
    10. 1000

    Can you tell the difference between each 100 sample increase in the delay and the previous sound? Increase the default size of the delayline to 10,000 samples. Listen to every 1,000 sample multiple of delay. Can you tell the difference between these delay amounts?

  4. Implement the averaging filter as a Max/MSP patch using the mydelayline~ object. Here is the flowgraph for the averaging filter: