Monitoring the status of all clips... Help?

j_kusel's icon

Hello all!

I'm trying to build a clip launcher device for my Monome, and I'm having some difficulty with the API... Is there any way to tell a live.observer object to output ALL changes in ANY clip status, whether it be stopped, triggered, playing, etc.? I don't particularly want to create an object for every single clip (256) and have to update ALL of them, I have a feeling I'd get major slowdown.

Let me know if I can clarify anything, and thanks in advance!
-Jordan

Basvlk's icon

I'm in a similar boat but havent started yet on it. a friend who is doing a lot of M4L thinks CPU load -wise it should be no problem having 256 observers active, I'm not convinced yet (then again, I haven't tried it yet!)

for the 'pain' of creating 256 observers the following can help:
1) the 'Max Toolbox'
2) Scripting: you can let Max create the boxes you need with a little logic, have a look at the below, I needed 16 objects to create osc-formatting, all the same objects with just a different number. The code below did just that. Let me know if it doesn't make sense

Alternatively you could venture into JavaScript which will make it much simpler: you could write code that just iterates through 256 options. I think. in any case, you can probably organise it a little 'cleaner' with javascript

Max Patch
Copy patch and select New From Clipboard in Max.

(btw don't ask why I did it this way and not use 'substitute', I think I may be OCD -I discovered that using 'prepend' for each instance is the fastest (least CPU intensive) way of formatting these strings)

broc's icon

You can use [poly~] to create multiple observers (max 1023).

See for example this thread

Myr's icon

i've got a varibright and non varibright m4l clip launcher already built if you'd like to have a look ultraturtle0?

i opted for observing the playing_slot_index and fired_slot_index of tracks. i have a poly~ object set up with the two observers inside set to 64 voices. if you ever need more than 64 tracks you can edit it, but you can't create more voices at any time other than start up!

you cannot create live objects through scripting or poly~ voice changes!

but yes, the playing and fired slot indexes do for getting the playing or triggered information. i'm also observing whenever the visible tracks or scenes change and iterating through all clip_slots getting the has_clip property whenever a track or scene is added or deleted.

also whenever a tracks playing_slot_index changes above -1 I get the has_clip property of the playing clip_slot. this allows the clip grid to update whenever a new clip is recorded or whenever you play a clip which you've newly dragged into or moved around the session view.

i also provided a button on the monome which updates the entire clip grid in case you move a lot of clips around the set.

this seemed the best way to me to avoid having to set up observers for every clip slot and clip in session view.

although it could be easy to setup observers for only the clips and clip_slots currently in focus on the clip launcher.

j_kusel's icon

@basvlk, I'll give it a try just to see how much of a slowdown there is/isn't... If you attempt it though, let me know.

@broc, that's what I was thinking, I'll check out the thread. Apparently, everything has to be created beforehand though? Meaning, no recording/monitoring new clips? I can deal with that, but it wouldn't be ideal.

@Myr, I saw your M4L Control patches on the monome forums, but after downloading a few other peoples' clip launchers, it seemed like they were all read-only, so I kinda gave up and tried to bite the bullet and build one myself. I'm working on an all-in-one scrollable interface (ala stretta's plane) with an onscreen Jitter display, but a few of the devices (this included) have flatout stumped me. Are your patches unlockable? I'd love to take a peek under the hood...

EDIT: For the record, I've got a non-varibright monome.

Myr's icon

you have to create all the live api objects you want to use at startup. that doesn't mean they always have to be focused on the same id and doing the same job though!

for instance you could setup a poly~ with 256 voices each observing the has_clip property for an array of clip_slots.

you'd have 4 variables in your patch, number of tracks i.e 16 width of monome, number of scenes i.e 16 height of monome, and then track offset and scene offset so you can scroll around the session view left and right (imagine these could be on encoders like in stretta's plane app.

whenever any of these variables changes you iterate through the clip_slot ids for the currently focused clip_slots sending one id to each observer in a voice or poly~. so now you have an array of observers watching out for any added or removed clips within the focused clip grid.

in my experience it is getting the ids from live.path which takes the most time. so i have a device which monitors the children of most objects in the live api, visible_tracks, scenes, master track devices etc.

so whenever i am moving around session view with my clip grid i'm recalling the relevant ids, which i store in coll objects with globally accessible names (you can use the coll in any m4l object, removing the need to get ids multiple times with more than one clip launcher etc) and then sending them on the the right live.observers or live.objects.

makes for a pretty damn efficient and speedy clip launcher. is fine to scroll through pretty quickly with buttons on my monome. would be nice to attach to an arc or encoder though.

all of the m4l apps i've put up on the forum are from a few years ago, were programmed with the old version of m4l (before persistent ids), and have some horrible bad coding practices in them. i'd advise not using them for reference, heh. the new ones are much cleaner and more efficient, but not totally polished off with decent ui and such which is why i haven't posted them for everyone yet. i think they'd provide much better learning resources though.

patches in m4l cannot be locked! or i should say you can always open them by unfreezing them, there is no way of making them read only. so if you click the unfreeze button on any of the patches you've downloaded you'll be able to edit them and copy and paste ideas.

i'm just uploading my clip launcher code somewhere now. will have it posted up in a minute.

Myr's icon

Alright so all of my m4l devices are pretty modular, so to get the clip launcher to work you need three devices.

1. M4LC Hub. Gets all of the ids for all (well nearly) objects in the LOM hierarchy and observes all of the observable ones (well nearly) i.e tracks, visible_tracks, scenes, master track devices etc. it stores all of the ids in "value" and "coll" objects which are globally named, so you can use them in any other m4l device eliminating the need to get any ids in other m4l devices. It also sends all changes out over a send named "m4lc" and receives commands over a receive named "m4lc" so you can send and receive changes in other m4l devices.

2. M4LC Monome. You need one of these per monome device. It contains the serialosc connection and acts like a router, so you can have more than one app sending to one monome and switch to different apps with presets. Currently allows 4 different apps to send to different quadrants on the monome. (With live 9 you can now automate the preset changes in clips in session view! so monome configuration can change as you move down the set triggering clips or scenes!)

3. M4LC Clip Launcher Monome (use the version with nvb written after it for non vari bright). This is the actual clip launching app. It allows you to set a width and height for the clip grid, and then move around the session view by a track and scene offset. Also it doesn't contain any live objects at all! It receives information from M4LC Hub and converts it to the right information to light the leds, and then takes button presses from the monome and converts them to the right commands to send to M4LC Hub.

I've given you the full folders including all external files. So you need to keep the devices in the right folders, so they can see all the external files. Any devices with a "v1" or "v2" etc after have been Frozen, so don't use those versions if you want to edit and play with the patch.

j_kusel's icon

Wow Myr, this is all fantastic, thanks so much! Earlier this morning I tried playing_clip_index and fired_clip_index and I am now able to retrieve/process all state changes per track, and it's just a matter of getting those updates to translate to blinking feedback, which is proving difficult. (As a side-note, I was having MAJOR issues getting my poly~ objects to load/keep abstractions properly, which was weird, but in my impatience I just included 16 track-observing subpatches for now.)

My original plan was to update blinking by using two rect~ oscillators (one for fired, one for playing, both different frequencies) and then sending them to a jit.poke~ object to update individual pixels on my jitter matrix. I figured because at any given time you would have a maximum of one playing clip and one triggered clip per track, I gave each track two jit.poke~ objects. I soon found out the issues with this... I'm probably going to have to use coll objects (which I'm not very adept at yet) to store all fired/playing/dormant clips and blink them all together. Man this is hard.

I'm gonna have a look at your patches today and see if I magically become enlightened. Thank you SO MUCH for the help/resources!

Basvlk's icon

Thanks a lot for sharing Myr - that was very generous!
It also makes me feel good about some decisions I've made - similarly I read all the path Ids into a call when the device loads, and from then on I don't need to request any paths: I do it only for tracks and devices though: I love how complete yours is.

One question: there is a lot of talk about using 'local' (ie valid within the device only) variables when using M4L by using '---' in front of value names. ie using "---v m4lc-live_app-id" instead of "v m4lc-live_app-id"
is there a reason you have not used the "---" method?

Thanks again!

Johnny Christ's icon

re: the "---" thing, I'd like to hear some discussion about this too.

Am I right in thinking this setup incorporates a polyphonic performance / cache system? That is, more than one (external, controller) clipgrid can read from / independently scroll the cached Live clipgrid?

Myr's icon

Well you only need to use "---" or "#0" when you want the variable to be local to the device or patch it is in. I use local variables when needed, and global when not.

For instance in the M4LC Hub patch all of the IDs and Names I collect and store in the device are global, now that IDs are persistant you can use them in any m4l device. Once you've got one observer getting a list of track IDs you don't need another one. Just get it once in one master device, store it in a globally named value or coll object, and you can get the track IDs quickly in any other device without having to use the live api again, which can be slow.

But in M4LC Clip Launcher variables such as the number of tracks to have in the clip grid, or the track offset which controls where you are focused in session view, are locally named "v ---track-offset". So you can have more than one Clip Launcher device in a live set focused on different areas of the session view, with different size clip grids. And you don't have to waste time and power getting or observing ids you've already got.

Johnny Christ's icon

Okay great! That sounds precisely what I'm looking for, multiple cliplaunchers. :) Ta muchly!

@Myr - Could I PM you about a related matter maybe?

Myr's icon

@Johnny

yeah, no worries.

Johnny Christ's icon

@Myr

Cheers, vague, barely coherent PM sent. :)

jakeone's icon

Hi Myr.. and others. The M4LC Hub sounds like exactly what I'm looking for - I need something to observe everytime a clip is launched and to get its name, that is then to be sent down OSC for use in VDMX. However the Dropbox link has expired. Can you help?? Thanks Jake.

Michael Gary Dean's icon

If you have specific tracks that need to be observed, you can use the track property playing_slot_index. You could then put a device on every track, if needed. Once you have the playing slot index, you can use any of the clip properties etc.

Along with the index you get info about the playing status of clips:

First slot has index 0, -2 = track stop slot fired in session view, -1 = arranger recording with no session clip playing. [not in return/master tracks]

Here's the code:

Max Patch
Copy patch and select New From Clipboard in Max.