Dict property in Max for Live

Gene Pool's icon

Hi,

I want to programmatically change track routings. I want to be able to assign the input channel according to whether the name of the channel matches a string.

The LOM docs say I need to assign input_routing_type / input_routing_channel according to the values found in available_input_routing_types / available_input_routing_channels. So I figure the first step is to enumerate the channels available and find the one I want:

var api = new LiveAPI("live_set");
api.goto("live_set view highlighted_clip_slot canonical_parent");
var t = api.get("available_output_routing_types");
post(t);

This yields a dump like this:

js: {"available_output_routing_types": [{"identifier": 13, "display_name": "Ext. Out"}, {"identifier": 14, "display_name": "Master"}, {"identifier": 17, "display_name": "Sends Only"}]}

But I'm having a devil of a time trying to enumerate the variable t. t.getkeys() gives an error it's not a function and t["available_output_routing_types"] yields undefined. How can I enumerate the array of values contained in the first (and only) key of the property?

I'd like to enumerate, and then break when display_name equals the sought after channel, and then apply that to a track's input_routing_type.

Thanks!

broc's icon

I don't use JS, but have a Max patch that basically does what you want. It allows to change the input routing of the track where the patch/device is loaded. You may use it directly or as a model for translation to JS. (I would be interested to see the JS version for comparing)

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

Gene Pool's icon

Thanks for your help, Broc. I need to do it in Javascript to fit in with the other things I'm doing in Javascript.

I'm sure I'm missing something simple. I can't find any examples of people working with dict return values from the LOM, it doesn't work as the documentation suggests, nor does it work like a regular JS object would. I have seen examples of creating a dict in JS, but that is a problem further down the road.

broc's icon

I have just tested your JS example and can confirm that t contains a proper dictionary where t.getkeys() should work. So it looks like a bug and I would contact cycling support.

Gene Pool's icon

Awesome! And you get the same error that the function getkeys is not defined?

broc's icon

Yes.

tyler mazaika's icon

I agree its a pain/confusing to work with returned dictionaries like this. But you can actually use JSON.parse() on the LiveAPI query response to get an iterable JS object.

Cheers,
Tyler

function bang() {
    var api = new LiveAPI( null, "live_set" )
    api.goto("live_set view highlighted_clip_slot canonical_parent")
    var t = api.get("available_output_routing_types");
    var s = JSON.parse(t)
    for (var i = 0; i < s["available_output_routing_types"].length; i++) {
        var d = s["available_output_routing_types"][i]
        post( d["identifier"], d["display_name"], "\n" )
    }
}

------------------------------------------------------------------

And actually... digging through a morass of old code I had before figuring out the JSON approach, here's something that works ok using the Dict object style. JSON seems much easier.

function bang() {

    var api = new LiveAPI( null, "live_set" )
    api.goto("live_set view highlighted_clip_slot canonical_parent")
    var routings = m4l_get_dictionary_value_for_property( api, "available_input_routing_types" )
    for (var i = 0; i < routings.getsize("available_input_routing_types"); i++) {
        var found_name = routings.get("available_input_routing_types["+i+"]::display_name")
        post(found_name,"\n")
    }
}

function m4l_get_dictionary_value_for_property( api_object, property_name ) {
    var return_dict = new Dict()
    return_dict.setparse("response", api_object.get(property_name)[0])
    return return_dict.get("response")
}

Gene Pool's icon

Brilliant, thank you Tyler!

fraction's icon

hi @Tyler

i d like to duplicate in js the observer function to apply to the code above, in order to keep an update list of the track in the project (display_name)

Similar for tempo where i use a callback function :

///

var tempo = new LiveAPI(callback,"live_set");
tempo.property = "tempo"
post("tempo.property is", tempo.property, "\n")

function callback(args) {
post("callback called with arguments:", args, "\n")}

///

I was thinking to use your code:

///

var mytrack = new LiveAPI(callback,"live_set" )
    mytrack.goto("live_set view highlighted_clip_slot canonical_parent")
    var t = mytrack.get("available_output_routing_types");
    var s = JSON.parse(t)
    for (var i = 0; i <s["available_output_routing_types"].length; i++) {
        var d = s["available_output_routing_types"][i]
        post( d["identifier"], d["display_name"], "\n" )
    }

function callback(args)
    { post("callback called with arguments:", args, "\n")}

}

///
but doesnt seem to work.
Would u mind to give an hand?

tyler mazaika's icon

Theres no limit to the number of ways something could “not work”.

Start a new thread and include what errors are logged in console and what behaviors you think should be happening that aren’t. Then other folks can probably chip in their thoughts, too.

Toussain's icon

Just here to say that this thread saved me from a nightmare. Thank you all !

Simon East's icon

This also saved me a lot of time. Why on earth is it not properly documented that the API is returning JSON strings not native JS dictionaries as the docs imply!