Old 01-06-2021, 03:02 AM   #201
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Permanent monitoring using defer-script.

Store all MediaTracks in a table in trackorder.
Next time, check, whether Mediatrack of track1 is still the same as in the first position of the table, andsoonandsoon.
If there's any Mediatrack not like the one in the table, order has been changed.

Keep also track of the ReaProject, so you catch tabswitches. Otherwise you think order has changed, though selected project has changed.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 01-06-2021, 03:48 AM   #202
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 451
Default ShowMessageBox

Okay I have another one. I built up a list and used ShowMessageBox() to display it. But the columns are messed up. I've read in threads that it was changed to monospace, but I don't see that. I suppose there is no way to change it so it specifically uses monospace? Either ANSI codes or some other function? I suppose it's not a big deal but it would be nice to have the ability to display a window with a neat little table inside. I calculated the spacing and spaced it out with formatting codes to align with my headings, so numbers would fit underneath, but the spacing was still off.
Hypex is offline   Reply With Quote
Old 01-06-2021, 03:58 AM   #203
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Quote:
Originally Posted by Hypex View Post
Okay I have another one. I built up a list and used ShowMessageBox() to display it. But the columns are messed up. I've read in threads that it was changed to monospace, but I don't see that. I suppose there is no way to change it so it specifically uses monospace? Either ANSI codes or some other function? I suppose it's not a big deal but it would be nice to have the ability to display a window with a neat little table inside. I calculated the spacing and spaced it out with formatting codes to align with my headings, so numbers would fit underneath, but the spacing was still off.
Only ReaScript-console has been changed to monospace (reaper.ShowConsoleMsg("String") )

You can try using \t between the entries. This aligns them up, as far as I can see.

Code:
reaper.MB("A\tB\tC\nAA\tBBB\tZU","",0)
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 01-06-2021, 04:15 AM   #204
80icio
Human being with feelings
 
Join Date: Mar 2016
Location: Italy
Posts: 322
Default

wrote this script to find out what track groups are assigned to a track, the
script works (just for the first 32 trackgroups but i can easily implement from 33 to 64)
just need to know if there's anything any of you would change/improve or cut on this script

thanks

Code:
local trksel = reaper.GetSelectedTrack( 0, 0 )
local grp = reaper.GetSetTrackGroupMembership(trksel, "VOLUME_LEAD", 0, 0 )

local grptable ={}
  for i = 1, 32 do
    grptable[i] = false
  end

local allgrp = grp

function seekgroups()
grpn = 0
  while grp >= 1 do
    grp = math.floor(grp/2)
    grpn = grpn + 1
  end
  grp = allgrp - 2^(grpn-1)
  allgrp = grp
end


function collectgroups()
  for i = 1, 32 do
  seekgroups()
  if grpn ~= 0 then
  grptable[grpn] = true
  end
  end
end
reaper.ClearConsole()
collectgroups()
for i = 1, 32 do
reaper.ShowConsoleMsg(i .. " - " .. tostring(grptable[i]) .. "\n")
end

Last edited by 80icio; 01-06-2021 at 04:25 AM.
80icio is offline   Reply With Quote
Old 01-06-2021, 07:53 AM   #205
Triode
Human being with feelings
 
Triode's Avatar
 
Join Date: Jan 2012
Posts: 1,180
Default

Hey 80icio

Just in case this was related to my script... I sent you a message yesterday. Did you get it?
Cheers

Quote:
Originally Posted by 80icio View Post
wrote this script to find out what track groups are assigned to a track, the
script works (just for the first 32 trackgroups but i can easily implement from 33 to 64)
just need to know if there's anything any of you would change/improve or cut on this script

thanks

Code:
local trksel = reaper.GetSelectedTrack( 0, 0 )
local grp = reaper.GetSetTrackGroupMembership(trksel, "VOLUME_LEAD", 0, 0 )

local grptable ={}
  for i = 1, 32 do
    grptable[i] = false
  end

local allgrp = grp

function seekgroups()
grpn = 0
  while grp >= 1 do
    grp = math.floor(grp/2)
    grpn = grpn + 1
  end
  grp = allgrp - 2^(grpn-1)
  allgrp = grp
end


function collectgroups()
  for i = 1, 32 do
  seekgroups()
  if grpn ~= 0 then
  grptable[grpn] = true
  end
  end
end
reaper.ClearConsole()
collectgroups()
for i = 1, 32 do
reaper.ShowConsoleMsg(i .. " - " .. tostring(grptable[i]) .. "\n")
end
__________________
Mixing / Brush and Beater Drums Online: www.outoftheboxsounds.com
Triode is offline   Reply With Quote
Old 01-06-2021, 09:09 AM   #206
80icio
Human being with feelings
 
Join Date: Mar 2016
Location: Italy
Posts: 322
Default

Quote:
Originally Posted by Triode View Post
Hey 80icio

Just in case this was related to my script... I sent you a message yesterday. Did you get it?
Cheers
Somehow it is! but it's an exercise to understand the function
GetSetTrackGroupMembership and how to interpret the number you get when there's multiple groups selected for 1 track.
80icio is offline   Reply With Quote
Old 01-06-2021, 12:51 PM   #207
Triode
Human being with feelings
 
Triode's Avatar
 
Join Date: Jan 2012
Posts: 1,180
Default

