Forums > Javascript

bugreport: inlet property gives incorrect inlet number

January 1, 2007 | 9:31 pm

Hi all,

I output a bang that triggers a message back into js, which is catched by anything(). The inlet property then reports an incorrect inlet number. Have a look at the example below.

—- save as "test.js":

outlets = 1;
inlets = 2;
autowatch = 1;

function go()
{
outlet(0, "bang");
}

function anything()
{
post("input in inlet " + inlet + ": " + messagename);
}

—- save as anything:

#P message 53 79 19 9109513 yo;
#P message 109 58 18 9109513 go;
#P newex 75 79 44 9109513 js test.js;
#P connect 0 0 2 0;
#P connect 2 0 0 0;
#P connect 1 0 0 1;

Expected output:
input in inlet 0: yo

Actual output:
input in inlet 1: yo

Windows XP, Max 4.6.2

I hope someone can confirm.

Thanks,
Mattijs


January 2, 2007 | 9:57 pm

On Jan 1, 2007, at 1:31 PM, Mattijs Kneppers wrote:

> I output a bang that triggers a message back into js, which is
> catched by anything(). The inlet property then reports an incorrect
> inlet number. Have a look at the example below.

In general, this type of recursion is not supported for objects which
use proxy inlets, as does js, all MSP objects and many more. You’ll
need to use some kind of event deferral or something to separate the
recursion into multiple events sequenced over time.

To re-phrase, the reported inlet number cannot be relied upon to be
accurate in the instance of feedback loops. Hope this helps.

-Joshua


January 5, 2007 | 1:10 am

Quote: jkc wrote on Tue, 02 January 2007 22:57
—————————————————-
>
> On Jan 1, 2007, at 1:31 PM, Mattijs Kneppers wrote:
>
> > I output a bang that triggers a message back into js, which is
> > catched by anything(). The inlet property then reports an incorrect
> > inlet number. Have a look at the example below.
>
> In general, this type of recursion is not supported for objects which
> use proxy inlets, as does js, all MSP objects and many more. You’ll
> need to use some kind of event deferral or something to separate the
> recursion into multiple events sequenced over time.
>
> To re-phrase, the reported inlet number cannot be relied upon to be
> accurate in the instance of feedback loops. Hope this helps.
>
> -Joshua

Thanks for your reply. It’s a pity, I would have loved to use a feedback loop this way. I guess that could be made a feature request since I believe this is not a conceptual but a technical limitation (am I right?).

Thanks,
Mattijs


January 5, 2007 | 10:13 am

On 1/5/07, Mattijs Kneppers wrote:
>
>
>
> Thanks for your reply. It’s a pity, I would have loved to use a feedback
> loop this way. I guess that could be made a feature request since I believe
> this is not a conceptual but a technical limitation (am I right?).
>
>
> Hi Mattijs,

Not sure how you would like to use that strategy, but if you can’t use
[defer(low)] inside the feedback loop, I doubt that what you’re trying to do
is the (only) way to go. If you give us an example, maybe someone can give
you a different solution.

cheers, -thijs


January 6, 2007 | 8:35 pm

Quote: thijskoerselman@gmail wrote on Fri, 05 January 2007 11:13
—————————————————-
> > Hi Mattijs,
>
> Not sure how you would like to use that strategy, but if you can’t use
> [defer(low)] inside the feedback loop, I doubt that what you’re trying to do
> is the (only) way to go. If you give us an example, maybe someone can give
> you a different solution.
>
> cheers, -thijs

Hi Thijs,

I’d love to show you what I’m working on. I attached the files. But although I tried to make nice help files to guide you through the idea I expect that it is quite complex (or complicated) to find out 1) how I made this work and 2) why I’m trying to do it.

Still, if you want to try, you’re more than welcome. If you find an alternative I’ll definitly buy you a beer.

In the attachment, to have a quick view of the idea, open 1.pat. For more explanation, open the .help files separately.

Let me know what you think ;)

Best,
Mattijs

Btw, the layout of the patchers is done on pc, didn’t test on mac. I hope it doesn’t look very bad on mac.


January 6, 2007 | 9:01 pm

On Jan 6, 2007, at 12:35 PM, Mattijs Kneppers wrote:

>
> Still, if you want to try, you’re more than welcome. If you find an
> alternative I’ll definitly buy you a beer.

Well, now that there’s an offer of alcohol involved, I’m a tad more
motivated to think about the problem ;)

I think that the following strategy works the way you wanted for your
initial example–i.e. copy the messagename and inlet properties to a
local variable. What happens internal to js is that messagename and
inlet are global to the script, set and overwritten with each message
call. Let me know if this doesn’t solve your problem.

test.js
——————————————-

