Old 04-21-2018, 10:39 AM   #1
inertia
Human being with feelings
 
Join Date: Oct 2013
Posts: 533
Default Help with renaming script ....weird bug

I have a strange problem with my script. The idea is to cleanup the FX names in the FX list window on each track.

If you add a track and add 3 or 4 plugins and run the script then only the first and last plugin are renamed.

The problem only happens when I run the SetFXName function inside a loop otherwise the function works as expected when I manually give the plugin index.

I think it's failing at :
if t_check:find(FX_GUID) then
__________________
http://murdryck.info
inertia is offline   Reply With Quote
Old 04-21-2018, 10:39 AM   #2
inertia
Human being with feelings
 
Join Date: Oct 2013
Posts: 533
Default

https://pastebin.com/MM6PM9ni
__________________
http://murdryck.info

Last edited by inertia; 04-21-2018 at 10:47 AM.
inertia is offline   Reply With Quote
Old 04-21-2018, 12:06 PM   #3
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: The vast, frozen wasteland of western Canadia.
Posts: 5,379
Default

My guess is an issue with how you're counting FX indexes. Notice how in the printout below it grabs the fourth plugin during the second iteration.

I added some extra messaging to your code and got the following. Track effects were:

Code:
1973 Equalizer
Aradaz Crunch
Crossover
Desk4
Code:
reading FX on track 1
	found	VST: 1973 Equalizer (x86) (Stillwell Audio)	at index 0
	cleaned	1973 Equalizer

...chunk stuff, name is changed...

VST "VST: 1973 Equalizer (x86) (Stillwell Audio)" 1973.dll 0 "1973 Equalizer" 959985458


	found	VST: AradazAmp_Crunch_v1.4 (x86) (Aradaz)	at index 1
	cleaned	AradazAmp Crunch v1.4

...chunk stuff, name is changed...

VST "VST: Desk4 (airwindows)" Desk464.dll 0 "AradazAmp Crunch v1.4" 1684763753


	found	VST: CrossOver (x86) (RS-MET) (2->8ch)	at index 2
	cleaned	CrossOver

...chunk stuff, name is changed...

VST "VST: Desk4 (airwindows)" Desk464.dll 0 "CrossOver" 1684763753


	found	CrossOver	at index 3
	cleaned	nil


...doesn't do the last chunk because of the nil...
----------------------

The process as a whole is really convoluted and could be done much simpler, which would make debugging it much easier - I'm guilty of the same thing in a few of my scripts, and I can attest that they're a nightmare to sort through.

For instance:

- Only read through the chunk once
- Store the names, the relevant lines, and the relevant line numbers in a table
- Clean the names and insert them into the copied lines
- Replace the original lines with those
- Set the chunk.

SetFXName is also way too big, which makes it harder to nail problems down.

I've been reading a lot about writing "good" code lately, and one consistent point is to make functions small. They don't have to be tiny, but ideally should do only one thing. Big for and if structures can almost always be broken out into a function of their own that just returns the value you want.
__________________
Currently working away from home; don't expect timely responses from me.
Default 5.0 Nitpicky Edition / GUI tutorial for Lua / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate / ReaPack
Lokasenna is offline   Reply With Quote
Old 04-21-2018, 01:48 PM   #4
inertia
Human being with feelings
 
Join Date: Oct 2013
Posts: 533
Default

Thanks for looking.

That function isn't mine but something I found on the net. I do actually code Java for a living and do structure code a lot better than this, haha

The script was supposed to be a trivial thing but, as usual, it turns out to be a bit more complicated. I am also learning Lua on the fly and figuring out every piece of code as I go along.

Debugging the chunk, I cannot find any of the contents of FX_GUID in the output information, so I don't really understand how it matches the id anyway.

I also don't understand why it works fine to do this :

SetFXName(track, 0, "test name1")
SetFXName(track, 1, "test name2")
SetFXName(track, 2, "test name3")
SetFXName(track, 3, "test name4")

Why would sending an index integer into the function via a loop screw this up?

I will try and optimise the function tomorrow as your suggestions.
__________________
http://murdryck.info
inertia is offline   Reply With Quote
Old 04-21-2018, 02:07 PM   #5
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: The vast, frozen wasteland of western Canadia.
Posts: 5,379
Default

It doesn't work - the same effect chain as above ends up looking like this:

test name1
VST: AradazAmp...
VST: CrossOver...
test name4

The GUID is in {}s on the FXID line, with some dashes in it.

Definitely looks like it's not storing/recalling the line to edit properly, though I can't quite tell how. Could be an index somewhere that should be index - 1, or vice versa, or checking the length on a table that starts at 0 (Lua expects them to start at 1 for any table.___ or ipairs stuff). Not sure.
__________________
Currently working away from home; don't expect timely responses from me.
Default 5.0 Nitpicky Edition / GUI tutorial for Lua / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate / ReaPack

Last edited by Lokasenna; 04-21-2018 at 02:15 PM.
Lokasenna is offline   Reply With Quote
Old 04-21-2018, 03:44 PM   #6
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: The vast, frozen wasteland of western Canadia.
Posts: 5,379
Default

