Arguments in *_new

Oct 13, 2006 at 5:21pm

Arguments in *_new

I am working on a UB version of McCartney’s pulse object. It compiled and
runs fine except that it ignores the arguments. I am guessing that I should
change the header to use argc and argv. Does anyone have an example of how
that works? There are four arguments (here t n d b) that may be omitted
with default values supplied as below.

/* function run to create a new instance of the Pulse class */
void *pulse_new(long t, long n, long d, long b)
{
Pulse *x;

x = (Pulse *)newobject(pulse_class); /* allocates memory and sticks
in an inlet */

intin(x,4);
intin(x,3);
intin(x,2);
intin(x,1);
x->p_out2 = intout(x);
x->p_out1 = intout(x);
x->p_clock = clock_new(x, (method)pulse_tick);
x->p_tempo = (t==0) ? 120 : ((t<5) ? 5 : ((t>500) ? 500 : t));
x->p_durnumer = (n< =0) ? 1 : n;
x->p_durdenom = (d< =0) ? 4 : d;
x->p_maxbeats = (b< =0) ? 0 : b;
x->p_changenumer = 0;
x->p_changedenom = 0;
x->p_onoff = 0;
return (x); /* always return a copy of the created
object */
}

Cheers
Gary Lee Nelson
Oberlin College
http://www.timara.oberlin.edu/GaryLeeNelson

#28123
Oct 13, 2006 at 5:51pm

Gary –

What does your setup() function look like in main()? I think it should
read something like this:

setup((struct messlist **)&pulse_class, (method)pulse_new,
(method)dsp_free, (short)sizeof(t_pulse), 0L, A_DEFLONG, A_DEFLONG,
A_DEFLONG, A_DEFLONG, 0);

(I’m assuming pulse is an msp object…?)

brad

http://music.columbia.edu/~brad

On Fri, 13 Oct 2006, Gary Lee Nelson wrote:

> I am working on a UB version of McCartney’s pulse object. It compiled and
> runs fine except that it ignores the arguments. I am guessing that I should
> change the header to use argc and argv. Does anyone have an example of how
> that works? There are four arguments (here t n d b) that may be omitted
> with default values supplied as below.
>
> /* function run to create a new instance of the Pulse class */
> void *pulse_new(long t, long n, long d, long b)
> {
> Pulse *x;
>
> x = (Pulse *)newobject(pulse_class); /* allocates memory and sticks
> in an inlet */
>
> intin(x,4);
> intin(x,3);
> intin(x,2);
> intin(x,1);
> x->p_out2 = intout(x);
> x->p_out1 = intout(x);
> x->p_clock = clock_new(x, (method)pulse_tick);
> x->p_tempo = (t==0) ? 120 : ((t<5) ? 5 : ((t>500) ? 500 : t));
> x->p_durnumer = (n< =0) ? 1 : n;
> x->p_durdenom = (d< =0) ? 4 : d;
> x->p_maxbeats = (b< =0) ? 0 : b;
> x->p_changenumer = 0;
> x->p_changedenom = 0;
> x->p_onoff = 0;
> return (x); /* always return a copy of the created
> object */
> }
>
>
> Cheers
> Gary Lee Nelson
> Oberlin College
> http://www.timara.oberlin.edu/GaryLeeNelson
>
>
>

#86026
Oct 13, 2006 at 6:00pm

Bradford Garton wrote:

> Gary –
>
> What does your setup() function look like in main()? I think it should
> read something like this:
>
> setup((struct messlist **)&pulse_class, (method)pulse_new,
> (method)dsp_free, (short)sizeof(t_pulse), 0L, A_DEFLONG, A_DEFLONG,
> A_DEFLONG, A_DEFLONG, 0);

Well spotted. The code I sent him is really old and has this:

/* set up the class */
setup(&pulse_class, pulse_new, 0L, (short)sizeof(Pulse),
0L, A_DEFLONG, A_DEFLONG, A_DEFLONG, A_DEFLONG, 0);

I remeber I once had a similar porblem and putting all the (method)s
there solved the problem.
Additionally the dsp_free (or a private free function that does this
job) is missing here.

Olaf

#86027
Oct 13, 2006 at 6:10pm

Pulse is McCartney’s tempo object for Max – not MSP. Setup is this.

setup((t_messlist **)&pulse_class, (method)pulse_new,0L,
(short)sizeof(Pulse), 0L, A_GIMME, 0);

I replaced the new function with this borrowed from forgotten code by some
guy named Gary Nelson. It now works.