Yeah I was looking for a way for the track group based item editing to work only with track groups that are turned on. Let me know if you end up with a way to do that
__________________
Mixing / Brush and Beater Drums Online: www.outoftheboxsounds.com
Triode is offline   Reply With Quote
Old 01-07-2021, 01:16 AM   #208
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 451
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
Only ReaScript-console has been changed to monospace (reaper.ShowConsoleMsg("String") )


Ah, yes


You can try using \t between the entries. This aligns them up, as far as I can see.

Thanks for the hint. I found it neatly aligned all my numbers, but my headings were all out of whack. Also, it looks to be a relative tab position, as bigger numbers pushed the position across.


I'll just do it another way. Not as neat. But I can be a neat freak when it comes to displaying a simple list. :-)
Hypex is offline   Reply With Quote
Old 01-08-2021, 12:35 AM   #209
80icio
Human being with feelings
 
Join Date: Mar 2016
Location: Italy
Posts: 322
Default

Quote:
Originally Posted by Triode View Post
Yeah I was looking for a way for the track group based item editing to work only with track groups that are turned on. Let me know if you end up with a way to do that
Code:
dofile(reaper.GetResourcePath().."/UserPlugins/ultraschall_api.lua")
reaper.Main_SaveProject( 0, 0 )
retval, projfn = ultraschall.EnumProjects(0)
disabled1, disabled2 = ultraschall.GetProject_GroupDisabled(projfn)
reaper.ShowConsoleMsg(disabled1 .. "\n")
This is the closet thing I have so far to get disabled groups using ultrashall api (disabled 2 is for 33 to 64 groups)
unfortunately saving the project is needed.

There's should be some config variables temporarily stored somewhere that can tell if a group is disabled (while the project is unsaved) but I don't know that much about it
80icio is offline   Reply With Quote
Old 04-12-2021, 10:10 AM   #210
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

Hi guys!

I have a sorting question.

How can I sort complex tables? Here's a simplified piece of my code where I'm stuck. Here, each cell consists of a "main" value (position) and a "secondary" value (velocity), additionaly each "secondary" split into two cells. I can easily add values with a table.insert just by using two lines. They are predictably added to the end of the table.

A task. I only need to sort the "main" value, but keeping the binding to the "secondary". Can someone suggest a solution?


Code:
State_Points = {}  -- State_Points table 
local st_cnt    = 1  
local RMS = 12
local peak_smpl = 23
local cnt = 10

       for i = 1, cnt, 1 do -- 

           State_Points[st_cnt]   = i -- position (main)
           State_Points[st_cnt+1] = {RMS, peak_smpl} -- velocity (secondary)
           st_cnt = st_cnt+2
       end   

 ---------------------------------
Res_Points = {}

    for i=1, #State_Points, 2 do

         local p = #Res_Points+1
         Res_Points[p]   = State_Points[i] -- position (main)
         Res_Points[p+1] = {State_Points[i+1][1], State_Points[i+1][2]} -- velocity (secondary)
    end 
   
local velocity = 127
local position = 7.3
-----------------------
        table.insert(Res_Points, position)
        table.insert(Res_Points, {velocity, velocity})

local velocity = 120
local position = 1.5
 ----------------------         
        table.insert(Res_Points, position) 
        table.insert(Res_Points, {velocity, velocity})

   --    table.sort(Res_Points) -- just error: "attempt to compare table with number"
cool is offline   Reply With Quote
Old 04-12-2021, 11:13 AM   #211
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 190
Default

Quote:
Originally Posted by cool View Post
How can I sort complex tables? Here's a simplified piece of my code where I'm stuck. Here, each cell consists of a "main" value (position) and a "secondary" value (velocity), additionaly each "secondary" split into two cells. I can easily add values with a table.insert just by using two lines. They are predictably added to the end of the table.

A task. I only need to sort the "main" value, but keeping the binding to the "secondary". Can someone suggest a solution?
This may help point you in the right direction, but I have a function I use to sort dictionary that are within a table (i.e. table[0] = {key=1, other_key=2}).

Code:
--sorts the array given to it by whatever key value you provide
function sort_array_dicts(tempArray, key, isOne, reverse)

	local itemCount = #tempArray
	local hasChanged

	local startIndex = 0
	if isOne == true then
		startIndex = 1
	end

	--sorts it in ascending order
	if not reverse then
		repeat
			hasChanged = false
			itemCount = itemCount - 1

			for i = startIndex, itemCount do
				if tempArray[i][key] > tempArray[i + 1][key] then
					tempArray[i], tempArray[i + 1] = tempArray[i + 1], tempArray[i]
					hasChanged = true
				end
			end
		until hasChanged == false

	--sorts it in descending order
	else
		repeat
			hasChanged = false
			itemCount = itemCount - 1

			for i = startIndex, itemCount do
				if tempArray[i][key] < tempArray[i + 1][key] then
					tempArray[i], tempArray[i + 1] = tempArray[i + 1], tempArray[i]
					hasChanged = true
				end
			end
		until hasChanged == false
	end


	return tempArray
end

The only two necessary parameters are "tempArray" (the table you want it to sort) and "key" (the key that you want it to sort by). The other ones just default to nil if you don't pass anything to them, but "isOne" should be set to true if the table starts at an index of 1 (native in Lua) and "reverse" should be set true if you want it to sort everything highest to lowest.