inlets = 2;

function anything()
{
var mything = new String(messagename);
var myinlet = inlet;

if (mything == "first") outlet(0, "next");
post("messagename " + mything + ", inlet " + myinlet);
post();
}

-Joshua


January 6, 2007 | 9:53 pm

Quote: jkc wrote on Sat, 06 January 2007 22:01
—————————————————-
> Well, now that there’s an offer of alcohol involved, I’m a tad more
> motivated to think about the problem ;)
>
> I think that the following strategy works the way you wanted for your
> initial example–i.e. copy the messagename and inlet properties to a
> local variable. What happens internal to js is that messagename and
> inlet are global to the script, set and overwritten with each message
> call. Let me know if this doesn’t solve your problem.
>

The thread you’re referring to is about a different issue than this thread (although I agree they look similar): http://www.cycling74.com/forums/index.php?t=msg&th=23675&start=0&rid=3579&S=a181cd3c624d8aaaff66f98640ed2749

I posted my reply there and I can say I’ll happily buy you a beer the next time you’re in amsterdam or I’m in san fransisco! :)

I also tried your solution for the issue discussed in this thread and I am afraid it doesn’t work here. The beer for this one is still open ;)

Thanks for checking this out!
Mattijs

Btw Joshua, I can imagine you or someone else at cycling could find the zip file I attached in my previous post interesting to give a few moments of attention. It is an attempt to add a core concept to max that doesn’t exist yet. Or if you don’t have time to check it now, I will post it as a feature request later (or email to support).


January 6, 2007 | 11:12 pm

On Jan 6, 2007, at 1:53 PM, Mattijs Kneppers wrote:

> The thread you’re referring to is about a different issue than this
> thread (although I agree they look similar): http://
> http://www.cycling74.com/forums/index.php?
> t=msg&th=23675&start=0&rid=3579&S=a181cd3c624d8aaaff66f98640ed2749
>
> I posted my reply there and I can say I’ll happily buy you a beer
> the next time you’re in amsterdam or I’m in san fransisco! :)
>
> I also tried your solution for the issue discussed in this thread
> and I am afraid it doesn’t work here. The beer for this one is
> still open ;)

Ah, yes, sorry for confusing the two similar threads, since they are
similar problems and I didn’t have the energy to figure out what that
"pattr no matter how deep" example patch. .

This specific problem is with the leftmost inlet and proxies. This
issue exists for all Max objects. To better clarify the issue is that
the leftmost inlet is not a proxy inlet, and it doesn’t specifically
set the inlet number when receiving a message. All other inlets are
proxy inlets and do in fact record the inlet number and then reset
the inlet number to zero when done processing. Since this recursion
is happening mid-processing, the inlet number is not reset to zero.

I can’t think of a way to avoid this without some fairly serious
infrastructure change to Max, or one of the following workarounds
(which, while a bit ugly, should allow you to accomplish what you
want in the meantime):

1. Put your js file inside a sub patcher which prepends a message for
each inlet where you can accurately determine which inlet is called
based on the method name. Something like:

var myowninlet = 0;

function inletleft()
{
myowninlet = 0;
//your logic goes here
}

function inletright()
{
myowninlet = 1;
//your logic goes here
}

2. Declare 3 inlets and use the middle and rightmost inlet. Since
these two are both proxies, the correct inlet will be set upon
function entry, even with this sort of recursion (but after any such
recursive outlet call the global inlet value cannot be relied upon
and you’ll need to use local variables to cach on function entry like
my solution for the other thread)

Hope this helps…

-Joshua


January 8, 2007 | 12:51 am

On 1/6/07, Mattijs Kneppers wrote:
>
>
> I’d love to show you what I’m working on. I attached the files. But
> although I tried to make nice help files to guide you through the idea I
> expect that it is quite complex (or complicated) to find out 1) how I made
> this work and 2) why I’m trying to do it.

Yes it looks a little complicated, but for the most part I get what you’re
doing. My first impression is that you use a lot of objects/code for (what
it seems is) sharing ,addressing and initializing variables in some kind of
global scope. It looks like you put a lot of thought in it, and since there
is no way for me to know how you use it exactly I can’t really judge on
that.

Still, if you want to try, you’re more than welcome. If you find an
> alternative I’ll definitly buy you a beer.

Is the beer offer still open after Joshua’s reply? I just recovered from a
major hang-over but I’ll give it a shot;-)

> Let me know what you think ;)

Did you have a look at Jeremy’s pattrmarker? You can define a global name
within the pattr system, and use [pattr] in combination with "bindto" to
bind to a value anywhere in your patch without knowing where it is exactly.
(I just ran into an issue for which I will post a different tread). Of
course this doesn’t instantly replace the layer and voice things you have
going on in your code, but it might be an eyeopener if you haven’t looked at
it yet.