/* function run to create a new instance of the Pulse class */
void *pulse_new(t_symbol *s, short argc, t_atom *argv)
{
Pulse *x;
long t,n,d,b = 0;
x = (Pulse *)newobject(pulse_class); /* allocates memory and sticks
in an inlet */

intin(x,4);
intin(x,3);
intin(x,2);
intin(x,1);

if (argc)
{
switch(argv->a_type)
{
case A_LONG: t = argv->a_w.w_long;break;
case A_FLOAT: t = argv->a_w.w_float;break;
}
argv++;
argc–;
} else t = 0;
if (argc)
{
switch(argv->a_type)
{
case A_LONG: n = argv->a_w.w_long;break;
case A_FLOAT: n = argv->a_w.w_float;break;
}
argv++;
argc–;
} else n = 0;
if (argc)
{
switch(argv->a_type)
{
case A_LONG: d = argv->a_w.w_long;break;
case A_FLOAT: d = argv->a_w.w_float;break;
}
argv++;
argc–;
} else d = 0;
if (argc)
{
switch(argv->a_type)
{
case A_LONG: b = argv->a_w.w_long;break;
case A_FLOAT: b = argv->a_w.w_float;break;
}
argv++;
argc–;
} else b = 0;

x->p_out2 = intout(x);
x->p_out1 = intout(x);
x->p_clock = clock_new(x, (method)pulse_tick);
x->p_tempo = (t==0) ? 120 : ((t<5) ? 5 : ((t>500) ? 500 : t));
x->p_durnumer = (n< =0) ? 1 : n;
x->p_durdenom = (d< =0) ? 4 : d;
x->p_maxbeats = (b< =0) ? 0 : b;
x->p_changenumer = 0;
x->p_changedenom = 0;
x->p_onoff = 0;
return (x); /* always return a copy of the created
object */
}

On 10/13/06 1:51 PM, “Bradford Garton” wrote:

> Gary –
>
> What does your setup() function look like in main()? I think it should
> read something like this:
>
> setup((struct messlist **)&pulse_class, (method)pulse_new,
> (method)dsp_free, (short)sizeof(t_pulse), 0L, A_DEFLONG, A_DEFLONG,
> A_DEFLONG, A_DEFLONG, 0);
>
> (I’m assuming pulse is an msp object…?)
>
> brad
> http://music.columbia.edu/~brad
>
>
> On Fri, 13 Oct 2006, Gary Lee Nelson wrote:
>
>> I am working on a UB version of McCartney’s pulse object. It compiled and
>> runs fine except that it ignores the arguments. I am guessing that I should
>> change the header to use argc and argv. Does anyone have an example of how
>> that works? There are four arguments (here t n d b) that may be omitted
>> with default values supplied as below.
>>
>> /* function run to create a new instance of the Pulse class */
>> void *pulse_new(long t, long n, long d, long b)
>> {
>> Pulse *x;
>>
>> x = (Pulse *)newobject(pulse_class); /* allocates memory and sticks
>> in an inlet */
>>
>> intin(x,4);
>> intin(x,3);
>> intin(x,2);
>> intin(x,1);
>> x->p_out2 = intout(x);
>> x->p_out1 = intout(x);
>> x->p_clock = clock_new(x, (method)pulse_tick);
>> x->p_tempo = (t==0) ? 120 : ((t<5) ? 5 : ((t>500) ? 500 : t));
>> x->p_durnumer = (n< =0) ? 1 : n;
>> x->p_durdenom = (d< =0) ? 4 : d;
>> x->p_maxbeats = (b< =0) ? 0 : b;
>> x->p_changenumer = 0;
>> x->p_changedenom = 0;
>> x->p_onoff = 0;
>> return (x); /* always return a copy of the created
>> object */
>> }
>>
>>
>> Cheers
>> Gary Lee Nelson
>> Oberlin College
>> http://www.timara.oberlin.edu/GaryLeeNelson
>>
>>
>>

Cheers
Gary Lee Nelson
Oberlin College
http://www.timara.oberlin.edu/GaryLeeNelson

#86028
Oct 13, 2006 at 6:44pm

Olaf,

I expected that the code would be old so I went over it carefully removing
the A4 references and dependence on a resource file for the assist messages.
I just posted the whole thing on my download page – link below. Thanks so
much Olaf.

Cheers
Gary Lee Nelson
Oberlin College
http://www.timara.oberlin.edu/GaryLeeNelson

On 10/13/06 2:00 PM, “Olaf Matthes”

wrote:

> Bradford Garton wrote:
>
>> Gary –
>>
>> What does your setup() function look like in main()? I think it should
>> read something like this:
>>
>> setup((struct messlist **)&pulse_class, (method)pulse_new,
>> (method)dsp_free, (short)sizeof(t_pulse), 0L, A_DEFLONG, A_DEFLONG,
>> A_DEFLONG, A_DEFLONG, 0);
>
> Well spotted. The code I sent him is really old and has this:
>
> /* set up the class */
> setup(&pulse_class, pulse_new, 0L, (short)sizeof(Pulse),
> 0L, A_DEFLONG, A_DEFLONG, A_DEFLONG, A_DEFLONG, 0);
>
>
> I remeber I once had a similar porblem and putting all the (method)s
> there solved the problem.
> Additionally the dsp_free (or a private free function that does this
> job) is missing here.
>
> Olaf

#86029
Oct 14, 2006 at 1:47am

This dialog is interesting, but does nothing to explain Gary’s problem.

The only difference between Brad’s and Olaf’s code are typecasts. The stack is set up identically in either case (bar the NULL vs. dsp_free item, but since Gary has confirmed that pulse is plain-vanilla Max, that ain’t an issue). And since Gary was complaining about runtime issues, not compiler warnings (of which he presumably has legions, it is not possible to compile a Max object in XCode without spurious warnings), the question remains:

Why was (… A_DEFLONG, A_DEFLONG, A_DEFLONG, A_DEFLONG, 0) not working?

Can anyone else confirm this? Unfortunately (as I’ve mentioned elsewhere) I can’t run XCode on my road machine, so I can’t try this myself. If four A_DEFLONGs won’t work in Mach-O externs, that’s worth knowing about.

It’s true that A_GIMME seems to be the future (it’s required of pattr-savvy objects), but there are still lots of objects using A_DEFLONG, A_DEFFLOAT, and A_DEFSYM.

Finally, a word to Gary: looking at your code, what happens if the user is naughty and types a symbol in your object’s argument list? Typnig misteaks ni arugmnet lsits happne moer ofetn thna w eliketo thnik. (Examining your code closely, what happens isn’t disastrous but is not conventional behavior either.) You might want to make use of the new argv/argc parsing functions that were introduced with the Max 4.0 API and/or add some type checking.

– Peter

Quote: Olaf Matthes wrote on Fri, 13 October 2006 20:00
—————————————————-
> Bradford Garton wrote:
>
> > Gary –
> >
> > What does your setup() function look like in main()? I think it should
> > read something like this:
> >
> > setup((struct messlist **)&pulse_class, (method)pulse_new,
> > (method)dsp_free, (short)sizeof(t_pulse), 0L, A_DEFLONG, A_DEFLONG,
> > A_DEFLONG, A_DEFLONG, 0);
>
> Well spotted. The code I sent him is really old and has this:
>
> /* set up the class */
> setup(&pulse_class, pulse_new, 0L, (short)sizeof(Pulse),
> 0L, A_DEFLONG, A_DEFLONG, A_DEFLONG, A_DEFLONG, 0);
>
>
> I remeber I once had a similar porblem and putting all the (method)s
> there solved the problem.
> Additionally the dsp_free (or a private free function that does this
> job) is missing here.
>
> Olaf
>
—————————————————-

#86030
Oct 14, 2006 at 3:53am

On Sat, 14 Oct 2006, Peter Castine wrote:

> The only difference between Brad’s and Olaf’s code are typecasts.

Right — I had asked Gary because I didn’t know how he was using the
setup(). I was also surprised that the typecasts would have made a
difference.

> Why was (… A_DEFLONG, A_DEFLONG, A_DEFLONG, A_DEFLONG, 0) not working?

I grabbed that from another object where the params were indeed recognized
properly.

I guess A_GIMME is the way to go.

brad

http://music.columbia.edu/~brad

#86031
Oct 14, 2006 at 7:52am

— Original Message —
> On Sat, 14 Oct 2006, Peter Castine wrote:
>
> > The only difference between Brad’s and Olaf’s code are typecasts.
>
> Right — I had asked Gary because I didn’t know how he was
> using the
> setup(). I was also surprised that the typecasts would have
> made a
> difference.
>
> > Why was (… A_DEFLONG, A_DEFLONG, A_DEFLONG, A_DEFLONG, 0) not working?
>

Another reason this is dangerous is that IIRC there is an arbitrary limit (maybe floats only, I forget) to how many of these arguments you can call for. Five in a row could cause parameter passing to mysteriously choke.

>
> I guess A_GIMME is the way to go.
>

Definitely. It’s just too bad you never get to write A_GIMME, A_GIMME, A_GIMME, in honor of Black Flag.

:)

Eric

#86032

You must be logged in to reply to this topic.