Signal inlets 2+ won't work

May 19, 2012 at 10:51am

Signal inlets 2+ won't work

I’m working on an external with five signal inlets, and I can’t seem to get any input from inlets 2 onward. I’ve included the project folder (an Xcode project) and the compiled external as an attachment, in case anybody wants to try those out. Here is my perform routine.

void rhythm_perform64(t_rhythm *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam)
{
    t_double *in3 = ins[2]; //works if I change to ins[1] or ins[0]
    t_double *outL = outs[0];
    t_double *outR = outs[1];
    int n = sampleframes;

    //fields
    int len = x->length;
    int wCount = x->writeCount;

	while (n--) {

        //write values to array
        if (wCount > len-1) {
            wCount = 0;
        }
	*outL++ = wCount;
        *outR++ = *in3++;

        //increment count and update value
        wCount++;
        x->writeCount = wCount;
    }
}

The code above will not get any output from outR. However, when I change the inlet declaration to ‘ins[1]‘ or ‘ins[0]‘, those inlet’s input is passed to the second outlet, as expected.

Here is my new instance routine, in which the inlets are initially created:

void *rhythm_new(t_symbol *s, long argc, t_atom *argv)
{
    t_rhythm *x = (t_rhythm *)object_alloc(rhythm_class);

    x->m_outlet3 = floatout((t_rhythm *)x);

	if (x) {
		dsp_setup((t_pxobject *)x, 5);

		outlet_new(x, "signal");
		outlet_new(x, "signal");
	}

	return (x);
}

As you can see, I HAVE created 5 inlets.

I haven’t found anything related to this in the documentation or the forums so far, so any help would be much appreciated.

Attachments:
  1. rhythm.zip
#63688
May 19, 2012 at 12:32pm

Hi John,
try to put the Z_NO_INPLACE flag into your new instance routine and it should work :

void *rhythm_new(t_symbol *s, long argc, t_atom *argv)
{
	t_rhythm *x = (t_rhythm *)object_alloc(rhythm_class);

    x->m_outlet3 = floatout((t_rhythm *)x);

	if (x) {
		dsp_setup((t_pxobject *)x, 5);	// MSP inlets: arg is # of inlets and is REQUIRED!
										// use 0 if you don't need inlets
		outlet_new(x, "signal"); 		// signal outlet (note "signal" rather than NULL)
		outlet_new(x, "signal");
	}

	x->ob.z_misc |= Z_NO_INPLACE; // < =

	return (x);
}
#229632
May 19, 2012 at 1:48pm

Aha! Works like a charm! But I must ask, why? All I got from the documentation was that it is a “flag indicating the object doesn’t want signals in place.” So what does ‘in place’ mean?

#229633
Jun 18, 2012 at 4:39pm

“in-place” refers to an optimization where memory may be shared between the input and output pointers. This reduces the amount of memory required to represent the signal vectors. The resulting behavior is that when you write to the output you are over-writing the input. Depending on the logic of your perform routine this may or may not be a problem.

In your particular case it is a problem that requires either the Z_NO_INPLACE flag or altering your perform method so that you don’t write to outL prior to reading from in3.

Hope this helps,
Tim

#229634
Aug 20, 2012 at 1:07am

Yo, Timothy and John I just want to say THANK YOU for this post. I’m writing a Max6 external that currently takes in three signal inputs and I couldn’t figure out what was going on. I’ve been beating my head against the wall for the past four hours. I was actually going to post about this exact problem when I decided to check and see if someone else had run into the issue.

#229635

You must be logged in to reply to this topic.