I adjusted some of your code to (in theory) work. I may have missed the point of your code, so it is probably best to check over it and make sure that it stores all of the stuff you need.

Code:
State_Points = {}  -- State_Points table 
local st_cnt    = 1  
local RMS = 12
local peak_smpl = 23
local cnt = 10

       for i = 1, cnt, 1 do
       	table.insert(State_Points, {position=i, rms=RMS, peak=peak_smpl}) -- velocity (secondary)
       end   

 ---------------------------------
Res_Points = {}

    for i=1, #State_Points do
         table.insert(Res_Points, State_Points[i]) 
    end 
   
local velocity = 127
local position = 7.3
-----------------------
	table.insert(Res_Points, {position=position, rms=velocity, peak=velocity})

local velocity = 120
local position = 1.5
 ----------------------         
        table.insert(Res_Points, {position=position, rms=velocity, peak=velocity})

	sort_array_dicts(Res_Points, 'position', true)
I basically just changed the initial table to store all of the information for its index within a dictionary, rather than store the info for the same point across multiple indexes. Also, if you didn't want to use a dictionary and just use another table, you can just do something like this:

Code:
table.insert(State_Points, {i, RMS, peak_smpl})
--other code--
table.insert(Res_Points, {position, velocity, velocity})
--other code--
sort_array_dicts(Res_Points, 1, true)

Last edited by jkooks; 04-12-2021 at 11:37 AM.
jkooks is offline   Reply With Quote
Old 04-12-2021, 01:45 PM   #212
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 1,992
Default

hey cool why are you using two key of a table to put info about one group of things?