That’s as far as I go in my attempt to get a free beer.

hth.
cheers -thijs

btw: I didn’t find where you wanted to apply the js recursion.


January 8, 2007 | 10:18 pm

Hi Thijs,

Thanks for your replies. Yeah, I checked all possibilities of the pattr family (hence ‘try 15′ ;). The pattrmarker defines a global address while what I need is a semi-local variable (an ordinary variable in other programming languages, one that has a scope).

Roughly, this script searches up in the patcher hierarchy to bind to the first matching pattr. That’s what the recursion is currently used for. The whole thing is already fully functional but with a workaround for the issue discussed in this thread (check the TS.var.help file ;).

Thanks,
Mattijs

Btw, I was cheating. I normally buy ppl free beers without them having to return something. There’s a nice party in Utrecht 19 jan in Tivoli (Speedy J does a 3 hours acid set). If you’re around, let me know ;)

Quote: thijskoerselman@gmail wrote on Mon, 08 January 2007 01:51
—————————————————-
> On 1/6/07, Mattijs Kneppers wrote:
> >
> >
> > I’d love to show you what I’m working on. I attached the files. But
> > although I tried to make nice help files to guide you through the idea I
> > expect that it is quite complex (or complicated) to find out 1) how I made
> > this work and 2) why I’m trying to do it.
>
>
>
> Yes it looks a little complicated, but for the most part I get what you’re
> doing. My first impression is that you use a lot of objects/code for (what
> it seems is) sharing ,addressing and initializing variables in some kind of
> global scope. It looks like you put a lot of thought in it, and since there
> is no way for me to know how you use it exactly I can’t really judge on
> that.
>
> Still, if you want to try, you’re more than welcome. If you find an
> > alternative I’ll definitly buy you a beer.
>
>
> Is the beer offer still open after Joshua’s reply? I just recovered from a
> major hang-over but I’ll give it a shot;-)
>
>
> > Let me know what you think ;)
>
>
> Did you have a look at Jeremy’s pattrmarker? You can define a global name
> within the pattr system, and use [pattr] in combination with "bindto" to
> bind to a value anywhere in your patch without knowing where it is exactly.
> (I just ran into an issue for which I will post a different tread). Of
> course this doesn’t instantly replace the layer and voice things you have
> going on in your code, but it might be an eyeopener if you haven’t looked at
> it yet.
>
> That’s as far as I go in my attempt to get a free beer.
>
> hth.
> cheers -thijs
>
>
> btw: I didn’t find where you wanted to apply the js recursion.
>
>
>
—————————————————-


January 8, 2007 | 10:28 pm

Quote: jkc wrote on Sun, 07 January 2007 00:12
—————————————————-
> Ah, yes, sorry for confusing the two similar threads, since they are
> similar problems and I didn’t have the energy to figure out what that
> "pattr no matter how deep" example patch. .

I understand.

>
> This specific problem is with the leftmost inlet and proxies. This
> issue exists for all Max objects. To better clarify the issue is that
> the leftmost inlet is not a proxy inlet, and it doesn’t specifically
> set the inlet number when receiving a message. All other inlets are
> proxy inlets and do in fact record the inlet number and then reset
> the inlet number to zero when done processing. Since this recursion
> is happening mid-processing, the inlet number is not reset to zero.

That’s interesting information. I’d love to hear where I could find out more about these issues. The max sdk?

>
> I can’t think of a way to avoid this without some fairly serious
> infrastructure change to Max, or one of the following workarounds
> (which, while a bit ugly, should allow you to accomplish what you
> want in the meantime):
>
> 1. Put your js file inside a sub patcher which prepends a message for
> each inlet where you can accurately determine which inlet is called
> based on the method name. Something like:
>
> var myowninlet = 0;
>
> function inletleft()
> {
> myowninlet = 0;
> //your logic goes here
> }
>
> function inletright()
> {
> myowninlet = 1;
> //your logic goes here
> }

That’s right. I hoped to avoid the 2 extra [prepend set]s because this object is going to be used a lot. I’ll stick to the second option then :)

>
>
> 2. Declare 3 inlets and use the middle and rightmost inlet. Since
> these two are both proxies, the correct inlet will be set upon
> function entry, even with this sort of recursion (but after any such
> recursive outlet call the global inlet value cannot be relied upon
> and you’ll need to use local variables to cach on function entry like
> my solution for the other thread)

Cool, I didn’t know about proxy inlets. I tested it and it works!

>
>
> Hope this helps…

It does, thanks a lot.
Mattijs


Viewing 11 posts - 1 through 11 (of 11 total)