Help: detect son member inside group that is other group (for clone)

Hi, how are you?

I have created a new function for clone a group with only tracks inside (respecting the visual form of each track, except general collapse, and rest, only the visual aspect).

The problem occurs when the group contains more groups. The function return a error.

Is there any way to detect that within a group there is another group?

In this way, if there is one or more groups within the parent group, condition the function to stop it. This would only be valid for a single level group, but at least it would not return the error.

The function “clone a group with only tracks inside”:

function amic_CH04_9M(m, nmg, clg, cbg, nmt, clt, cbt, ncl, vol, pan, dly, sfx, fxt )-- CLONE TRACK OR GROUP WITH A LEVEL
  --[[
  renoise.Track.TRACK_TYPE_SEQUENCER
  renoise.Track.TRACK_TYPE_GROUP
  renoise.Track.TRACK_TYPE_MASTER
  renoise.Track.TRACK_TYPE_SEND
  ]]

  local song, app = renoise.song(), renoise.app()
  local sid = song.selected_track_index
  print ( "sid:", sid )
  local ssid = song.tracks[song.selected_track_index]

  if (song.selected_track.type == renoise.Track.TRACK_TYPE_GROUP) then --IF GROUP
    m = #ssid.members
    print ( "sid:", sid )
    print ( "m:", m )
    nmg = ssid.name print ( "nmg:" , nmg )
    clg = ssid.color print ( "clg:" , clg )
    cbg = ssid.color_blend print ( "cbg:" , cbg )
    song:insert_group_at( sid + 1 )    

    local ssid = song.tracks[sid + 1]
    ssid.name = nmg.." Clone"
    ssid.color = clg
    ssid.color_blend = cbg
    song.selected_track_index = sid - m -- jump first track son

    for i = 1, m do --or-- for i = 1, a do
      local ssid = song.tracks[song.selected_track_index]
      nmt = ssid.name print ( "nmt-son:" , nmt )
      clt = ssid.color print ( "clt-son:" , clt )
      cbt = ssid.color_blend print ( "cbt-son:" , cbt )
      --- ---
      ncl = ssid.visible_note_columns print ( "ncl:" , ncl )
      vol = ssid.volume_column_visible print ( "vol:" , vol )
      pan = ssid.panning_column_visible print ( "pan:" , pan )
      dly = ssid.delay_column_visible print ( "dly:" , dly )
      sfx = ssid.sample_effects_column_visible print ( "sfx:" , sfx )
      fxt = ssid.visible_effect_columns print ( "fxt:" , fxt )
      song:insert_track_at(song.selected_track_index + m + 1 )
      print ( "m:", m )
      local ssid = song.tracks[song.selected_track_index + m + 1]
      ssid.name = nmt.." Clone"
      ssid.color = clt
      ssid.color_blend = cbt
      --- ---
      ssid.visible_note_columns = ncl
      ssid.volume_column_visible = vol
      ssid.panning_column_visible = pan
      ssid.delay_column_visible = dly
      ssid.sample_effects_column_visible = sfx
      ssid.visible_effect_columns = fxt
      song.selected_track_index = song.selected_track_index + 1
    end

    song.selected_track_index = song.selected_track_index + m + 1 --jump new group

    for i = 1, m do
      local sid2 = song.selected_track_index
      song:add_track_to_group( sid2 - m , sid2 ) 
    end

  else
    --content else
  end
  --- --- ---
    if (song.selected_track.type == renoise.Track.TRACK_TYPE_SEQUENCER) then --IF TRACK

    --[[ -- 9 parameters
        name = "MY TRACK",
        color = { 0xFF,0x00,0x00 },
        color_blend = 40,
        visible_note_columns = 1,
        volume_column_visible = true,
        panning_column_visible = false,
        delay_column_visible = false,
        sample_effects_column_visible = false,
        visible_effect_columns = 0
      ]]

    nmt = ssid.name print ( "nmt:" , nmt )
    clt = ssid.color print ( "clt:" , clt )
    cbt = ssid.color_blend print ( "cbt:" , cbt )
    --- ---
    ncl = ssid.visible_note_columns print ( "ncl:" , ncl )
    vol = ssid.volume_column_visible print ( "vol:" , vol )
    pan = ssid.panning_column_visible print ( "pan:" , pan )
    dly = ssid.delay_column_visible print ( "dly:" , dly )
    sfx = ssid.sample_effects_column_visible print ( "sfx:" , sfx )
    fxt = ssid.visible_effect_columns print ( "fxt:" , fxt )
    
    song:insert_track_at(sid + 1)
    local ssid = song.tracks[sid + 1]
    ssid.name = nmt.." Clone"
    ssid.color = clt
    ssid.color_blend = cbt
    --- ---
    ssid.visible_note_columns = ncl
    ssid.volume_column_visible = vol
    ssid.panning_column_visible = pan
    ssid.delay_column_visible = dly
    ssid.sample_effects_column_visible = sfx
    ssid.visible_effect_columns = fxt
  
    song.selected_track_index = sid + 1
  else
   --content else
  end
end

It is possible to add more lines to clone more features (notes, parameters, device chains…).However, cloning (or duplicating) multiple groups and tracks within a parent groupis a challenge for any programmer.In fact, Renoise 3.1 has a bug related to this.

@Danoise, would you dare to write the function to clone up to 5 levels of groups, respecting the visual aspect?

I think this is the most difficult function I have faced so far with LUA code. I invite anyone to try!!! :guitar:

Do you dare to write it?You would be a god!

I can not get down from group level 1.From level 2 I crash! – erroooooorrrr!!! :smashed:

The group tracks features the property “members” (renoise.song().tracks.members).

I would suggest that you scan the track structure (recursively). You will not escape recursion at some stage here, I believe.

For the sake of simplicity, I’d probably 1) scan the track structure recursively, 2) store the structure in a table, 3) parse the table thru a copying function.

The group tracks features the property “members” (renoise.song().tracks.members).

I would suggest that you scan the track structure (recursively). You will not escape recursion at some stage here, I believe.

For the sake of simplicity, I’d probably 1) scan the track structure recursively, 2) store the structure in a table, 3) parse the table thru a copying function.

With renoise.song().tracks[renoise.song().selected_track_index].members returns a number (sons of the group). In the function, I call the number as “m”.

With this number, I can not differentiate between track or group, the type.

With 2 levels of groups:

----------------------------- GROUP1 --------------------

------------- GROUP2 ------------------- TRACK1-----

------TRACK2------TRACK3------

GROUP2 is within GROUP1. I can not detect that GROUP2 is a group, or is not a track.Maybe knowing this, I set the function.

Regarding to create the function with scan, table and copy, I believe that I am incapable. It has to work with 5 group levels, or even more.But it would be a pleasure to see a simple, even for a level of group, to study.For example, this simple case:

With 1 level group:

------------------------ GROUP1 -------------------------

------ TRACK1-------TRACK2-------TRACK3--------

Some code example?

Thank you very much for the help joule!