getpath of a clip only with deferlow?

Nov 9, 2011 at 11:11am

getpath of a clip only with deferlow?

Clicking on a MIDI Clip [live.path] sends out an id which goes to [live.object] to get the path of the Clip. I don’t understand why it works only with [deferlow] right after [live.path]. Can anyone explain this?
I attached the device…

#59913
Nov 9, 2011 at 11:17am

here’s the device…

#215688
Nov 9, 2011 at 12:53pm

Quote from the docs (Live API Overview):

Note: changes to a Live Set and its contents are not possible from a notification. The error message in the Max Window is ‘Changes cannot be triggered by notifications’. In many cases putting a deferlow between the notification outlet and the actual change helps to resolve the issue.

#215689
Nov 9, 2011 at 12:58pm

Thanks, I know this quote. I should probably reframe my question: why is implemented this way?

#215690
Nov 9, 2011 at 1:37pm

I’d guess it’s for prevention of feedback loops.
(not sure if the developers want to discuss implementation details)

#215691
Nov 9, 2011 at 1:48pm

yeah maybe. But then I wonder why it’s not set to low priority in the first place? Oh, it seems to behave differently depending on where the live.object points at. It works with getting the path of a track f.e.

#215692
Nov 10, 2011 at 2:33am

I think the whole deferlow thing is unclear – for me it’s a bit like if it doesn’t work, stick a couple of deferlows in.. If we understood why they are required, the mechanics behind it, it would be easier to program efficiently. Apologies if it actually is explained somewhere, I searched but couldn’t find it.

#215693
Nov 10, 2011 at 10:25am

Here is an article that explains some relevant aspects of the Max execution model.

http://cycling74.com/2004/09/09/event-priority-in-max-scheduler-vs-queue/

#215694
Nov 10, 2011 at 10:36am

Thanks, I know this article as well. =)
I think I just considered getting the path of a MIDI Clip by clicking on it so basic that I didn’t expect it to be necessary to use any tricks. M4L ain’t easy to tame…

#215695
Nov 10, 2011 at 11:09am

Here’s my understanding of deferlow – can you tell me if this is correct?
Everything below (and connected to) the deferlow object is executed with the lowest priority – effectively allowing other events to finish first, before the events below deferlow object.

in the case of M4L objects, what is that ‘thing’ or those events that need to finish first? what is that M4L object dependent on that requires it to be below a deferlow?

apologies if I completely misunderstood something!

#215696
Nov 10, 2011 at 11:28am

[deferlow] puts the message it receives at the end of the low priority thread (there is high priority and low priority) unlike [defer] which puts it at the front of the low priority thing (This of course also affects the objects downstream of [deferlow] but they are not “deferlowed” per se). So [deferlow] is the strongest slow-down you can do.

In this case it’s the sending out the id of the MIDI Clip I clicked on that is put to the very end of the queue. Why it has to do this to give back the path of a Clip but f.e. not of the track this Clip is on I don’t understand.

I’d think that if I can deferlow it than it could also be built into the object so it “just works”.

#215697
Nov 10, 2011 at 11:57am

the thing about max is, whilst most of it is easy to learn and use, it wants to give you so much flexibility, individuality and level of control like no other app, that sometimes you run into these sort of issues (the perennial “scheduler” issue) that you wish “it just took care of it for me”, but it cannot be that way, as then you would not have all that amazing control and uniqueness.

however, i do not think that this issue is particularly complex at all, and once you have been patching with max a while it starts to make more and more sense and becomes natural to take into account. even though the helpfiles explain it very well, here is my potentially nightmare explanation, i hope it helps a bit:

– Pasted Max Patch, click to expand. –
#215698
Nov 10, 2011 at 12:02pm

by the way

“I’d think that if I can deferlow it than it could also be built into the object so it “just works”.”

… usually, the reason one thing has to be deferlow-ed when another does not and you are not expecting it, is simply to do with bad patching practices and not following your execution orders exactly correctly. the problem with deferlow is that it ‘makes stuff work’ so it gets way overused, whereas ones use of it should not be frivilous but very exacting. if you need 10 in a simple patch then something is usually very wrong with the patch, not the execution / thread calling of Live/Max.

#215699
Nov 10, 2011 at 12:11pm

Wow nice patch – you must have a lot of time!

Did you have a look at my attached .amxd? Why does it need deferlow in this specific case? I can’t see any bad patching practice in it.

#215700
Nov 10, 2011 at 12:29pm

Pid – I completely agree, I’d want my patches to be defer low-free if possible. I build all my abstractions to Max object conventions like get triggered by the left-most input, and try to build my patches so that they execute in the right order just by design (left-to-right arrangement of objects etc), and use a lot of triggers to add control of execution order.

