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