I don't really understand what you need but I would organize my tables this way
Code:
State_Points = {}  -- State_Points table 
local st_cnt    = 1  
local RMS = 12
local peak_smpl = 23
local cnt = 10

       for i = 1, cnt do -- 
           State_Points[i]   = {}
           State_Points[i][["RMS"] = RMS
           State_Points[i][["peak_smpl"] = peak_smpl
       end
Or instead of using RMS and peak_smpl as a key you can use a number as long you remember or even comment on the code what key they correspond to.

About table sorting, if you want to table.sort the table above lets say by the RMS value you could changing the function it uses (is the second variable). look here
https://www.lua.org/pil/19.3.html

If you abstract more what you need I think I can try help build this function.
daniellumertz is offline   Reply With Quote
Old 04-12-2021, 06:56 PM   #213
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

jkooks, thank you! And a lot of apologies at once: I did not specify the details of the problem!

I only need to sort the Res_Points table. This is how I tried to do on the last, commented out line. Ideally, without touching table.insert, because it is a "variable": different numbers of cells can be written with table.insert.

In one sentence: I need to sort the Res_Points table by the "position" key every time table.insert runs.

daniellumertz, Thank you for your attention to the topic! Unfortunately, this is not my script. This is a part of a huge working script, which was not written by me (it was written by Evgen2777) and which it is too late to change. So I have to adapt.
cool is offline   Reply With Quote
Old 04-12-2021, 09:59 PM   #214
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 1,992
Default

I would or try to remake this table at some point like remake the script or try to condense this old table model in one that fits you best,

like this exemple
Code:
tabless = {}
a = 5
a2 = {5 , 6}
table.insert(tabless, a)
table.insert(tabless, a2)
a = 2
a2 = {8 , 9}
table.insert(tabless, a)
table.insert(tabless, a2)

new_table = {}
for k,v in pairs(tabless) do
    if k%2 == 1 then
        new_table[#new_table+1] = {}
        new_table[#new_table]["a_value"] = tabless[k]
        new_table[#new_table]["a2_table"] = tabless[k+1]
    end
end

print(new_table[1]["a_value"])
print(new_table[1]["a2_table"][2])
from this to write a function inside the table.sort that compares the values of the odd numbers of a table. like this

Code:
tabless = {}
a = 5
a2 = {7 , 6}
table.insert(tabless, a)
table.insert(tabless, a2)
a = 2
a2 = {8 , 9}
table.insert(tabless, a)
table.insert(tabless, a2)

new_table = {}
for k,v in pairs(tabless) do
    if k%2 == 1 then
        new_table[#new_table+1] = {}
        new_table[#new_table]["a_value"] = tabless[k]
        new_table[#new_table]["a2_table"] = tabless[k+1]
    end
end

print(new_table[1]["a_value"])
print(new_table[1]["a2_table"][2])

table.sort(new_table, function(keyLhs, keyRhs) return keyLhs.a_value < keyRhs.a_value end)
print(new_table[1]["a_value"])
daniellumertz is offline   Reply With Quote
Old 04-13-2021, 01:27 AM   #215
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

Thank you! It's very close!

Code:
State_Points = {}  -- State_Points table 
local st_cnt    = 1  
local RMS = 12
local peak_smpl = 23
local cnt = 10

       for i = 1, cnt, 1 do -- 

           State_Points[st_cnt]   = i -- position (main)
           State_Points[st_cnt+1] = {RMS, peak_smpl} -- velocity (secondary)
           st_cnt = st_cnt+2
       end   

 ---------------------------------
Res_Points = {}

    for i=1, #State_Points, 2 do

         local p = #Res_Points+1
         Res_Points[p]   = State_Points[i] -- position (main)
         Res_Points[p+1] = {State_Points[i+1][1], State_Points[i+1][2]} -- velocity (secondary)
    end 
   

local velocity = 127
local position = 7.3
-----------------------
        table.insert(Res_Points, position)
        table.insert(Res_Points, {velocity, velocity})


local velocity = 120
local position = 1.5
 ----------------------         
        table.insert(Res_Points, position) 
        table.insert(Res_Points, {velocity, velocity})


-------------------------sort table-----------------------------

Res_PSorted = {}
for k,v in pairs(Res_Points) do
    if k%2 == 1 then
        Res_PSorted[#Res_PSorted+1] = {}
        Res_PSorted[#Res_PSorted]["position_value"] = Res_Points[k]
        Res_PSorted[#Res_PSorted]["velocity_table"] = Res_Points[k+1]
    end
end

print(Res_PSorted[1]["position_value"])
print(Res_PSorted[1]["velocity_table"][2])

table.sort(Res_PSorted, function(keyLhs, keyRhs) return keyLhs.position_value < keyRhs.position_value end)
print(Res_PSorted[1]["position_value"])
Now sorting works, but I still have two questions, because of which I cannot integrate this into my script properly.

1. New table, it's OK. Most of the functions work fine after I change the table name. Nevertheless, is it possible to sort the current Res_Points table, or add the sorting result to it, replacing the existing values?

2. Despite the fact that sorting works well, nevertheless, the structure of the table has changed. For example, further down the code. Before I used:

Code:
    local points_cnt = #Res_PSorted
      for i=1, points_cnt, 2 do
                 if i<points_cnt then startppqp0s = Res_PSorted[i] end
                 if i<points_cnt-2 then next_startppqp0s = Res_PSorted[i+2] end
                  vel =  Res_PSorted[i+1][mode]
     end
Now I had to use:
Code:
    local points_cnt = #Res_PSorted
      for i=1, points_cnt, 2 do
                 if i<points_cnt then startppqp0s = Res_PSorted[i].position_value end
                 if i<points_cnt-1 then next_startppqp0s = Res_PSorted[i+1].position_value end
                 vel =  Res_PSorted[i].velocity_table[mode]
     end
Is it possible to preserve the structure of the table? I apologize for the nitpicking and many questions. Tables are my weak point.
cool is offline   Reply With Quote
Old 04-13-2021, 09:54 AM   #216
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 1,992
Default

I find table.sort very confusing, I think you could write a abstracted version of what you need, JUST with the purely essencial and try to post in some lua forum. I wouldn't know how to make a sort function to sort it each odd number of the table. Maybe with metatable but my head just bugs trying to understand it...Post here when you got yours solution!
daniellumertz is offline   Reply With Quote
Old 04-14-2021, 10:17 AM   #217
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

Quote:
Originally Posted by daniellumertz View Post
I find table.sort very confusing, I think you could write a abstracted version of what you need, JUST with the purely essencial and try to post in some lua forum. I wouldn't know how to make a sort function to sort it each odd number of the table. Maybe with metatable but my head just bugs trying to understand it...Post here when you got yours solution!
OK!
It turned out to be more complicated than I thought.
Thank you!
cool is offline   Reply With Quote
Old 04-16-2021, 11:50 AM   #218
en5ca
Human being with feelings
 
Join Date: Dec 2018
Posts: 394
Default

Can I access MIDI CC or Chanel values assigned to Action (the script) in a same way like reaper.get_action_context() reads the MIDI/OSC parameter value?

E.g. MIDI Channel 1 CC 7 parameter value is assigned to script, but only the parameter value can be read/used in the script itself?
en5ca is offline   Reply With Quote
Old 07-21-2021, 04:29 AM   #219
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 451
Default

Is this thread abandoned now? Have a query. How do I get the window position from gfx_init()? I'm experimenting from IDE with gfx_showmenu() which is nice but the x/y offset is from the screen and not the window. It has the window w/h already but not x/y position. Would like to display it in the window framebuffer, that is inside the window, but don't know how. Are there any tutorials for this stuff?
Hypex is offline   Reply With Quote
Old 07-21-2021, 05:10 AM   #220
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

Quote:
Originally Posted by Hypex View Post
Is this thread abandoned now? Have a query. How do I get the window position from gfx_init()? I'm experimenting from IDE with gfx_showmenu() which is nice but the x/y offset is from the screen and not the window. It has the window w/h already but not x/y position. Would like to display it in the window framebuffer, that is inside the window, but don't know how. Are there any tutorials for this stuff?
Hi!

If my memory serves me.
First, we get the coordinates of the window:
Code:
 local _, xpos, ypos, Wnd_W, Wnd_H = gfx.dock(-1, 0, 0, 0, 0)

xpos and ypos = position
Wnd_W and Wnd_H = window size


and then:
Code:
gfx.init( window_title, Wnd_W,Wnd_H, dock_position, xpos,ypos)
cool is offline   Reply With Quote
Old 07-21-2021, 08:22 AM   #221
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 451
Default

Quote:
Originally Posted by cool View Post
Hi!

If my memory serves me.
First, we get the coordinates of the window:

Hi! Thanks for the info. Ok so it looks like you grab the default values before opening the window. At this point it would be good to have the screen w/h as well.


Well I tried it but I still get zero values back. Unless I open a window. Then the x/y are still zero but the w/h are filled in and match gfx_w/gfx_h.


I tested both Windows and Linux. Windows opens a window in the upper left. Not right in the corner but returns 0/0 for x/y. However doing a showmenu at 0/0 shows it neatly under the title bar in the window. Strange. But on Linux the window is centred. However it still returns 0/0 for x/y and the menu shows up in the upper left of the screen!



Seriously this is too inconsistent. I don't know how anyone can work like this unless they know the secrets. I can't figure it out. The only thing that makes sense is a VGA style 640x480 window size. That's nice. :-)
Hypex is offline   Reply With Quote
Old 07-21-2021, 08:44 AM   #222
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

I made a simple demo for it:

Code:
-- open window
gfx.init("this is a test window", 800, 600, 0, 300,100)

function main()
  -- query window-state
  Dockstate, PosX, PosY, Width, Height=gfx.dock(-1,0,0,0,0)
  
  -- if right mouse is clicked, open a menu
  if gfx.mouse_cap&2==2 then
    -- convert the coodinates to near the mouse
    gfx.x, gfx.y = gfx.screentoclient(PosX+gfx.mouse_x, PosY+gfx.mouse_y)
    gfx.showmenu("Haiho")
  end
  
  reaper.defer(main)
end

main()
This opens a window and shows a menu at mouse-position, when clicked with right click.
I think, you can adapt this demo to the way you want it.

You can also see, how PosX, PosY, Width, Height change, when you move or resize the window.

The reason why you got 0,0,640,400 is that the window is actually at position 0,0 with a size of 640x400. You can set a different size/position with gfx.init.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...

Last edited by Meo-Ada Mespotine; 07-21-2021 at 10:38 AM.
Meo-Ada Mespotine is offline   Reply With Quote
Old 07-21-2021, 11:43 PM   #223
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 451
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
This opens a window and shows a menu at mouse-position, when clicked with right click.
I think, you can adapt this demo to the way you want it.

Okay thanks also. I see you also specified positions. I keep seeing this along with font sizes and can't get my head around it. It could be my old way of thinking as when I see absolute position I tend to think of it as absolute position and size which won't be the same on all screens. Does it refer to some scale that is converted?


Quote:
You can also see, how PosX, PosY, Width, Height change, when you move or resize the window.
Okay yes. I also got it stuck and accidentally opened more instances of it. Multitasking scripts are good but not when you keep opening them and then make it disappear. ;-)


Quote:
The reason why you got 0,0,640,400 is that the window is actually at position 0,0 with a size of 640x400. You can set a different size/position with gfx.init.
Now that makes no sense to me. I can understand relative position to window. But I expected window position to be absolute offset on screen. Especially since showmenu() looked to me as if it was showing up relative to screen in an absolute postilion. I can see your code working, but mine is still broke. If it makes any difference mine is EEL and doesn't defer but runs through once. I'm just wanting to display it inside the window but I don't know where that is! That gfx_dock() function just gives me 0 for x and y. Does it depend on defer() being called? Mind you I'm testing on Linux which differs from Windows. Windows doesn't centre the window by default but it does display the menu exactly inside the window below the title bar for position 0,0.



The following is supposed to open a nicely centred window then display a menu inside the window where the text is but I can't get it work. :-?



Code:
function gfx_setxy(x,y)
(
  gfx_x=x;
  gfx_y=y;
);

 gfx_init("Test");
 state=gfx_dock(-1,wx,wy,ww,wh);
 gfx_screentoclient(wx,wy);
 gfx_drawstr("Test\n");
 gfx_setxy(wx,wy);
 gfx_showmenu("first item, followed by separator||!second item, checked|>third item which spawns a submenu|#first item in submenu, grayed out");
 gfx_quit();
Hypex is offline   Reply With Quote
Old 07-22-2021, 01:14 PM   #224
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

To have a centered window, you need to set the coordinates in the gfx.init window. Otherwise the window will always open at screen-position 0,0.

After that, get the width of the window from the variable gfx_w and divide it by 2 and set gfx_x with it.
Then you get the height of the window from the variable gfx_h divide it by 2 and set gfx_y with the value.
You might need to convert them into integers before gfx_x and gfx_y but I don't know how to do it in EEL

Then you open gfx_showmenu.

This should work.

For further questions somebody else needs to take over. Will be off from the forum now for some time.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 07-22-2021, 07:40 PM   #225
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 451
Default

That's the thing. On Linux the window is centred. But the position still comes back as 0,0! That's why I can't make any sense of it. A centred window at 0,0 is not good to work with. Could be a bug.

On Windows it isn't centred but the position is correct and it's easy to neatly show a menu under the title.

Also forgot to mention the gfx_screentoclient() and gfx_clienttoscreen() functions return the exact same thing. I give them both 0,0 and they give back 0,0. :-?

Last edited by Hypex; 07-24-2021 at 11:36 PM.
Hypex is offline   Reply With Quote
Old 02-16-2022, 01:10 AM   #226
bezusheist
Human being with feelings
 
bezusheist's Avatar
 
Join Date: Nov 2010
Location: Mullet
Posts: 829
Default

i found this script a few years back, but it doesn't seem to work correctly (now?). ie..it returns several different values when clicking on the same sample. i think i messed it up when i was trying to customize it. could someone take a look at it and maybe set me straight here ?
thanks...
Code:
font_size = 16;
font_name = "Verdana";

buffer = 10000;


function get_samples_at_cursor(take)
(
  take_pcm_source = GetMediaItemTake_Source(take);
  //GetMediaSourceType(take_pcm_source, #typebuf);
  sample_rate = GetMediaSourceSampleRate(take_pcm_source);
  num_channels = GetMediaSourceNumChannels(take_pcm_source);
  samples_per_channel = 1;
  offs = GetCursorPosition() - item_pos;

  take != last_take ? (
    take_pcm_source = GetMediaItemTake_Source(take);
    //GetMediaSourceType(take_pcm_source, #typebuf);
    sample_rate = GetMediaSourceSampleRate(take_pcm_source);
    num_channels = GetMediaSourceNumChannels(take_pcm_source);
    last_accessor > 0 ? DestroyAudioAccessor(last_accessor);
    last_accessor = CreateTakeAudioAccessor(take);
    last_offs = -100000000.0;
    last_take = take;  
    x = GetCursorPosition(); 
  );

  AudioAccessorValidateState(last_accessor) || offs != last_offs ? (
    memset(buffer, 0, samples_per_channel*num_channels);
    nsret = last_accessor > 0 ? (GetAudioAccessorSamples(last_accessor,sample_rate,num_channels,offs,samples_per_channel,buffer) > 0 ? samples_per_channel : 0) : 0;
    i = 0;
    nsret > 0 ? (
      chan_1 = 20 * log10(abs(buffer[0]));
      num_channels == 2 ? chan_2 = 20 * log10(abs(buffer[1]));
    diff = abs(chan_1)-abs(chan_2);
    );
    last_offs=offs;
  );
);


function get_take()
(
  (item = GetSelectedMediaItem(0, 0)) ? (
    item_pos = GetMediaItemInfo_Value(item, "D_POSITION");
    (take = GetActiveTake(item)) ? (
      get_samples_at_cursor(take);
    );
  );
);

function init(window_w, window_h)
(
  //gfx_a = 1; gfx_r = 1; gfx_g = 1; gfx_b = 1;
  gfx_init("dB display", window_w, window_h);
  gfx_setfont(1, font_name, font_size);
);

function run() local(time_range, time_sel_start, time_sel_end)
(
  gfx_a = 0.5; gfx_r = 1; gfx_g = 1; gfx_b = 1;
  gfx_x = 10;
  gfx_y = 10;

  get_take();
  
  gfx_a = 0.5;
  gfx_printf("chan 1 ");
  gfx_a = 1;
  gfx_drawnumber(chan_1,16);
  
  num_channels == 2 ? (
    gfx_a = 0.5;
    gfx_x = 10;
    gfx_y += gfx_texth;
    gfx_printf("chan 2 ");
    gfx_a = 1;
    gfx_drawnumber(chan_2,16);
    
    gfx_x = 10;
      gfx_y += gfx_texth;
     gfx_a = 0.5;
      gfx_printf("diff ");
      gfx_a = 1;
      gfx_drawnumber(diff,16);
  );
  
  gfx_update();
  gfx_getchar() >= 0 ? defer("run();");
);

//init(window_w, window_h);
init(300, 100);
run();
*and for bonus points...is there a way to get the returned value as "text" i can cut and paste ? aside from opening the editor and taking it from the side, which is not full resolution. ?
__________________
I like turtles
bezusheist is offline   Reply With Quote
Old 02-19-2022, 10:05 AM   #227
Sima
Human being with feelings
 
Join Date: Feb 2021
Posts: 3
Default

How do I manage to reorder multiple midi-items on different tracks (one item per track) to a new track, but all the midi-items on the new track one after another?
Sima is offline   Reply With Quote
Old 02-26-2022, 05:30 AM   #228
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 451
Default

Quote:
Originally Posted by bezusheist View Post
i found this script a few years back, but it doesn't seem to work correctly (now?). ie..it returns several different values when clicking on the same sample. i think i messed it up when i was trying to customize it. could someone take a look at it and maybe set me straight here ?
thanks...

I ran the script and it seems to work as expected giving a dB display. Where does it go wrong? Would be good to use the same sample.


There has been a change with cursor positioning in EEL. If the cursor is offset to a calculated position and read back the reading can differ. But that script only reads cursor. However for reference check below:

https://forum.cockos.com/showthread.php?t=261834





Quote:
*and for bonus points...is there a way to get the returned value as "text" i can cut and paste ? aside from opening the editor and taking it from the side, which is not full resolution. ?
Yes you can output it using ShowConsoleMsg(). You can use ClearConsole() first if you don't want the text to fill the window. You can then drag and copy from the window. For an example see this script I wrote to output cursor position.

Code:
// Show cursor time in seconds.

function main()
(
  Cursor = GetCursorPosition();
  sprintf(#Msg, "Cursor Time: %f\n", Cursor);
  ShowConsoleMsg(#Msg);
);

main();
Hypex is offline   Reply With Quote
Old 07-05-2022, 09:54 PM   #229
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

Hi guys. Why is my script not working correctly?

Task: deselect the item if it is the only one on the track in the selected area. The script works correctly only if there are no other items on the track, outside the select area. But, if there is, then the script takes them into account too. Although, by design, it should only perceive what is in the selected area (or selected items.)

What's my mistake?



Code and test project:

Code:
r.Main_OnCommand(40296, 0)  -- select all tracks
r.Main_OnCommand(40290, 0) -- selection by items

start, ending = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 )

selected_tracks_count = reaper.CountSelectedTracks(0)

for i = 0, selected_tracks_count-1  do

    track = reaper.GetSelectedTrack(0, i) -- Get selected track i
        track_items_count = reaper.CountTrackMediaItems(track)

    for j = 0, track_items_count-1  do

           item = reaper.GetTrackMediaItem(track, j) -- Get selected item i
               if item then;
                      sel = reaper.IsMediaItemSelected(item)
                    if sel == true then
                      item_pos =  r.GetMediaItemInfo_Value( item, 'D_POSITION' )
                      item_length = r.GetMediaItemInfo_Value( item, 'D_LENGTH' )
                      item_end = item_pos + item_length
                      
                      if track_items_count == 1 then
                            if (item_pos >= start and item_pos <= ending) or (item_end <= ending and item_end >= start) or (item_pos < start and item_end > ending) then
                                  r.SetMediaItemSelected(item, false)
                            end
                      end
                 end
             end
         end

end

r.Main_OnCommand(40635, 0) -- remove selection

r.UpdateArrange()
Attached Files
File Type: rpp Test_Proj.rpp (7.7 KB, 58 views)

Last edited by cool; 07-05-2022 at 10:08 PM.
cool is offline   Reply With Quote
Old 07-07-2022, 12:47 AM   #230
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

Okay, I've made some progress, but the code still doesn't work correctly.

Now the selection is deselected if only one item on the track is selected. This is how it was intended. But the code works correctly only if items on only one track are selected. I don't understand why it doesn't work. If I select items on all tracks, then the items from these tracks are summed up (all are taken into account at the same time), but an individual pass through the tracks is not performed. Why?

I removed the area selection check to simplify the code.

Let me remind you of my goal: If there is only one selected item on the track, the selection should be removed. If multiple tracks are selected, the script should go through each track individually and deselect the single item on each track.

Code:
r.Main_OnCommand(40296, 0)  -- select all tracks

selected_tracks_count = reaper.CountSelectedTracks(0)

for i = 0, selected_tracks_count-1  do

    track = reaper.GetSelectedTrack(0, i) -- Get selected track i
        track_items_count = reaper.CountTrackMediaItems(track)
        items_count = reaper.CountSelectedMediaItems(0)

    for j = 0, track_items_count-1  do
           item = reaper.GetSelectedMediaItem(0, j) -- Get selected item i
               if item then
                      if items_count == 1 then
                                  r.SetMediaItemSelected(item, false)
                      end
                end
         end

end

r.UpdateArrange()
cool is offline   Reply With Quote
Old 07-07-2022, 06:48 AM   #231
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,913
Default

Quote:
Originally Posted by cool View Post
If there is only one selected item on the track, the selection should be removed.
Not sure I follow but I think you need to make a function to get number of selected items on a track, do something if only one selected item, etc, something like,..

Code:
function IsOneSelectedMediaItem(track)
  local sel_count, index = 0,0
  for i = 0, reaper.CountTrackMediaItems(track)-1 do
    if reaper.IsMediaItemSelected(reaper.GetTrackMediaItem(track, i)) then 
      sel_count = sel_count + 1
      if sel_count > 1 then return end
      index = i
    end 
  end
  if sel_count == 1 then return reaper.GetTrackMediaItem(track, index) end
end

r = reaper
r.Main_OnCommand(40296, 0)  -- select all tracks
selected_tracks_count = reaper.CountSelectedTracks(0)

for i = 0, selected_tracks_count-1  do
  local track = reaper.GetSelectedTrack(0, i)
  local item = IsOneSelectedMediaItem(track)
  if item then  r.SetMediaItemSelected(item, false) end
end

r.UpdateArrange()
Edgemeal is offline   Reply With Quote
Old 07-07-2022, 09:05 AM   #232
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 957
Default

Quote:
Originally Posted by Edgemeal View Post
Not sure I follow but I think you need to make a function to get number of selected items on a track, do something if only one selected item, etc, something like,..

Stunned! Works flawlessly, thanks!
cool is offline   Reply With Quote
Old 09-13-2022, 12:47 PM   #233
DrakeSoft
Human being with feelings
 
Join Date: Feb 2020
Posts: 21
Default reaper.MIDIEditor_GetActive() return nil in interactive window

Hi,
I am just getting started with Reascript and lua programming.

I opened an interactive reascript shell, recorded a midi track and then tried to learn by playing around with that track; However, reaper.MIDIEditor_GetActive() always returns nil when I run the command in that window.

```lua
> local hwnd = reaper.MIDIEditor_GetActive()
nil
>
```

I have been able to run other commands like those in this tutorial https://admiralbumblebee.com/music/2...-Tutorial.html, but this is my first time interacting with the midi editor. Do I need to do something else before I can use the cfillion interactive shell with the midi editor?
DrakeSoft is offline   Reply With Quote
Old 09-15-2022, 08:58 AM   #234
DrakeSoft
Human being with feelings
 
Join Date: Feb 2020
Posts: 21
Default It appears to be an issue with how I open things

If I launch the interactive console and then afterwards launch the midi editor everything works fine. If after opening Reaper I first launch the midi editor and then launch the console it does not find the midi editor. I don't know why.
DrakeSoft is offline   Reply With Quote
Old 11-21-2022, 07:14 AM   #235
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 451
Default When gfx_getchar() doesn't

Hi. So was testing out gfx_getchar() and the useful function of testing a char. But it doesn't work with all codes.



This works:
Code:
gfx_getchar(27)
This doesn't:
Code:
gfx_getchar(13)
I can of course still check the return code. But is there any reason why gfx_getchar(27) returns positive if Esc is pressed but gfx_getchar(13) doesn't return positive when Return is pressed? At least on Linux.
Hypex is offline   Reply With Quote
Old 11-21-2022, 09:40 AM   #236
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Hmm, does it return 13 when using the return value?
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 11-22-2022, 02:01 AM   #237
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 451
Default

Yes it does return 13 as value if return key is pressed and it is called as gfx_getchar().


When I called it as gfx_getchar(13) I kept getting back 0 even when return was pressed.


That's what I meant to say instead of confusing it with code tags. I spent a little time trying to figure out why it wasn't picking up return but was picking up Esc. I couldn't see what I had done wrong. :-)
Hypex is offline   Reply With Quote
Old 08-12-2023, 12:45 AM   #238
Rumi
Human being with feelings
 
Join Date: Jul 2012
Location: Winterthur, Switzerland
Posts: 61
Default Script to align phase of two items in a crossfade

I am scripting a tool to prepare samples for a sample library. I am at the stage of preparing loops.

I need a way to phase align the waveform of two crossfaded items. The second item is a duplicate of the first item, moved some seconds.

So the note is the same, and the waveform should at least look similar, and it has the same frequency.

How can I align the audio phase of these two items with a lua script?

The idea I had so far is to measure and store some zero crossing points, and compare them, and then move the second item accordingly. It would be good to also measure the sample values a bit after the zero crossing, in order to see whether the waveform gets positive or negative (to avoid a polarity flip in a symmetrical waveform).

But maybe my approach is totally off, and there's a much better approach?

And if it's the right way, how do I measure these things? What I've found so far is GetCursorPosition(), but no way to measure waveform values.
Rumi is offline   Reply With Quote
Old 08-14-2023, 11:53 AM   #239
DreamDisease
Human being with feelings
 
Join Date: Jun 2017
Posts: 248
Default

I'm a noob at scripting but I'm trying to learn, and I've been able to read through some peoples' scripts that I use often, and I mostly understand them, but why do people use local on things that aren't variables inside functions? What's that do?

So far I understand that local restricts the scope to being defined only while in a function, but I'm seeing variables and even functions being defined as local out in the main code. Why? I'm also noticing the little sidebar does not track those variables at all. Only ones without local.

Also, when they use "_" or "__" as a variable name it normally means "not important, throwaway variable for collecting info I'm either forced to because its part of a pair of param arguments, or only need for a second to get another more important value" right?

Also also how do I make the reaper IDE step through code so it doesn't run it all at once and I can see how the variables are changing in real time before continuing? And is it possible to manually change a variable in the sidebar for debugging?
__________________
You got the music in you

Last edited by DreamDisease; 08-14-2023 at 12:00 PM.
DreamDisease is offline   Reply With Quote
Old 08-14-2023, 12:56 PM   #240
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Quote:
Originally Posted by DreamDisease View Post
I'm a noob at scripting but I'm trying to learn, and I've been able to read through some peoples' scripts that I use often, and I mostly understand them, but why do people use local on things that aren't variables inside functions? What's that do?

So far I understand that local restricts the scope to being defined only while in a function, but I'm seeing variables and even functions being defined as local out in the main code. Why?
It's slightly faster. It's also good practice to local everything that isn't really meant as global. So if you local everything, you get into the habit of doing it and think more intensively, whether something really should be global.
Having things accidentally global that should be local instead is a common source of bugs.

Quote:
I'm also noticing the little sidebar does not track those variables at all. Only ones without local.
That's right, the watchlist only shows global variables and functions.
Quote:
Also, when they use "_" or "__" as a variable name it normally means "not important, throwaway variable for collecting info I'm either forced to because its part of a pair of param arguments, or only need for a second to get another more important value" right?
Yeah, it's a convention to signal, that that return value isn't used later in the code and can be dumped into a variable called _
It's also valid to name it properly.
I personally tend to give it proper names, in the event that I need it later without knowing yet, but it's personal preference.
So if you use _ as variablename for unneeded returnvalues, you can do it.

You can't omit it, though. If a function returns multiple values, they will be returned in the order coded into the function. So if you need to use the third return value but not the first and second, you simply put them into _

Code:
_, _, needed_value = my_function()
is valid code in that case.
Quote:
Also also how do I make the reaper IDE step through code so it doesn't run it all at once and I can see how the variables are changing in real time before continuing? And is it possible to manually change a variable in the sidebar for debugging?
You can't. It doesn't support debugger breakpoints. However, you can stop the code earlier by adding a line like:

Code:
if tudelu==nil then return end
into the code. It will stop execution at this point, as long as variable tudelu isn't used and therefore contains the non-value nil.

Edit:
and no, you can't change a variable in the watchlist for debugging. Only in the code.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine 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 03:43 PM.


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