clock_delay problem, Max external


    Dec 09 2006 | 7:32 pm
    I am trying to write an external that will send out a bang according to an input integer, and subsequently send out a bang according to a 2nd input integer. For example, 1000 is entered in input 2, 500 is entered in input 3. The metro would then send a bang after 1000ms, next bang would be 500ms, and the process would repeat, 1000, 500, 1000, 500 etc. I am having trouble w/ clock_delay, for some reason the metro is only reacting to the integer from input 3. I have been struggling w/ this, any help would be much appreciated.
    code:
    #include "ext.h" // Required for all Max external objects void *class; // Required. Global pointing to this class #define DEFAULT_TEMPO 1000 #define MIN_TEMPO 20 typedef struct _metro /* data structure for this object */ { t_object m_ob; /* must always be the first field; used by Max */ void *m_clock; /* pointer to clock object */ long m_interval; /* tempo in milliseconds */ long m_interval2; /* ratio, relative to initial tempo, of 2nd bang */ void *m_bang_outlet; /* pointers to bang outlet */ void *m_time_outlet; /* pointers to time outlet */ } t_metro; void *metro_new(long value); void metro_in1(t_metro *m, long value); void metro_in2(t_metro *m, long value2); void metro_bang(t_metro *m); void metro_assist(t_metro *m, t_object *b, long msg, long arg, char *s); void metro_free(t_metro *m); void metro_stop(t_metro *m); void clock_function(t_metro *m); int main(void) { /* set up our class: create a class definition */ setup((t_messlist **) &class, (method)metro_new, (method)metro_free, (short)sizeof(t_metro), 0L, A_DEFLONG, 0); /* bind method "metro_bang" to the "bang" message */ addbang((method)metro_bang); /* bind method "metro_in1" to int's received in the 1st inlet */ addinx((method)metro_in1,1); /* bind method "metro_in2" to int's received in the 2nd inlet */ addinx((method)metro_in2,2); /* bind method "metro_stop" to the "stop" message" */ addmess((method)metro_stop,"stop",0); /* bind method "metro_assist" to the assistance message" */ // addmess((method)metro_assist,"assist",A_CANT,0); /* add class to the New object list */ finder_addclass("All Objects","mymetro"); return (0); } /********************************************************************************** metro_new(long value) inputs: value - the integer from the typed in argument in the object box description: creates a new instance of this class metro. returns: pointer to new instance *************************************************************************************/ void *metro_new(long value) { t_metro *m; m = (t_metro *)newobject(class); // create the new instance and return a pointer to it if (value > MIN_TEMPO) // initialize { m->m_interval = value; // save tempo argument from box post("mymetro tempo set to %ld", value); } else { m->m_interval = DEFAULT_TEMPO; // set to default tempo post("mymetro set to default tempo of %ld ms", DEFAULT_TEMPO); } m->m_clock = clock_new(m, (method)clock_function); // create the metronome clock intin(m, 2); // create the 3rd inlet intin(m, 1); // create the 2nd inlet m->m_time_outlet = intout(m); // create right outlet for time m->m_bang_outlet = bangout(m); // create left outlet for ticks return(m); } /************************************************************************************* metro_in1(t_metro *m, long value) inputs: m -- pointer to our object value -- value received in the inlet description: stores the new metronome tempo value *************************************************************************************/ void metro_in1(t_metro *m, long value) { m->m_interval = value; // store the new metronome interval post("metronome tempo changed to %ld", value); } /************************************************************************************* metro_in2(t_metro *m, long value) inputs: m2 -- pointer to our object value2 -- value received in the inlet description: stores the new metronome tempo value *************************************************************************************/ void metro_in2(t_metro *m, long value2) { m->m_interval2 = value2; // store the new metronome interval post("2nd beat changed to %ld", value2); } /************************************************************************************* void metro_bang(t_metro *m) inputs: m -- pointer to our object description: method called when bang is received: it starts the metronome *************************************************************************************/ void metro_bang(t_metro *m) { long time; time = gettime(); // get current time clock_delay(m->m_clock, 0L); // set clock to go off now post("clock started at %ld", time); } /************************************************************************************* void metro_stop(t_metro *m) inputs: m -- pointer to our object description: method called when myMetro receives "stop" message. Stops the metronome *************************************************************************************/ void metro_stop(t_metro *m) { long time; time = gettime(); // get current time clock_unset(m->m_clock); // remove the clock routine from the scheduler outlet_int(m->m_time_outlet, time); post("metronome stopped at %ld", time); } /************************************************************************************* void clock_function(t_metro *m) inputs: m -- pointer to our object description: method called when clock goes off: it outputs a bang to be sent to the outlet and resets the clock to go off after the next interval. *************************************************************************************/ void clock_function(t_metro *m) { long time;
    time = gettime(); // get current time clock_delay(m->m_clock, m->m_interval); // schedule another metronome click outlet_bang(m->m_bang_outlet); // send out a bang outlet_int(m->m_time_outlet, time); // send current time to right outlet post("clock_function 1 %ld", time); clock_delay(m->m_clock, m->m_interval2); // schedule another metronome click outlet_bang(m->m_bang_outlet); // send out a bang outlet_int(m->m_time_outlet, time); // send current time to right outlet post("clock_function 2 %ld", time); } /************************************************************************************* metro_free(t_metro *m) inputs: m -- pointer to our object description: method called when t_metro objects is destroyed. It is used to free memory allocated to the clock. *************************************************************************************/ void metro_free(t_metro *m) { clock_unset(m->m_clock); // remove the clock routine from the scheduler clock_free(m->m_clock); // free the clock memory }

    • Dec 09 2006 | 9:01 pm
      In clock_function(), you're setting the same clock twice. You need to use two clocks.
      JM
    • Dec 09 2006 | 9:02 pm