Externals in C - Sample rate retrieval


    Dec 06 2010 | 10:02 am
    Hi,
    I did a search for this beforehand but couldn't find anything so I apologise if I'm repeating something that's been posted here before.
    I'm building an external object for Max in C for a school assignment. We were given a basic template for an object that lets audio pass through, and we're modifying it into a 4-tap delay.
    I've got the signal vectors (s_vec) coming through the object, and also the vector size of the signal (s_n), both of these are picked up fine in my perform routine. For some reason I CAN NOT get the perform routine to pick up the sample rate of the incoming signal.
    I've added sp[0]->s_sr to my dspAdd section, and then added it to the perform routine in the same way I have s_n being read in, but when I use post to check the value of both values, the s_n prints as whatever the buffer is set to on the dac~ object unsurprisingly and the s_sr prints as 0. If I use post just after the dspAdd section however, the sample rate reads as 44100.
    I can elaborate or post screenshots if this isn't altogether clear.
    Thanks Joe

    • Dec 06 2010 | 10:36 am
      "I've added sp[0]->s_sr to my dspAdd section, and then added it to the perform routine in the same way I have s_n being read in..."
      maybe you've got this covered, but t_signal struct ref defines s_n as int and s_sr as float. did you make sure to assign it to a float variable(and you can also make it explicit('typecast' as below)) in your perform routine?
      something like this:
      void yourobject_dsp(t_mhnmna *x, t_signal **sp, short *count) {
      dsp_add(yourobject_perform, 5, x, sp[0]->s_n, sp[0]->s_sr, sp[0]->s_vec, sp[1]->s_vec;
      }
      t_int *yourobject_perform(t_int *w) { t_yourobject *x = (t_yourobject *)w[1]; int n = (int)w[2]; float f = (float)w[3]; t_float *in = (t_float *)w[4]; t_float *out = (t_float *)w[5]; ... ... }
      i could be wrong(too tired to run a full code test right now, need sleep), but try it out if you haven't already... hope it flies.
      ________________________________ *Never fear, Noob4Life was never here!*
    • Dec 06 2010 | 12:49 pm
      Yea, that's exactly what I've got. Here's an exact replica of those two parts of code in my object:
      dsp_add(mspExternalTPerform, 8, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, sp[0]->s_n, sp[0]->s_sr);
      The outlets are because I'm creating a delay with a quadrophonic output. All those outputs work, as does the slot with s_n in it.
      My perform routine (spaces are for ease of reading here):
      t_int* mspExternalTPerform(t_int* w)
      t_mspExternalT* x = (t_mspExternalT*)(w[1]); float* signal_in = (float*)(w[2]);
      float* signal_out_one = (float*)(w[3]); float* signal_out_two = (float*)(w[4]); float* signal_out_three = (float*)(w[5]); float* signal_out_four = (float*)(w[6]);
      long num_samples = (long)(w[7]); /* this was given to us as a long rather than an int */
      float sample_rate = (float)(w[8]) ...
      then a bunch of code for my delay etc.
      That last line should assign the sample rate to a flat variable named "sample_rate" right? But when I use this:
      post("sample rate is: %f", sample_rate)
      right after it, it returns a zero. However, the same line placed after my dsp_add line prints 44100.
      Help?!
      Thanks Joe
    • Dec 06 2010 | 1:32 pm
      The quick and simple answer is that we don't support passing floating point values as arguments to dsp_add. Only pointers and integers.
      Typically one accomplishes what you are looking to do by caching the sr value in your object struct. Or you could pass as a pointer to a float for that signal's sr field (you can assume this signal memory will persist).
      Sorry for the inconvenience.
    • Dec 06 2010 | 2:03 pm
      That explains why I can't get it to work!
      Ok, so I'm a little confused about how to do this now, could you elaborate on the mentioned methods? How do I catch the value in my object struct? This is in the
      typedef struct _mspExternalT
      section at the top, right?
      Thanks, Joe
    • Dec 06 2010 | 2:38 pm
      Yes. Add a floating point variable in your object struct. Assign it in your dsp method.
      typedef struct _myobject
      {
          t_pxobject  ob;
          ...
          float        sr;
          ...
      }t_myobject;
      
      and in your dsp method:
      ...
      x->sr = sp[0]->s_sr;
      ...
      
    • Dec 06 2010 | 2:44 pm
      Thank you so much, got it working now. Now if I can actually get the delay to work properly...
      Cheers! Joe