Which makes it so much more interesting to understand why m4l needs deferlows to operate! And not knowing why/when to use them and when not means you end up using many more than required, because at the end of the day you want it to work….

I’ll look at your patch when I get home, I hope it will clear things up for me!

#215701
Nov 10, 2011 at 12:40pm

@ pure

regarding your track example: Do you get the same error/warning message as with the clip?

(right-click on the device title bar and select ‘Open Max window’).

#215702
Nov 10, 2011 at 12:56pm

@broc: nope

I attached an updated version with a [live.path live_set this_device canonical_parent] in it that shows that getpath works without [deferlow] in this case.

#215703
Nov 10, 2011 at 1:57pm

@pure

I think your second example shows normal behavior because the path calculation is simple and thus can easily be performed in real time (high priority). In contrast, the path calculation of ‘detail_clip’ is much more complicated since the clip may reside anywhere in the set depending on user interaction (selection).

#215704
Nov 10, 2011 at 2:11pm

ok, broc is the expert, listen to her/him. however, i’ll add…

no, sorry, i did not look at your .amxd originally – i was just answering to the ‘deferlow’ issues. however, i have looked at your example device now and the answer is very simple and is a tricky part of the API that has always been there (and documented), namely: you cannot trigger processes based on observed notifications from the API.

this is one of the API ‘rules’. it is for this very reason that use of the [deferlow] object was envisioned, and its use here is perfect and correct and exactly as you had it. there was possibly confusion because [live.path] is not strictly an ‘observer’ object but, give it the argument you gave it to track straight to “detail_clip” and it becomes one.

therefore we ascertain that SOME parts of the API are slow, in terms of callbacks. as broc said, “the path calculation of ‘detailed_clip’ is much more complicated as the clip may reside anywhere in the set depending on user interaction”.

i attach a .amxd device based on yours demonstrating this, although i am sure you get it… disclaimer: i am no API expert – i delve into it now and then.

hth .

#215705
Nov 10, 2011 at 3:18pm

Pid, thanks for the valuable comment. Apparently I’m not the only expert here if at all…

#215706
Nov 10, 2011 at 3:42pm

@broc
easy vs. complicated path calculation: OK, if this is what it is I can live with that. Is anywhere documented which calls are what?

@pid
so sending an id is an “observed notification from the API” and doesn’t work, but deferring the same to the end of the low priority thread works. uh…

I just tried one more thing which really baffles me: even when I [zl reg] the id for a second before passing it on to [live.object] it won’t work. So it’s somehow not about the time but the thread it is attached to. or so…

#215707
Nov 10, 2011 at 5:12pm

easy vs. complicated path calculation: OK, if this is what it is I can live with that. Is anywhere documented which calls are what?

No, unfortunately. But I’m not sure if a strict classification would be possible.

#215708
Nov 10, 2011 at 6:10pm

“So it’s somehow not about the time but the thread it is attached to. or so…”

- well done, you got it! as i demonstrated in my initial crazy patch-description of [defer] and [deferlow], with [defer] (or [delay], or [pipe], or [s]/[r] etc) it is not possible to pinpoint the exact execution order, but with [deferlow] it is. this is why it works to [deferlow] on an ‘observer notification’ from the live api because it is saying ‘do everything you need to do, when you have done that, let me know and i will execute’. it is nothing to do with ‘id’s in general – you can happily trigger as many as you want so long as not directly from a notification. with the tricky business of ‘you cannot start another process based on a live api observer,’ think of it like a digital audio feedback loop – it cannot be done like in the analog domain – you need a sample of delay (in gen~!) or a vector of delay (in msp).

re: “easy vs. complicated path calculation” – sort of; it is more about ‘possible to predict time scale of callback’ and ‘NOT possible to predict…’; but in general, yes. “No, unfortunately. But I’m not sure if a strict classification would be possible” – exactly. it is not about a ‘list’ of objects or api calls that always need [deferlow], it is more about realising general situations in which these things are needed. so no list. however, i do agree that the documentation on this could be better. e.g. there should be a discussion-chapter somewhere in the docs about ‘strategies for programming with the live api and fitting everything else in and around it’. or a snappier title of course. preferably not written by such a hacky douchebag as myself that does not really know what the hell he is talking about.

api calls in both live and max (and most other media software on the planet) happen in a slower, deferred, not as high priority and to some degree unpredictable thread, because the important stuff – audio (and video, but that is different again) – must never get interrupted or glitch. in fact live and max are two of the most amazing and robust softwares in this regard and it is one of the things that makes them special. letting ‘us’ in there, right in the guts of the software, to mess around and hack and create our own things, is very tricky and sometimes difficult. but that is what max is. i am constantly amazed that max even works at all with me abusing it all the time.

