Two problems: getting a subset of a string and can't close panels window


    Jul 31 2022 | 9:59 pm
    Hi, looking for showing the playhead position in minutes and seconds outside Live (Android tablet + TouchOSC) I found the Time Display 1.0 object that is perfect... almost. The format it shows is: hhh:mm:ss:msmsms and I would like to strip away the hours - first three characters and the ":" , and the milliseconds, last three and the [:] before, so I opened the device in Max editor and in the end I managed to open the "soubroutine" called "Time" in which I tried to add a regexp filtering like this: "regexp .*[:](.*) with no luck: any help?
    In the Time patcher I added an udpsend to broadcast the time through OSC. The sending works and I can get the time into my TouchOSC layout but I'd like to strip away the outer characters. I would also like not to send OSC data continuosly but only when the last message is different then the previous one.
    Another thing is that when I try to open the "Time" patcher window with "Original" nothing happens and I have to use the "New window" instead. Now I have a few small windows floating around and I don't know how to turn them off.
    I watched many videos and read many papers and downloaded a lot of examples or snippets but I couldn't find a solution that works.
    Any good link about M4L programming and tutorials? Thanks. fabio

    • Aug 01 2022 | 12:44 pm
      upload the patch, otherwise one can't understand what that original or new floating windows are... it should be possibe to output time without hours and ms in first place, without a need for regexp. than add zl change to send only when seconds progress. ------ otherwise try this
      regexp outputs only numeric items, we route items 2 & 3 from the HH:MM:SS.MS list to sprintf to form MM:SS messages. If that timer patch is programmed correctly, there should be no need for zl.change, but I would not expect it to be the case. P.S. if I remember correctly , Live is not capable to report real time correctly, if there are any tempo changes involved.
    • Aug 01 2022 | 3:49 pm
      Thank you for taking the time to reply to my post and try to help me.
      Before I go on to other things, let me share the patch so you see what is like.
      Now let me ask a little question on a thing that's bugging me a little, please.
      Yesterday, every time I wanted to edit the popup window I had to choose "new window" because "original" was not available or it didn't work. Now, when Max is opened I'm left with all the popups, and I can't see how I can get rid of them: any help on this too, please?
      @source audio About the way to get only h:mm:ss I tried your suggestion but it didn't work. After a few trial and error, and a lot of frustration with Max documentation - both the help and the reference show quite a few things but explain very little and there is almost no CLEAR examples of how to setup a function to work, I managed to make it work almost perfectly. Here is how I did it, taking into account that I needed to send all the values as a single string, in order for a label into a TouchOSC to show the time correctly.
      Here is the working snippet (with some "probes" to see what's gettin along the signal path):
      And here's the TouchOSC lay out (sorry for the quality of the picture...) output:
      Now I would like to format minutes and seconds so that they always show two digit values: where should I look?
      And what if I would like to filter the millisecond to show only values at half a second (.0 or .5)?
      Thank you very much. fabio
    • Aug 02 2022 | 7:24 am
      1- you did not use sprintf as on the screenshot. 2- you stated you only want mm:ss ? 3 - you messed with the patcher and added it again to parent patch, and have now duplicates of it.
      Best would be to trash that device and start from scratch. simpler way to get real time is get_current_song_time or plugsync~ and translate ticks to HH:MM:SS then regexp and sprintf or use ms and do the math using plain max objects. Did I understand that correctly - you wrote you want ms to dislay as .0 or .5 that is what it would look like: 02:33.0 02:33.5 02:34.0 02:34.5 etc
      you don't need to display anything in Live, only send time to OSC. Can be all done with only few objects.
    • Aug 02 2022 | 8:12 am
      here one example using plugsync~
    • Aug 02 2022 | 11:10 am
      1- you did not use sprintf as on the screenshot.
      I gave your hint another look and of course it works. What was putting me off was that you wrote " we route items 2 & 3 ..." so I thought that the box where I saw "$2 $3" had to be a "route" instead of a standard message, even if I couldn't see the "route" word in your screen. But I thought that that didn't mean to be sintatically 100% respondent to the real objects. In fact, in the "zl change" box I can't see the dot between the two words but I learned that it is needed in the real one.
      2- you stated you only want mm:ss ?
      Yes, but along the way I thought that it would be better to show a single hour field too, just in case I would have to work with videos. I modified your patch consequently.
      3 - you messed with the patcher and added it again to parent patch, and have now duplicates of it.
      Here you are right again. In my frustration of not being able to open the popup window in edit mode, I tried things without knowing what I was doing... Now, how do I delete that tab in the parent window?
      Did I understand that correctly - you wrote you want ms to dislay as .0 or .5 that is what it would look like: 02:33.0 02:33.5 02:34.0 02:34.5 etc
      Yes, you got it right. It's a minor thing but I think that on the tablet layout it would feel better seeing that the time changes more frequently than once a second but not as fast as once every tenth of a second. Think of it as a sort of a "blinking led" telling you that te transport in running. To do it easily I would need a sort of a "round for defect" function where I can define 0.5 as the weight of the rounding process...
      you don't need to display anything in Live, only send time to OSC. Can be all done with only few objects. ... here one example using plugsync~
      Thank you very much, that's much simpler. I made a little adaptation to show the single hour digit and gere it is:
      Thank you again and have a nice day. fabio
    • Aug 02 2022 | 11:31 am
      glad it worked for you, and that you got rid of that complicated device.
      just a little hint : sprintf needs %02d etc only to add leading zeros, for single digit %d or %i is ok. and if you leave space between HH: and MM you get quotas at output
      sprintf symout %d:%02d:%02d.%d would produce
      if you prefer to have separation arround : then comment would be better as it ignores quotas
      touchOSC also ignores them, at least the old version
    • Aug 02 2022 | 5:11 pm
      Thank you very much again for your explanation. That is gold for my attitude: "while you are at something, try to learn something general and not just how to solve your little need of the moment".
      Going back to the OSC sending to TouchOSC (Mk1), to do it in Live I'm using the Live connection kit Max device "OSC Send" or the "Live Grabber sender", but with both I can't map directly to them the tracks ARM buttons. Searching around I found an M4L device called "Arm 8 tracks" that let me map the track ARM buttons to its buttons, which are mappable to the OSC senders. Now that I learned how to send to OSC directly from within a patch, I'm trying to mod the Arm 8 tracks putting directly into it's patch the sending functions via OSC. Here it is, with my modding in blu background.
      I have some questions, though. The string I need to send should have this format: OSC address | arm status (0/1) In my mod it should be in a form like this: /ViviARM 1 (when armed) and this: /ViviARM 0 (when unarmed) For now I've "hard coded" them in the patcher but If it's not too time consuming to learn, I'd like to be able to get the address from a global list stored somewhere, or better a table or a db where each record have at least 3 fields: track number, track name, OSC address. In that way I should be able to get the track number and/or the OSC address knowing its track name (or even better, selecting it from a list), with some sort of a look up. In that way I would be sure to use the same track info across all the patches. Now the questions:
      1 Where do you think I can I get the track number in that patch? And how? As you can see, on the first track I "probed" some outlets to see what and when I am receiving and I see that in the leftmost "probe", the last piece of info it is the track number minus 1 (the list starts from 0). Can you think of a way to get the track name?
      2 Do you think it is better to use a single udpsend box as I did ( in fact, I used two of them) instead of having one for each button? 3 Performancewise it seems to me that clicking on one of the buttons of the patcher, both in Max editor and in Live object, I get a faster feedback on TouchOSC than when I click directly on the arm button of a track: in the code, do you see any room for improvement on this?
      4 Do you have an Idea on how to build that "global db" of tracks info and values?
      Thank you. fabio
    • Aug 02 2022 | 9:44 pm
      I realized that I would need to be able to set an offset in seconds to compensate the gap between the projet start time (1.1.1) and the song start time (usually 12 seconds from 1.1.1.). We need to subtract the offset time before the number gets unpacked and, if I understood correctly the top part of your patch, we have 640 tick per second : am I right ?
      I thought that I should at first convert the offset seconds into ticks (offset seconds x 640) and then subtract the resulting ticks from the number before the translation into four pieces, so I thought to use an expression box like this: "expr $f1 - 640 * Sf2" where $f1 is the time in ticks and Sf2 is the offset time, in seconds. Trouble is that, as you can see in the patch, if I use the $f2 operator the box doesn't evaluate the expression but if I put the seconds number directly into the expr box like this: "expr Sf1 - 640 * 12", it gets evaluated! I would like to understand why it works like that because I will need to "present" the offset field into Live so I need the $f2 version to works. A useful thing would be to be able to programmatically get the time value of a locator named "Start", as I always have one at the exact beginning of the song. In that way I could use the Start time to set the offset device even if I move the locator around.
      Thank you. PS. I'm really puzzled about the behaviour of the expr box... I'm curious to see what I'm doing wrong...
    • Aug 03 2022 | 9:57 am
      I don't use Live, find it a crap and have no interest at all in it. Only reason I ever come in touch with it is to help some students and customers. For that reason I am wrong person to ask about armed tracks and the rest of it. But once asked, I would say try to use only 1 Live device, like that time display device and also use it to control arm state of that 8 tracks. Make your life easier and place that 8 tracks to track slots 1 - 8 so you don't need to detect anything but talk plain text to tracks and touchOSC. I have this idea that live set is static set for stage use or ? issuing track names and get/set their armed state should be easy thing to do in a single device in case you insist on using names and placing tracks in any order, but then have fun with it.... but you need a good strategy - is TouchOSC in control of armed states ? is song auto-arming the tracks in first place ?
      single udpsend is a better choice, one can also control order and flow, speed etc of sent messages. I see you used 192.168.0.255 - trying to broadcast ? instead of 192.168.0.99 ? sometimes, broadcasting has speed issues sorry I got this with IP wrong, a mistake - was a part of some other patch ------ To the offset : plugsync~ outputs raw ticks in relation 1. = 480 ticks or 1 quarter note. I don't know what that 640 you mention represents. To be able to programm offset, you will need time signature translated to ticks & multiplied by number of bars to offset. than insert (- that much) in ticks flow. Live has it with bars : beats : units and not real time, so I guess your offset is in bars. plugsync has time signature outlet as list, unpack and you multiply number of beats with beat (expr 1. / $f1 * 4) let's say TS is 7/8, 1/ 8 = 0.5 raw ticks (1. / 8 * 4) 7 * 0.5 = 3.5 = bar length in raw ticks. if you want to offset 6 bars then multiply 3.5 * 6 = 21. insert - 21. in rawticks output before * 480.
      All clear ? --------- But if you want real time offset, like 12 seconds, then you need to translate 12000 ms to ticks in tempo xy let's take tempo 110. 60000 / 110 = 545.4545454545 = 1 quarter note length in ms now 12000 / 545.4545454545 = 20 which is your offset in Live's representation of raw ticks. here a little presentation of both offset types
    • Aug 03 2022 | 12:22 pm
      P.S. I forgot to answer about "Start" locator.
      It is possible to extract it's position, which is expressed in elapsed quarter notes. in bar 6/8 and locator placed at bar 11, it will mean 3 * 10 = 30 quarter notes It makes me wonder why you use realtime, and not bars and beats, which seem to be the only Live native time measuring units ...
      here is your "Start" locator detector
    • Aug 03 2022 | 7:16 pm
      Hi, ant thank you again for the time you are spending in helping me to solve my little problems and, above all, to learn new things.
      but you need a good strategy - is TouchOSC in control of armed states ? is song auto-arming the tracks in first place ?
      No, there is no auto-arming. I'm just building a remote control for the most common needs while tracking.
      Yes, in my TouchOSC layout I can control the ARM states sending a midi cc message to Live where in a Clyphx User settings file I put the scripts and they are triggered by the midi cc message coming in. Some scripts are as simple as "track/Mute" or "track/ARM" but you can get a very good control of the most part of Live objects. Unfortunately Live "per se" doesn't give a lot of feedback directly and that is where OSC is unvaluable. Without that I couldn't get the state af the Mute or Arm buttons so I had to always check the PC window to be sure things were as expected and so I had to use two buttons for each function: "Mute on" and "Mute off", "Arm on" and "Arm off". But that was far from ideal so, thanks to OSC and to Max that let us use it within Live.
      About track names vs track numbers I'm relying heavily on track names because Clyphx let you use them as target of a few commands without being tied to the track position and without having to remember the position number. But as my tracks are always in the same positions inside the patchers I can easily use the numbers. I must search how are numbered the return tracks though... About the offset
      ............ if you want to offset 6 bars then multiply 3.5 * 6 = 21. insert - 21. in rawticks output before * 480. All clear ?
      Well, not really but I was considering that I could go with the offset indication made of beats or bars instead of realtime because my "Start" locator sits always on a line between bars or beats so I could use those values to define it. In any case, thanks to your new Time-OSC with automatic offset calculation I won't need to manually set a value for that. So let me thank you very much again for that little gem. I will keep it like it is.
      It makes me wonder why you use realtime, and not bars and beats, which seem to be the only Live native time measuring units ...
      I need to show the playhead/cursor position in realtime because who sings, usually could have put on the lyrics some comments and some marks with the running time indication because they were listening with a player that gave only runtime values.
      So, in these last few days, mainly for your help and your work I made giant steps on the path of building my remote control. Should you ever come to northern Italy send me a message and I'll be glad to take you to some nice place (my wife is from Bellagio... The real one, not the fake Vegas one...). There is still one thing for what I couldn'f find a solutionand not even any info: - getting the state of the global recording or of the recording button Now when I hit the "rec" button on my layout I have to check the tiny button on the PC window to be sure that recording in ON. After hours of serching I'm still left with empty hands...
      Thank you. fabio
    • Aug 03 2022 | 7:29 pm
      For the feedback of muting and arming through OSC, I ended up modding the "Arm 8 tracks" patch. Here is the one for the muting of the first 16 tracks:
      And this is for arming 8 tracks:
      For now I kept them as they were, with the interactive buttons, even if I'm not using them. I will think if it's better to remove everything but what is needed to send the status via OSC. Maybe I will make that version too.
      Now I need to understand how to apply the same functions to the return tracks...
      Thx. fabio
    • Aug 04 2022 | 12:36 am
      There is still one thing for what I couldn'f find a solutionand not even any info: - getting the state of the global recording or of the recording button
      After some further research I managed to get the status of the global recording. In fact it's as easy as reading a property of the live_set class.
      Sorry for the (un)quality...
      Thank you again. fabio
    • Aug 04 2022 | 3:35 pm
      that looks more complicated than I thought. That arm and mute devices you posted have no idea what track names are. track has slot number which is human visible by looking at the track activator number. Track id has nothing to do with that. If you want to report arm state of the track named Guitar, you need it's id which will remain same if you move the track to different slot. So what is your link between track name and it's slot number and report of the arm or mute state ? I don't see it. In order to do something like that, one has to build a list of track names and their id's and to monitor them for any changes, and keep their states linked to what ? what I am trying to say, either one builds remote control which is completely flexible, which means it reflects complete Live set state, or one uses fixed setup with set tracks, devices etc and programs static efficient control. I am not sure to understand exactly what your concept is. If you send arm and mute state of first 16 tracks to touchosc, that will allways be related to track numbers, not names. Here one option would be to check states of 16 tracks every time that Clyphx executes any script. like this
      and here linking track names & ids
      ----- you can use return_tracks instead of tracks to get their ids, states etc.
    • Aug 04 2022 | 5:38 pm
      one builds remote control which is completely flexible,
      That is the primary goal but to do that one must have a good knowledge of how to do it. A few days ago I knew almost nothing about how to do it and it's only thanks to your patient help that I'm starting to understand something.
      If you want to report arm state of the track named Guitar, you need it's id which will remain same if you move the track to different slot.
      Time ago I decided in favour of a static template with the same tracks in the same positions to get a link between names and numbers. But sometimes I found it useful to be free to add or remove a track - even only temporarily, and that would break the link between name and number from that track on to the right of the set. Now, as you say that the ID stays the same even if you move the track and I don't know nothing about how ID assignement work, let me ask you a couple of questions, please. Should I add a new audio track in position 5 and rename it to "Guitar", it will be given a certain ID: 1 - If I delete the track, save and close Live, reopen it and create the same track in the same position, will it get the same ID as before? 2 - And what if I create it in a different position but with the same name? The answers to these two questions are key for the route I will decide to follow for the further development of my remote so forgive me if for now I send my reply even if it doesn't cover the rest of your post. Thank you. fabio
      PS. Just this:
      you can use return_tracks instead of tracks to get their ids, states etc.
      OK: inside the children "return_tracks", are they enumerated with numbers or letters? Thank you.
    • Aug 05 2022 | 9:55 am
      every track & return_track gets new id when created, current highest id +1 all track types share same id number list , also the master track. if you had set with ONLY 5 tracks, delete 3 of them and add 3 again no matter what name they get, you will have new increased ids for that new tracks.
      instead of (theoretical) 1 2 3 4 5 you now have 1 2 6 7 8 Like in poker. ids of return tracks are numeric, same as normal tracks, even that they show alphabet chars A B C etc, and can't get reordered, but if you insert new return track by right click on a return track, it's letter will get "stolen" from new return track and all next return tracks including "victim" will get shifted in alphabet... ----- if you start default set with 4 tracks and 2 returns. you have ids 2 3 4 5 assigned to tracks, 6 7 to return tracks 8 for master at least that is what Live 11 does on my test system. Now it comes even worse - if you add a track it will get id 9, delete it and create another with any name - id 10, then add a return track it will become id 11. The worst thing is - there is no way to reassign ids. well ... there is, but it involves uncompressing the als file, editing it (it is xml format) save it and add .als extension. Live will open it even that it is not recompressed. If you create and delete a track repeatedly, the highest id number will continue to increase. After saving the Set it remains so as long as Set is open. On next open of the Set current highest existing id is used to create new tracks. Sounds complicated ? here an exampe : you start default set with that 1 midi 2 midi 3 audio 4 audio A Reverb B Delay Master I don't need any midi - remove them ids 2 & 3 dissapeared forever ! also take that rev and delay out. now we are left with 2 audio tracks and their ids are 3 & 4. Add audio track , delete it, add again, now 3rd audio track has id ??? you would say 5, but NO it is 10 because initial set had 7 ids, 4 tracks 2 returns and master, starting with id 2. on first track addition it got id 9 - we deleted it , added another track it got id 10. Can you follow that ? that id is linked to that track as long as it exists in that Set, no matter if you rename or move it to different track slot. But ... if one saved Set when it had only 2 audio tracks with ids 3 & 4, close the set and reopen it, new 3rd track would get id one number higher than master track assigned. ---------- Save Set without reopening it does not reset current highest assigned id. That has to do with undo functions . ------- This are decisions made by ableton from the very beginning and I guess will not change ever, no matter how inconvenient they are, same as unability to report real time no matter what time or tempo changes in song are contained etc. I had to laugh seeing post few days ago from someone from Ableton developer team asking "how can we make Live better ?" There is looong list of requests from users since many years, dealing with basic functions, which are a must in any serious DAW, which remain unanswered... ........................ If you don't want to play this poker game with track slots, names ids etc, your best bet is to create static sets and program custom control for them. If you allwas have tracks named like guitar, or piano and so on keep tham allways in same track slot, and take care to add them in proper order, because that matters when tracks get ids assigned. But wait --- Live is NOT capable of creating empty set without any tracks, so that one can start in proper order !?!?!? And they ask how to make Live better ? -------- Enough jokes, what would you do ? To remain flexible, also in terms of display on touchOSC screen, you need to scan and report any track and their state changes, at least. And that has to be based on ids. So how do you report arm state of added track named Kalimba at some point ? Does touchOSC have defined number of comments, or buttons which get renamed when track in track slot number changes ? And if track Guitar which was in slot 5 is armed, and you move it to track slot 6, you have to report both slots to touchOSC, or even ALL slots. Will add a lot of OSC messages.
    • Aug 05 2022 | 10:03 am
      P.S. here is a simple device that let's you follow track names and ids when they get created, deleted or reseated into diffeent track slot. select track name in the menu to check it's id.
      you can drop it into any track, midi, audio or master In case you want to make that flexible control, you will need some parts of it ...
    • Aug 05 2022 | 5:09 pm
      Thank you again. I'm having a look at your TR-ID-SHOW device to understand how thing goes and if you don't mind I'll check with you step by step.
      1 - First of all let's clear (for me) that when we deal with tracks (children of live_set) we are dealing with a list. The LOM shows this as the way to get to a given track in the list: Canonical path: live_set tracks N
      2 - Although I couldn't find an explanation of what that N stands for, looking at the code I dealt with, I assumed that the items in the list are enumerated by the number of their position in the set, from left to right, minus 1 (0 = based counting). And understanding that, instantly made it clear for me why you are stressing so much the point of setting the tracks in fix positions: being track numbers linked directly to track position, if you change the position, the link with a hard coded number will break.
      Is all that correct, so far? 3 - On the other hand, in the code, to refer to a given track you have to give the ID that Live assigned to the track when this was created. ID numbers (or addresses) are just coding handles and unfortunately their values are not predictable as they change when you delete and recreate a track, even in the same position, so there is not an usable link between track number (position-1) and track ID. But to get a track ID you have to know the track number...
      4 - So, lets enter track names. I think that the first thing that everybody does when building a Live set is to assign meaninful names to tracks. And maybe, between different sets the most of the tracks have the same names - at least for me is like that: drums, guitar, voice, etc. That said, I think that the easiest way for a user to select a track, wheter to perform actions on that or to get feedback from it, it is to use its name. And that becomes a must when having to do it away from the PC and the mouse,. Luckily Live makes the name of a track, as it is shown on its header, available to the programming environment as a property of the track. Unfortunately, to get the name of a track you need its ID and to get its ID you need its number: not ideal for flexibility... In the end, I think that the only way to be free from the fixed positioning of the tracks is to build a table with at least three columns: track number; track ID and track name; and then create a sort of an Excel vlookup, maybe also making it a reusable patch, with name as input and ID and number as two different outputs.
      I think this is not too far away from what you have done in your patch - building linked names and IDs lists into the umenus, but with my near null knowledge I can't see how to create a table and even less how to lookup into it with the name, to get back the ID and/or the number. I don't even know if this is possible...
      Hope all this makes sense.
      Thank you. f.
    • Aug 05 2022 | 11:46 pm
      Thanks to your work, maybe we don't need no table and no looking up... After I managed to understand a little better how it works, I imported your code into my "Arm 8 tracks" to make some testing and I noticed that when you select an item in the list of a umenu, the left output sends out the position of the item in the list (zero based) and that, for the way the list is built, it is directly the track number we need to send to the trigger of our actions. So we can send the track number obtained to a [path live_set_tracks $1] message to get the ID of the track for the rest of the code, to apply actions or to get properties values. I also saw thet you can use the umenu as a toggle but after a little test I reverted to the standard behaviour, for now. Another useful thing I saw is that after copying the umenu box several times, each copy works independently from the others. For now I haven't managed to make the umenu load and present the preset items. The umenus show the first item even if they act on the previously selected track. I didn't aligned the wires for now because in the mess I think that they are more easily followed like that.
      Thank you. f.
    • Aug 06 2022 | 5:57 am
      I am out for most of the day, so just a short reply, building that table with track names, positions and ids is no problem a all, but it is more of an information to look at then really a need. Only problem I see is that issuing names for ALL tracks is not an easy thing, at least not the way I understand it, because one would need to place a device in each track to auto detect if it was renamed etc. Otherwise one needs to rescan a central device from time to time to keep up to date. you ask live.object or observer to report track by it's number which includes id in first place, which is then used to get name and all other informations like arm, mute etc states. A list with 16 ids can be used to scan 16 track for arm state, like in previous example I posted, but that has to be executed either by specific interval using metro, or by reading input of control from touchosc, when one expects that something changes in the set.
    • Aug 06 2022 | 6:54 am
      Forgot to answer that your explanations of tracks, ids etc are all correct, I am sure you are making it through the LOM jungle, in first place by creating own devices and test patches. Another thought - if you have a table which keeps current track names and their ids you can issue track id by calling it from touchosc, for example /guitar/arm 1 that string split into guitar - selects it from table by name to get it‘s id then pack id with arm 1 message to arm it That could avoid a need for that extra midi to clyphx or whatever it is named scripter
    • Aug 06 2022 | 8:16 am
      I am sure you are making it through the LOM jungle
      I know who to thank for that... So, thank you again for your patience, your attitude and your time.
      Even if you'll be notified that I replied to this tread, please ignore for as long as you'll be confortable to reply in the next days or whenever. No hurry. Enjoy your time. I should do the same today as this evening should rain, hopefully. Northern Italy have never seen such a hot and dry period for a couple of centuries.
      Have a nice day.
      fabio.