Victory!

This is a perfect example of why everything in Lua should be local unless you specifically want a global. This part:

Code:
for i = #t, 1, -1 do
    local t_check = t[i]:gsub('-','')
       
    if t_check:find(FX_GUID) then
      search = true
--      if search then reaper.ShowConsoleMsg("found\n") end
    end
 
    if t[i]:find('<') and search and not t[i]:find('JS_SER') then
      edited_line = t[i]:sub(2)
      edited_line_id = i
     
     -- reaper.ShowConsoleMsg("edited_line_id "..edited_line.."\n")
     
      break
    end
  end
search is a global variable, so it retains its value after the loop finishes and has true ready to go when the next iteration of SetFXName rolls by - this causes it to grab the first line that satisfies the other conditions (starting with '<', doesn't contain 'JS_SR'). Since the loop is going from #t backwards, that means it grabs the last effect in the chunk.

Slightly cleaned up code with more console messages here:
Code:
function Msg(str)
   reaper.ShowConsoleMsg(tostring(str).."\n") 
end

function SetFXName(track, fx, new_name)
    
    -- get re
    if not track or not tonumber(fx) then return end

    Msg("\n\nplugin "..fx)
    Msg("new name:\t"..new_name)

    local FX_GUID = reaper.TrackFX_GetFXGUID( track, tonumber(fx) )
    if not FX_GUID then return else FX_GUID = FX_GUID:gsub('-',''):sub(2,-2) end

    Msg("FX_GUID "..FX_GUID)

    plug_type = reaper.TrackFX_GetIOSize( track, fx )

    -- get chunk t
    local _, chunk = reaper.GetTrackStateChunk( track, '', false )
    local t = {} 

    for line in chunk:gmatch("[^\r\n]+") do 
        t[#t+1] = line
    end
    
    local GUID_line
    
    local edited_line, edited_line_id
    
    for i = #t, 1, -1 do
        
        local t_check = t[i]:gsub('-','')
           
        if t_check:find(FX_GUID) then 
            GUID_line = i
            Msg("found FX_GUID: "..i)
        end
    
    end
    
    if not GUID_line then return end
    
    for i = GUID_line, 1, -1 do

        if t[i]:find('<') and not t[i]:find('JS_SER') then
            edited_line = t[i]
            edited_line_id = i
          
            Msg("line to edit\n\t"..edited_line_id..": "..tostring(edited_line))
          
            break
            
        end
        
    end
    
    -- parse line
    if not edited_line then return end

    Msg("parsing line:")
    
    -- break the line into words
    local t1 = {}
    for word in edited_line:gmatch('[%S]+') do 
        t1[#t1+1] = word 
        Msg("\t"..tostring(word))        
    end

    t2 = {}
    
    -- combine the words that have "s, I think
    for i = 1, #t1 do
        segm = t1[i]
        if not q then
            t2[#t2+1] = segm 
        else 
            t2[#t2] = t2[#t2]..' '..segm 
        end
        if segm:find('"') and not segm:find('""') then
            if not q then q = true else q = nil end
        end
    end

    if plug_type == 2 then t2[3] = '"'..new_name..'"' end -- if JS
    if plug_type == 3 then t2[5] = '"'..new_name..'"' end -- if VST

    local out_line = table.concat(t2,' ')

    Msg("out_line:\n\t"..out_line)

    t[edited_line_id] = out_line
    
    Msg("edited line:\n\t"..t[edited_line_id])
    
    reaper.SetTrackStateChunk( track, table.concat(t,'\n'), false )
    reaper.UpdateArrange()
    
    return true
    
end

function cleanup(name)
    newname = name:gsub("_", " ")
    return newname
end

function sleep(n)
    if n > 0 then os.execute("ping -n " .. tonumber(n+1) .. " localhost > NUL") end
end

reaper.ClearConsole()

for i = 1,reaper.CountTracks(0),1 do
    track = reaper.GetTrack(0,i-1)

    Msg("reading FX on track "..i)

    for plugin_index = 1,reaper.TrackFX_GetCount(track),1 do
        retval, fxname = reaper.TrackFX_GetFXName(track, (plugin_index-1), "")
        cleanname = (string.match(cleanup(fxname), ': (.-)%s%('))
        
        Msg("\tfound\t"..tostring(fxname).."\tat index "..(plugin_index-1).."\n\tcleaned\t"..tostring(cleanname))

        if cleanname or not cleanname == '' then
            local ret = SetFXName(track, plugin_index-1,  cleanname)
            Msg("returned "..tostring(ret))
        end
        Msg("\n")
    end

end


Msg("Finished")
__________________
Currently working away from home; don't expect timely responses from me.
Default 5.0 Nitpicky Edition / GUI tutorial for Lua / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate / ReaPack
Lokasenna is offline   Reply With Quote
Old 04-21-2018, 10:15 PM   #7
inertia
Human being with feelings
 
Join Date: Oct 2013
Posts: 533
Default

Brilliant. Thanks again for taking the time to sort it out.

Seems to be working just fine now.
__________________
http://murdryck.info
inertia is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 04:04 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.