and yes, obviously, i had a pretty slow day today (!!), but i just got an email with some c++ stuff in it so i’ll be locked away this weekend doing that as i really suck at it.

p.s. broc is still the man! i learn loads from him!

#215709
Nov 11, 2011 at 2:37am

Seriously helpful thread! I finally understand the language they’re using in the manuals.
the below may be obvious? let me know…

I think you can interpret the message “live.object: Setting the Id cannot be triggered by notifications” as follows:
1) because you clicked a different clip in Live, the live.path object had to send out a new path ID. this is a notification
2) the notification (the new path ID) was going to set the ID for the live.object BUT.. “Setting the Id cannot be triggered by notifications”

But not everything you do (even some possibly complicated stuff) is triggered by a ‘notification’ from live: eg if you trigger the path directly by clicking a message box with the path name. Maybe the attached device illustrates it. I changed from ‘getpath’ to ‘get name’ because it illustrates my point a bit better. It definitely means I can get rid of a lot of deferlows in my patches.

I think I learned more in 3 months on this forum than I have in the year before :-)

#215710
Nov 11, 2011 at 2:57am

Awesome. I just was able to cut out 32 deferlows (see clipping) : not understanding when they were required, I had a deferlow after every live.path that was feeding an id into a live.object. Now I know when I need them and when I don’t!

– Pasted Max Patch, click to expand. –
#215711
Nov 11, 2011 at 2:25pm

@ basvik

I think your .amxd example illustrates the ‘notification’ aspect very well.
For clarity of the comparison, ‘getpath’ may be replaced by ‘b’ (purely cosmetic).

It would be nice to have examples like this in the documentation/tutorials of M4L.

#215712
Nov 11, 2011 at 4:36pm

Thanks broc, much appreciated.

agreed. I’ve actually learned so much in the past weeks I may gather it up and put it in a thread. (my dayjob is running a small technical training team in a big company, I don’t really want to take my work home!)

and yes my patch was a bit sloppy – (late night work) I like the [t getpath l] method, so much cleaner that using a message box: unfortunately it doesn’t work with ‘get name’!

#215713
Nov 11, 2011 at 5:08pm

@basvik “unfortunately it doesn’t work with ‘get name’”

it does – just not sure if it makes much sense ;)

– Pasted Max Patch, click to expand. –
#215714
Nov 11, 2011 at 5:51pm

@basvik

To clarify, I meant replacing [t getpath l] by [t b l] as getpath is used here only to trigger the message [get name].
So the appearance of getpath could be confusing at first sight.

#215715
Nov 11, 2011 at 6:43pm

@ broc: understood: this was just because I made the patch from editing other ones, a slip-up. From a trying-explain-the-issue point of view, superconfusing, I agree

@pure: i did try that too. I think I did a test using pedant to compare a [trigger object with symbol + fromsymbol] patch with [triggering a message box], but in terms of performance it doesn’t matter much: the API calls are slow and their time varies a lot, compared to the rest of the objects. So I guess that’s a good argument to just make the patch the way it is most readable.. I vote for triggering a message box

#215716
Jan 2, 2012 at 4:50am

Update – in case anyone reads this thread and finds it useful: I’ve been wrecking my head over the above: i think I figured out when and where I should use [deferlow] to prevent the “Setting the Id cannot be triggered by notifications” error messages, but M4L behaviour has been very inconsistent.

Turns out there is a BIG difference whether you have your device open for editing in Max (many more errors, and inconsistently: sometimes execution is fine, sometimes I get the error, and it seems to depend on how busy the system is whether or not you get the error). But when you have the M4L device running inside Live (ie _not_ open for editing) it behaves a lot more predictable

#215717
Jan 2, 2012 at 8:55am

yeah this happens with many objects. then having to clutter the little space you have in live with a lot of prints and bangs for debugging is quite annoying…

#215718
Jan 2, 2012 at 10:08am

In my experience, serious testing in edit mode is not possible. So in general I save (or even reload) the device and then look at the Max window in performance mode (open with right-click on the device title bar). Strictly speaking, interactive editing in M4L doesn’t really work as advertised.

#215719
Jan 2, 2012 at 11:38am

unfortunately true :(
though, still trying to ignore this fact =)

#215720
Jan 2, 2012 at 7:19pm

Maybe we should gather up a few of those ‘gotcha’s ‘
I think I saw the posts that said you can’t really do interactive editing but I ignored them – because on the surface it seems to work ok: it’s the unpredictability that really causes the frustration.

Now I get it – and my devices work so much better! So actually, I”m pleased :-) Happy New Year btw

#215721
May 29, 2013 at 8:02am

pid – if you cant make a call based off an observed value, then how can you make a call, like enter notes (sent by push) when the buttons are retrieved through an observer?

#251102

You must be logged in to reply to this topic.