live.remote~ not working in bpatcher
The M4L patch I'm making has several files and scripts, so I won't upload the files and patch unless necessary. I'll try to explain how it works and what exactly is NOT working.
I'm watching the path "live_set view selected_parameter" with a [live.path] so when the user selects a parameter, the id goes out the middle outlet -> [deferlow] -> a JS script. There's some logic between the deferlow and the JS to make sure that the ID only gets to the JS script if the user wants it to, but that works just fine. In the JS script, I make a new bpatcher with the following code (this is in a function that takes the ID as an argument):var temp = new LiveAPI('id ' + id);
As you can see, I make a new bpatcher in my M4L patch that loads an abstraction based on the ID from the [live.path]. In this abstraction, it sends the ID to a subpatch that loads the ID into a [live.remote~], [live.object], and [live.observer] (I originally tried to use the [M4L.api.DeviceParameterRemote] abstraction but when that wasn't working I decided to make my own). Both the [live.object] and [live.observer] work perfectly; I can set values with the object, see changes with the observer, etc... Seems like it works fine. However, it quickly becomes clear that the [live.remote~] is not working, since the parameter remains active in Ableton and any values sent to the [live.remote~] makes no change to the parameter either. I've confirmed that the ID gets sent to the [live.remote~] (seemingly correctly), since the id gets sent to all the other live.* things in the same exact way and they work.
var newMapping = this.patcher.newobject('bpatcher', 5, 5, 130, 159, 0, 0,
'@name', 'Mapping', // Name of my bpatcher abstraction file
'@args', id, temp.get('is_quantized'), temp.get('name'));
Based on this, I suppose I could just stick with the [M4L.api.DeviceParameter] abstraction and call it a day and not even touch [live.remote~]. However, I'd really like to be able to use [live.remote~] so that value changes don't mess with undo steps and the device/automation gets disabled. Also, I want to understand what's going wrong so I don't make the same mistake in the future. Is there some weird quirk to [live.remote~] that I don't understand? Side note: it doesn't seem to work either inside or outside edit mode, and there are no error messages being generated.
Sorry for this wall of text, I'm just super stumped on this one. Maybe it's a [deferlow] issue that I don't fully understand either?
Hi Chris, I haven’t tried with [live.remote~] yet, but my experience with dynamically created sub patchers with [live.*] objects is they don’t always work the same. For instance I recall when instantiating a [live.observer] with a property name in the object (rather than pass that message later) the object never worked, and just seemed inert in the way you describe. But that only happened if the bpatcher was instantiated after the device was loaded.
In short: you may be doing everything right and its just a bug, but hopefully there’s a workaround of some sort.
Cheers,
Tyler
Hey Tyler,
Thanks for the response. I did a bunch of testing and it does seem to be an issue with dynamically creating the bpatchers. I made a few different versions of test patches. The only time it seemed to not be working was after loading the bpatcher by a script. If I make a bpatcher using a script message -> [thispatcher], then no matter what I do, the [live.remote~] does nothing. I've tried passing the ID in as args (what I was originally doing), manually sending the ID into the bpatcher via an inlet after it's instantiated, and instantiating the bpatcher then opening a "New View" of it and sending an ID message directly into the [live.remote~]. None of that works. Sorta at a loss here, I have no idea whats going on. If it is just a bug as you say, then it's incredibly inconvenient because the patch I'm making depends on the ability to dynamically create these bpatchers. Anyone have any workarounds? Hopefully one of those bugfixing wizards sees this and can patch it if it is indeed a bug.
One inelegant, but not-that-difficult workaround comes to mind: have a large bank of live.remote~ objects sitting outside your bpatchers and script connections from the bpatcher outlets to those objects. You'd still get most of the benefit (smaller load time and file size etc.) of the dynamically-created bpatchers, even if you have a bunch of live.remote~ objects that aren't being used (id 0) at any given time.
Yeah I was thinking about doing that but still want to have the ability to make infinite mappings... Turns out the issue is a lot more simple (and a lot worse) than I originally thought. A [live.remote~] created by a script simply doesn't work. Here's a very simple way to demonstrate this:
1. Make a [live.path] watching "path live_set view selected_parameter"
2. Click a few parameters to allocate some IDs
3. Send a "script newdefault var1 10 100 live.remote~" message into a [thispatcher]
4. With one of the IDs that you allocated (such as "id 1"), send an ID message into the new [live.remote~] right inlet
5. Nothing happens. Sending values into it doesn't do anything either
EDIT: I made a pretty simple patch that demonstrates this. Load this patch into Ableton and make sure the ID 1 is set to some DeviceParameter (or just change the "id 1" message to something that would work). You'll notice that the parameter remains active and if you edit the patch to send values into the generated [live.remote~], nothing happens.
I found this post from 2014 that describes the same problem. I guess it's safe to say this isn't getting fixed any time soon... https://cycling74.com/forums/make-dynamic-amount-of-map-buttons-in-bpatchers-with-javascript-wont-map
Thanks for that follow up, Chris! And I agree with your (unfortunate) assessment.
I am running into the same issue: dynamically creating bpatcher objects including live.remote objects won't link with Live's parameters. If anyone has found some way to make it work I'm all ears!
Hi there. It is now 4 years since the last post in this thread and, as far as I know, this issue is still not solved. I tried Tyler's solution: live.remote~ objects outside the bpatchers with scripted connections from the bpatcher outlets to those objects. Parameters are addressed after targeting them with a Mapbutton, but I can't send any data there. No doubt there will be more users by now that have dealt with this problem. I would be happy to hear their experiences and possible solutions.
Yeah, this issue is really frustrating. My M4L solution would be drastically simpler for my end users if live.remote~ objects could be created dynamically. Instead, I have been forced into weird design decisions that require my end users to add a bunch of M4L devices they would otherwise not need to add.
Yes, I am aware I can create a bank of live.remote~ objects, but I ran into feasibility issues after load testing that. In other words, my M4L solution would require adding too many live.remote~ objects, which stresses the CPU unnecessarily. If I could instead dynamically add the live.remote~ objects I need when I need them, then I would not need nearly as many.
On that note and on the other hand, there is a weird silver lining to this issue; that is, my end users are forced to add M4L devices in Live device chains, which spreads the CPU load across cores. If, as in the alternative, all the live.remote~ objects are in one M4L device, then there is no such CPU load distribution. But, that silver lining is tempered by me wondering why live.remote~ objects require so much CPU to begin with. I mean, maybe that is just the way it is (given Max tapping into Ableton's API probably requires some overhead).
@JBONE1313. Yeah, that was an impressive /rant ;-)
But hey, the thing we should not forget, is that the implementation of Max in Ableton makes an incredible creative platform. I've done things that I could never have dreamed of...
Back to the issue, now. The reason why I started looking into dynamically loading bpatchers was not so much CPU loads, but internal (not MIDI or key) mapping issues. In my main performance device, the load time of 208 instances of live.remotes~ (necessary for the mapbuttons) is horrendous. We're talking several minutes. So everything looks as if m4l offers the possibility of dynamically creating them, it is just that it does not, in fact. It is difficult to determine the cause; whether the responsibility lies with Cycling or with Ableton. But I am in dear need of a strategy for this, my spiritual and material livelihoods are at stake.
the thing we should not forget, is that the implementation of Max in Ableton makes an incredible creative platform.
Completely agree. I reserve the right to complain though. :)
my spiritual livelihoods are at stake.
I know the feeling. After decades of frustration, I have learned to get my spiritual needs met elsewhere, i.e., not from artistic pursuits. Back on topic...
In my main performance device, the load time of 208 instances of live.remotes~ (necessary for the mapbuttons) is horrendous. We're talking several minutes.
That does not seem right. I can load thousands of live.remote~ objects in relatively short time. Consider playing around with my example in this thread to see if you can narrow down your issue. Based on my testing, I would think 208 live.remote~ objects would not be a problem. I have load tested my solution, and it performs fine for AT LEAST 800 live.remote~ objects (spread across devices). Moreover, once they are instantiated and initialized, reloading the set is quite snappy.
So everything looks as if m4l offers the possibility of dynamically creating them, it is just that it does not, in fact.
Yeah, I have not found any way to dynamically create live.remote~ objects.
There is also this thread, in which Tyler Mazaika is suggesting using dict to keep track of the ID's. Haven't tried that yet.
@JBBOLLEN
1) I would not say the dict model as a way to persist values inside dynamic bpatchers is relevant to weather live.remote~ works in those bpatchers. You'll need to keep the live.remotes~ outside of them, anyway.
2) I agree with JBONE1313 in that having a bunch of live.remote~ on their own should not be a huge CPU hit, nor should they impose a "slow-loading" penalty. I've got some lightweight devices that have like 8- or 100 in them and they load very fast. Very roughly, in my experience bpatcher loadtime scales more-or-less linearly based on the total number of max objects in the patches.
* If you have ways to refactor common code logic this can help a bunch with load time.
* Often times writing UI-configuration code in .js files can save you tons of max object in a patch
Thanks, Tyler. I'm not giving up. In the coming weeks, I will dedicate some time to thorough testing. I will report.