Is there any way to observe when a device is moved?

    Jun 15 2010 | 2:24 am
    Hoping the answer is yes. Is there a way to be notified when a device is moved within the set? When a device is moved, I would like to use its ID obtain its new path and save it with M4L.api.SaveLivePath.maxpat

    • Jun 15 2010 | 8:41 am
      I think the answer is no, but your method wouldn't work anyway.
      Quote from the documentation:
      "If the object is moved in Live, its id usually remains unchanged. There may be exceptions if the movement is implemented as a delete/create sequence, though. When an object is deleted and a new object is created at its place, it will get a new id."
      As I understand it, moving a device may result in a completely new configuration, i.e. previous id (and parameter mappings) are no longer valid.
    • Jun 15 2010 | 12:49 pm
      hmm, the snippet you quoted says the id "usually remains unchanged" so I think my method would "usually" work except in the case they mention about deleting/creating.
      It's really blowing my mind that if I want to use a M4L device that observes params of another device, I can't modify my set without having to rewire the M4L device next time I open the set.
      It seems like if Live assigned a unique GUID to all devices on creation and retained them across closing/opening, this problem would be solved but maybe I'm simplifying things too much.
    • Jun 15 2010 | 5:53 pm
      It depends what you mean by "modifying my set"
      If you cut and paste a device which has a key or MIDI mapping, you will lose the mapping. There's no way that could ever work.
      If you are talking about modifications like adding tracks and changing the location of your device, then have a look at the left outlet of live.path.
    • Jun 15 2010 | 9:00 pm
      live.path has two outlets: follows path and follows ID. If you always compare those both you should be able to detect when the device is moved. Than you can grab the path via the getpath method.
    • Jun 16 2010 | 12:27 am
      I'm using M4L.api.DeviceParameterRemote.maxpat which makes use of M4L.api.SaveLivePath.maxpat which uses the left outlet of live.path and outputs that back into the live.object and back into the M4L.api.SaveLivePath.maxpat patch. Is that not enough?
      (And to answer your question, by 'modifying the set' I just mean creating new tracks/devices or possibly dragging a device to a new location)
      I understand that I can compare the path vs. the ID to tell if it's been moved. The question is *when* do I compare this? If I don't know when the user has moved the device, I don't know when to do the comparison and store a new path.
      Seems like this problem could be solved if I had a "DeviceMoved" event to bind to or a "SetBeingClosed" event to bind to.
    • Jun 16 2010 | 1:44 am
      M4L.api.SaveLivePath sets its path using the path message
      Live.path's left outlet only responds to a bang, getid or goto message. Check the ref.
      I recommend that people who are becoming more advanced in the use and design of Live API patchers get their hands dirty and work at the object level rather than the abstraction level. It's a little more learning pain, but worth it for the flexibility
    • Jun 16 2010 | 2:14 am
      Seconded. You can do a lot more with code that does precisely what you want instead of reusing code that is, by its very nature, designed to accommodate anyone using m4l for the first time out of the box. Most of the time I find the abstractions included with the toolkit to be too cumbersome to use in my own patches. They are good to study and get an idea of how the API works.
    • Jun 16 2010 | 9:24 am
      just a small chime in here, but it is worth pointing out that using pattr to save/restore paths in abstractions, ie, somewhere not in the top level m4l patcher, became broken in max 5.1.4. apparently it will be fixed for 5.1.5.
      is adamribaudo currently suffering - partly - from this issue? (i am!).
      other than that i third andrew / amounra - always build your own.
    • Jun 16 2010 | 12:47 pm
      I feel like we're getting hung up that I'm using M4L.api.SaveLivePath.
      My original question, and the question that I posed to Ring, was "Can I observe when a device has been moved and take action as a result? How do I know *when* to bang live.path to get the device's new location? "
      Even conceptually, I still don't understand how I can build a patch that is smart enough to re-save a device path after the target device has been moved and before the set is closed.
      pid - good thinking, but that's fixed in the latest beta so I'm all set there.
    • Jun 16 2010 | 10:21 pm
      there are a variety of ways to keep track of devices, here is one:
      Other options include monitoring the currently selected track->currently selected device, or managing/querying arrays of IDs in JS.
    • Jun 17 2010 | 12:22 am
      Thanks so much!
      I was actually looking to track the movement of another device, not the current device, but was able to edit your patch easily enough to do so. My implementation is below.
      This is just me ranting a bit but to me it makes sense for Cycling to add Ben's pattern into the provided M4L "DeviceParameterRemote" patch to fix the problem mentioned above. I understand the importance of learning how abstracted patches work, but every M4L developer shouldn't have to implement their own "Select a device parameter and hold on to it across sets" sub-patch. That problem is common enough that it only needs to be solved once and then everyone can get the benefits. Then, as the community finds frequently used patterns, Cycling can incorporate those abstracted building blocks into their distribution. As evidence of this problem, look at the "utilities" section of I found multiple devices with the problem mentioned in this thread that Ben just provided a solution for.
      In my mind, Max is a lot like JavaScript in the sense that the output is by nature open source. If you're familiar with JavaScript, you know what jQuery has done to catapult the language and bring in new developers because they took a difficult language and created commonly used abstractions for manipulating the DOM that anyone could use. I feel like conversely, M4L has developers silo'd, each working on the same problems individually rather than pulling from a library of abstracted code. This is evidenced by the 3 posters above who told me not to use the provided M4L patches and to build my solution from scratch.
      What I'm proposing is instead of viewing the provided M4L patches as examples, view them as the defacto way of accomplishing those tasks that will work 95% of the time. And if they are to going be the defacto solutions, update them as problems are found.
      Here's my implementation that tracks a device other than "this_device":
    • Jun 17 2010 | 1:29 am
      Seconded. I'd love to be able to draw from a library of ready-made source libraries to complete my objectives, it would save a lot of time.
      I'm looking for good solutions to the same question you originally asked, and haven't come to a conclusion on how I'm going to solve the problem. The solution works for a device, but what about when trying to keep track of ALL devices. BLOAT. And the more m4l has to keep track of in the API, the slower it becomes. Up to now I've just rebuilt the id table in JS with each track addition, but this is painfully slow when using a lot of API objects.
      Max has been around for a while, and I've been using it for a while. There are a lot of resources. M4l on the other hand, not the case. It will take time. As much as Max is a niche developer environment, m4l is even more so, and that is going to make it harder to pull more people into it.
      Just consider me the (sarcastic) yes-man of this thread ;)
    • Jun 17 2010 | 3:16 am
      To round things out, here is my "M4L.api.DeviceParameterRemote.maxpat" implementation that re-saves the path of the param after its device has moved within the set. I feel like it's a little bloated but it works and that's good enough for me for now ;)