display_name (track)

fraction's icon

I want to get list of the track (name) of set, which you can access with "get" on live_set. But this property gives only the identifier (id), not the name

(in js)
var mytracks = new LiveAPI("live_set");
api.goto("live_set");
var t = mytracks.get("tracks");
post(t);

Is there a way to access display_name of tracks in Live other than going through observe audio_outputs / available_routing_types? i find a bit strange that you have to go so deep to get such a basic info, that could be accessible from live_set object.

idea?

11OLSEN's icon

You need this in js?

fraction's icon

yes. But either way, with max object, getting name seems to nee to go through observer / audio_outputs / available_routing_types

11OLSEN's icon

Max:

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

JS:

function bang()
{
    var mytracks = new LiveAPI("live_set");
    var track_ids = mytracks.get("tracks");
    post(track_ids + "\n");
    
    for (i=1; i <= track_ids.length/2; i++)
    {
        mytracks.id = track_ids[i*2-1];
        post(mytracks.get("name")+"\n");
    }
}
11OLSEN's icon

Oh wait, you wrote "display_name". I thought you meant the normal track names.

fraction's icon

no great, i mean i was using another path, but this is nice too, thx! display_name is like name i think.
Would you know how to keep this list updated if you delete or create a track?
i m trying with a callback function that i use for other property, but i can't get it work.

11OLSEN's icon

First no, display_name is what you see for example in the input routing dropdown of a track. In case someone wants to get them:

function bang()
{
    var mytracks = new LiveAPI("live_set");
    var track_ids = mytracks.get("tracks");
    post(track_ids + "\n");
    
    for (i=1; i <= track_ids.length/2; i++)
    {
        mytracks.id = track_ids[i*2-1];
        
        var dict = new Dict();
        d = mytracks.get("input_routing_channel");
        dict.parse(d);
        post(dict.get('input_routing_channel::display_name') + "\n");
    }
}


And here is a track name observer:

function bang()
{
    var test = new LiveAPI(callback, "live_set");
    test.property = "tracks";
    
    
    function callback(args) 
    {
    
        if (args[0] == "tracks")
        {
            post("tracks changed" +"\n");
            var mytracks = new LiveAPI();
            
            for (i=1; i <= (args.length-1)/2; i++)
            {
                mytracks.id = args[i*2];
                post(mytracks.get("name")+"\n");
            }
        }
    }
    
} 
fraction's icon

thx a lot! the difference between display_name and name wasn't clear to me.

And also thx for the observer :)))

Such help is really precious honestly. The forum where i use to come for usual max ressource is pretty poor in js, and even more for js/live.api while i find js is more appropriated to control live.

fraction's icon

hi 11olsen,

i cant get the display_name part working. I think it's the wrong path, and display_name doesnt exist in song/track.
I m saying this because my end purpose is to have a dynamic dict that containes current live track name, so i think it'd be easier to use an array that exists, from available_output_routing? isn't it?

This is working:

var mytracks = new LiveAPI("live_set");
mytracks.goto("live_set this_device canonical_parent");
var t = mytracks.get("available_output_routing_types");
var d=new Dict("mydict")
d.parse(t);
post("dict_elements",t);

It creates a dic with all the tracks but i have now another problem, to query the subkeys. This is not working, because it's a dic in a dic:
post(dict.get('available_output_routing_types::display_name') + "\n");

Would you mind to help? maybe it'd be easier to parse only by
{"display_name" : "1-audio", "2-audio"}

but I dont know how to do it. In max it's ok using route dictionnary + dict.unpack , but for some reason i want to achieve this in js. How would you do this?
thx!

11OLSEN's icon

I still don't understand why you think that available_output_routing_types or input_types can give you a complete tracklist of your Liveset. Depending on the tracks this list is incomplete and includes things like "Ext. Out" and "Sends Only" which are obviously no track names.

I m saying this because my end purpose is to have a dynamic dict that containes current live track name

So why not modify the track name observer example and update a dict in the callback method?

11OLSEN's icon
var dict_tracknames = new Dict("tracknames");


function bang()
{
    var test = new LiveAPI(callback, "live_set");
    test.property = "tracks";
    
    
    function callback(args) 
    {
    
        if (args[0] == "tracks")
        {
            //post("tracks changed" +"\n");
            dict_tracknames.clear();
            
            var mytracks = new LiveAPI();
            
            for (i=1; i <= (args.length-1)/2; i++)
            {
                mytracks.id = args[i*2];
                //post(mytracks.get("name")+"\n");
                dict_tracknames.append(mytracks.get("name"));
            }
        }
    }
    
}
fraction's icon

hi olsen,
i thought it was easier to deal with "available_output" as it comes out as an dic fomat in the lmo, being aware it's no the exact track list (anyways im going to apply some filter before on certain name).
I m stuggling to learn js, while i think i m quite easy with max to be honest. And each day tell me how to feel that gap :) -working through dic+js+lmo is still a bit high currently, but still need to move further
so many thanks for your help :)

11OLSEN's icon

I'm happy to help if you can clearly state what's your goal and what's the problem to reach it.
important docs: https://docs.cycling74.com/max8/vignettes/javascriptinmax
and https://docs.cycling74.com/max8/vignettes/live_object_model

11OLSEN's icon

being aware it's no the exact track list (anyways im going to apply some filter before on certain name)

OK but what will you do against the fact that audio track's available_output_routing_types doesn't include the midi tracks of a Liveset?

11OLSEN's icon

To answer your question regarding the subdicts:
The "available_output_routing_types" key returns an array of the subdicts. For example to print the display_name of the first subdict:

post("subdict1_display_name", d.get("available_output_routing_types")[0].get("display_name"));
fraction's icon

hi olsen,
thx so much for all of that. Yes i didnt need other tracks than audio. But it doesn't matter at the end if i can manage a dic as well from live_set + track property, which i wasn't really aware of it could give me a dic. I m going to need to filter by specific name probably using a regex function at some point.
My main ressource to really understand lmo with max objects, was the max.api device included in the ableton+the doc you mentioned, and i was trying to translated in js, and the closer property to what i needed was available_output_routing which gives as well track name somehow.

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

i m a bit tired to manage live api with max objects, but there's some kind of learning curve, as the documentation both for js and lmo is pretty limited in examples.

thx as well for the subdict; i need to try this to understand how that work in js.

this is super helpful really :)

11OLSEN's icon

To only insert audio track names to the dict you simply add:
if (mytracks.get("has_audio_input") == true) //check if it's an audio track
    dict_tracknames.append(mytracks.get("name"));

fraction's icon

thx - im going to use the track name property .

Struggling with regex() now. :)

i knoow why i wanted to use available_output_routing, it's because when track name change, it doesn't update the id (of course), so it doesnt update the dic - only if you add/delete a track.
i think with available_output_routing, if you change the name, you can update the array, at least with max object it works like that (i wrote you btw)