Old 06-16-2022, 10:09 AM   #961
chmaha
Human being with feelings
 
chmaha's Avatar
 
Join Date: Feb 2021
Posts: 2,261
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
You just need a function that enumerates through all marker-names and ignore those, who don't fit the naming-scheme.
This should give you the id over all markers(not the shown one but the one in timeline order).
Then you delete it.
This is where the problems started for me. I did just that but for some reason REAPER doesn't like two with the same ID and even when using the timeline order ID the cursor always goes to the instance first in the timeline. Otherwise, I thought I had cracked the nut
__________________
ReaClassical -- Open Source Classical Music Editing Tools for REAPER | Donate via PayPal, Liberapay or Stripe
airwindows JSFX ports | Debian & Arch Pro Audio Guides
chmaha is offline   Reply With Quote
Old 06-16-2022, 11:25 AM   #962
nscotto
Human being with feelings
 
Join Date: Jul 2020
Posts: 84
Default How do I wait until a plugin window is actually on the screen after opening it?

Hi,


Hi,

I'd like to open a plugin and take a screenshot of it from a script, however it seems that the screenshot is going faster than the rendering of the plugin so I am looking for a solution to wait until it is rendered.


I am not sure whether it is possible to actually know precisely when the plugin window has finished rendering on the screen - and if it's not then that's fine as long as I can at least wait a little time.
The problem is... on my system there is no os.sleep.


Here is a snippet:
Code:
  local trackidx = reaper.CountTracks(0)
  reaper.InsertTrackAtIndex(trackidx, true)
  local track = reaper.GetTrack(0, trackidx)
  local fxidx = reaper.TrackFX_GetByName(track, fxname, true)
  reaper.TrackFX_Show(track, fxidx, 3)
  hwnd = reaper.TrackFX_GetFloatingWindow(track, fxidx)
  -- CapWindowToIcon is using JS_LICE api to capture a screenshot of the window
  CapWindowToIcon(hwnd, path)
  reaper.DeleteTrack(track)

Last edited by nscotto; 06-16-2022 at 02:49 PM.
nscotto is offline   Reply With Quote
Old 06-23-2022, 08:59 AM   #963
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 BethHarmon View Post
This is where the problems started for me. I did just that but for some reason REAPER doesn't like two with the same ID and even when using the timeline order ID the cursor always goes to the instance first in the timeline. Otherwise, I thought I had cracked the nut
Sorry for the long delay in answering. Had some private stuff to deal with.

Did you find a solution meanwhile? If not, I thought about the issue for some time and might have two ways of approaching it, depending on the "robustness" you need. So if you still need some help, I write the two approaches down for you and I try to come up with some code-examples on how you could approach it.
__________________
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 06-23-2022, 09:02 AM   #964
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 nscotto View Post
Hi,


Hi,

I'd like to open a plugin and take a screenshot of it from a script, however it seems that the screenshot is going faster than the rendering of the plugin so I am looking for a solution to wait until it is rendered.


I am not sure whether it is possible to actually know precisely when the plugin window has finished rendering on the screen - and if it's not then that's fine as long as I can at least wait a little time.
The problem is... on my system there is no os.sleep.


Here is a snippet:
Code:
  local trackidx = reaper.CountTracks(0)
  reaper.InsertTrackAtIndex(trackidx, true)
  local track = reaper.GetTrack(0, trackidx)
  local fxidx = reaper.TrackFX_GetByName(track, fxname, true)
  reaper.TrackFX_Show(track, fxidx, 3)
  hwnd = reaper.TrackFX_GetFloatingWindow(track, fxidx)
  -- CapWindowToIcon is using JS_LICE api to capture a screenshot of the window
  CapWindowToIcon(hwnd, path)
  reaper.DeleteTrack(track)

From my guts: you get the hwnd of the focused window. If that matches the hwnd of the floating window, you wait some more, then take a screenshot.

To wait, you can try out defer-cycles, as any kind of a sleeping function(if existing) would delay the redrawing of the ui and therefore, you could wait forever, until you could get the screenshot, as the redraw would always happen after your screenshot.
So using defer circumvents the issue usually.

Here's my introduction to defer:
https://forum.cockos.com/showpost.ph...2&postcount=21
__________________
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 06-23-2022, 09:30 AM   #965
chmaha
Human being with feelings
 
chmaha's Avatar
 
Join Date: Feb 2021
Posts: 2,261
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
Sorry for the long delay in answering. Had some private stuff to deal with.

Did you find a solution meanwhile? If not, I thought about the issue for some time and might have two ways of approaching it, depending on the "robustness" you need. So if you still need some help, I write the two approaches down for you and I try to come up with some code-examples on how you could approach it.
No solution as yet and grateful for any assistance...
__________________
ReaClassical -- Open Source Classical Music Editing Tools for REAPER | Donate via PayPal, Liberapay or Stripe
airwindows JSFX ports | Debian & Arch Pro Audio Guides
chmaha is offline   Reply With Quote
Old 06-24-2022, 03:44 PM   #966
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 BethHarmon View Post
No solution as yet and grateful for any assistance...
Ok, just to make sure that I got all the facts right and some assumptions I made from your description(correct me where I am wrong):

1.You want to add some markers on your own by your scripts. You want to be able to affect only them and ignore all other markers created by the user, no matter, how the user names them or indexes them.

2.You want to use the shown index-number as additional information, like: DEST-IN with index 2 is related to DEST-OUT with index 2, so you know, that they belong to each other.
And when deleting the two, you don't want to affect other markers with index 2. Not even, if the user named them DEST-IN or DEST-OUT.
__________________
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 06-25-2022, 12:12 PM   #967
chmaha
Human being with feelings
 
chmaha's Avatar
 
Join Date: Feb 2021
Posts: 2,261
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
Ok, just to make sure that I got all the facts right and some assumptions I made from your description(correct me where I am wrong):

1.You want to add some markers on your own by your scripts. You want to be able to affect only them and ignore all other markers created by the user, no matter, how the user names them or indexes them.

2.You want to use the shown index-number as additional information, like: DEST-IN with index 2 is related to DEST-OUT with index 2, so you know, that they belong to each other.
And when deleting the two, you don't want to affect other markers with index 2. Not even, if the user named them DEST-IN or DEST-OUT.
1 you have exactly right. 2 is partly right. DEST-IN and DEST-OUT only ever have the marker IDs 100 and 101 respectively. So, yes, when deleting them, I don't want to affect other markers that potentially have IDs of 100 or 101. Same for SOURCE-IN and OUT with marker IDs 102 and 103. I care less about the situation when users have named them DEST-IN, for example. That would just be, well, dumb of them Plus, the chances of that happening are close enough to 0 that it's not worth worrying about.

Feel free to raise it as an issue in my github repo: https://github.com/ElizabethHarmon/R...ssical-Editing if it's easier for us to keep track of.
__________________
ReaClassical -- Open Source Classical Music Editing Tools for REAPER | Donate via PayPal, Liberapay or Stripe
airwindows JSFX ports | Debian & Arch Pro Audio Guides

Last edited by chmaha; 06-25-2022 at 03:16 PM.
chmaha is offline   Reply With Quote
Old 07-08-2022, 07:50 AM   #968
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Ok, after yet another delay, here's finally my proposal.

My idea is basically to not use the shown-index or anything else marker-related to differentiate between your markers and the markers created by the user.
In fact, I propose, that you store a ProjExtState for a marker, that holds, if the marker has been created by you or not.

So you create a marker, add an extstate of it that says "created by me".
And when you want to alter/delete the marker, you reread the extstate and check, if it's "created by me" and if yes, alter the marker, if no, do nothing.
I'll employ marker-guids in this, that are unique identifiers for a marker/region that never changes, no matter what the user does to the marker(aside from deleting).


For this, you need three functions to do it:

First, a proper add-projectmarker function. Use this one, as this not only returns the shown index, but also the index in timeline order(we'll need this) and the marker/region-guid. It also fixes some edge-case issues with Reaper's own AddProjectMarker-function:

Code:
function AddProjectMarker(proj, isrgn, pos, rgnend, name, wantidx, color)
--[[
  Description:
        Creates a new projectmarker/region and returns the shown number, index and guid of the created marker/region. 

  Retvals:
        integer index - the shown-number of the newly created marker/region
        integer marker_region_index - the index of the newly created marker/region within all markers/regions
        string guid - the guid of the newly created marker/region

  Parameters:
        ReaProject proj - the project, in which to add the new marker; use 0 for the current project; 
        boolean isrgn - true, if it shall be a region; false, if a normal marker
        number pos - the position of the newly created marker/region in seconds
        number rgnend - if the marker is a region, this is the end of the region in seconds
        string name - the shown name of the marker
        integer wantidx - the shown number of the marker/region. Markers can have the same shown marker multiple times. Regions will get another number, if wantidx is already given.
        integer color - the color of the marker
--]]

  -- add a marker AFTER the current last marker(makes finding Guid for it faster)
  local shown_number=reaper.AddProjectMarker2(proj, isrgn, reaper.GetProjectLength()+100, reaper.GetProjectLength()+100, name, wantidx, color)
  
  -- get the guid of the new last marker
  local retval, Guid = reaper.GetSetProjectInfo_String(proj, "MARKER_GUID:"..reaper.CountProjectMarkers(proj)-1, "", false)

  -- change position to the actual position of the marker
  local LastMarker2={reaper.EnumProjectMarkers3(proj, reaper.CountProjectMarkers(proj)-1)} -- get the current shown marker-number
  reaper.SetProjectMarkerByIndex2(proj, reaper.CountProjectMarkers(proj)-1, isrgn, pos, rgnend, LastMarker2[6], name, color, 0)
  
  -- find the index-position of the marker by its Guid
  for i=0, reaper.CountProjectMarkers() do
    local retval2, Guid2 = reaper.GetSetProjectInfo_String(proj, "MARKER_GUID:"..i, "", false)
    if Guid2==Guid then found_marker_index=i break end
  end
  
  return shown_number, found_marker_index, Guid
end
Then we need two functions, one for storing and one for getting the extstate for a marker/region. They use marker-guids to make the magic happen:

Set MarkerExtState:
Code:
function SetMarkerExtState(markerindex, section, key, value)
--[[
  Description:
    Stores an extstate, associated with a certain marker/region
  
  Retval:
    integer retval - the number of key/value-pairs in this section
    
  Parameters:
    integer markerindex - the marker/region-index in timeline order(NOT the shown index!)
    string section - a section, in which to store the key-value
    string key - the name of the key
    string value - the value to store
--]]
  -- get marker-guid
  local A,B=reaper.GetSetProjectInfo_String(0, "MARKER_GUID:"..markerindex, "", false)
  
  -- store projextstate
  return reaper.SetProjExtState(0, B.."_"..section, key, value)
end
Get MarkerExtState:
Code:
function GetMarkerExtState(markerindex, section, key)
--[[
  Description:
    Gets a stored extstate, associated with a certain marker/region
  
  Retval:
    string value - the value stored
    
  Parameters:
    integer markerindex - the marker/region-index in timeline order(NOT the shown index!)
    string section - a section, from which to get the key-value
    string key - the name of the key
--]]
  -- get the marker/region-guid
  local A,B=reaper.GetSetProjectInfo_String(0, "MARKER_GUID:"..markerindex, "", false)
  
  -- get the stored extstate
  return reaper.GetProjExtState(0, B.."_"..section, key)
end

With these three functions, we can make robust marker-management happen.


The following code-example adds a new DEST-IN-marker at editcursor-position and stores in the back, that it has been created by this script:

Code:
function AddProjectMarker(proj, isrgn, pos, rgnend, name, wantidx, color)
  -- add a marker AFTER the current last marker(makes finding Guid for it faster)
  local shown_number=reaper.AddProjectMarker2(proj, isrgn, reaper.GetProjectLength()+100, reaper.GetProjectLength()+100, name, wantidx, color)
  
  -- get the guid of the new last marker
  local retval, Guid = reaper.GetSetProjectInfo_String(proj, "MARKER_GUID:"..reaper.CountProjectMarkers(proj)-1, "", false)

  -- change position to the actual position of the marker
  local LastMarker2={reaper.EnumProjectMarkers3(proj, reaper.CountProjectMarkers(proj)-1)} -- get the current shown marker-number
  reaper.SetProjectMarkerByIndex2(proj, reaper.CountProjectMarkers(proj)-1, isrgn, pos, rgnend, LastMarker2[6], name, color, 0)
  
  -- find the index-position of the marker by its Guid
  local found_marker_index="Buggy" -- debugline, hope it never gets triggered
  for i=0, reaper.CountProjectMarkers() do
    local retval2, Guid2 = reaper.GetSetProjectInfo_String(proj, "MARKER_GUID:"..i, "", false)
    if Guid2==Guid then found_marker_index=i break end
  end
  
  return shown_number, found_marker_index, Guid
end

function SetMarkerExtState(markerindex, section, key, value)
  -- get marker-guid
  local A,B=reaper.GetSetProjectInfo_String(0, "MARKER_GUID:"..markerindex, "", false)
  
  -- store projextstate
  return reaper.SetProjExtState(0, B.."_"..section, key, value)
end



-- get current editcursor-position
position=reaper.GetCursorPosition()

-- add DEST-IN-marker at this position
shownindex, marker_index_timeline_order, guid = AddProjectMarker(0, false, position, 0, "DEST-IN", -1, 0)

-- store, that it has been stored by this script and that it's a DEST-IN-marker
SetMarkerExtState(marker_index_timeline_order, "Beth Harmons Markers", "Created by my scripts?", "Yes")
SetMarkerExtState(marker_index_timeline_order, "Beth Harmons Markers", "Type", "DEST-IN")
The following script will delete the next marker right of the editcursor, but only, if it's a DEST-IN-marker stored by the first script.
Otherwise, it'll leave the marker untouched(hope I didn't miss an edge-case).
It doesn't matter, if the user renamed the marker, it will delete it anyway(you can adapt the part where I stored the type as marker-extstate to use the marker-name instead).

Code:
function SetMarkerExtState(markerindex, section, key, value)
  -- get marker-guid
  local A,B=reaper.GetSetProjectInfo_String(0, "MARKER_GUID:"..markerindex, "", false)
  
  -- store projextstate
  return reaper.SetProjExtState(0, B.."_"..section, key, value)
end

function GetMarkerExtState(markerindex, section, key)
  -- get the marker/region-guid
  local A,B=reaper.GetSetProjectInfo_String(0, "MARKER_GUID:"..markerindex, "", false)
  
  -- get the stored extstate
  return reaper.GetProjExtState(0, B.."_"..section, key)
end


-- get editcursor-position
position=reaper.GetCursorPosition()

-- find the index of the next marker right of the edit-cursor
found_marker=-1
for i=0, reaper.CountProjectMarkers(0) do
  index, region, pos, _, name = reaper.EnumProjectMarkers(i)
  if pos>position then 
    found_marker=i
    break
  end
end


if found_marker>-1 then
  -- get, if the marker had been created by your scripts
  _, Created=GetMarkerExtState(found_marker, "Beth Harmons Markers", "Created by my scripts?")
  _, Type=GetMarkerExtState(found_marker, "Beth Harmons Markers", "Type")

  -- if yes:
  if Created=="Yes" and Type=="DEST-IN" then
     -- remove stored extstates to not bloat projects
     SetMarkerExtState(found_marker, "Beth Harmons Markers", "Created by my scripts?", "")
     SetMarkerExtState(found_marker, "Beth Harmons Markers", "Type", "")
     
     -- delete marker
     reaper.DeleteProjectMarkerByIndex(0, found_marker)
  end
end

With this, you would only affect markers created by you and completely ignore any other marker created by the user, which is probably the safest way to do it.
And your markers can still be found out by you by checking their marker-extstates, no matter if the user changed any attribute of a marker(unless they remove it).
Hope this solves your issue.

Sorry that it took yet another long delay for my answer to appear. Had to go to the hospital last week and therefore was not being able to code/write anything(though I had it fleshed out last week already).
It's as if reality tries to prevent me from helping you, but "HAH! Not with me, reality! Not with me"

Anyway, going into recovery over the next few weeks, so I'm not here during that time, but if you need help with this, have questions or need some kind of assistance,
best is to ask XRaym, as he knows markers and marker-guids inside out as well, he should be able to get easily, what I was after and help with any questions.

Ok, back to recovery...hope I didn't miss something...
__________________
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-08-2022, 09:02 AM   #969
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Quote:
best is to ask XRaym, as he knows markers and marker-guids inside out as well,

@BethHarmon
Just in case, I wrote some doc about the Markers indexes:


https://github.com/ReaTeam/Doc/blob/...d%20regions.md


Maybe it can somehow be helpful in some way ^^
X-Raym is offline   Reply With Quote
Old 08-10-2022, 12:31 PM   #970
adu89
Human being with feelings
 
Join Date: Mar 2019
Posts: 8
Default Render settings dirty state.

Is it possible to know if the render dialog is in a dirty state via c++? I'm building and extension in c++ that depends on some render settings information. The extension polls the render settings and presents some information real time. I'd like to warn the user in the case that they changed some render settings but didn't save them.
adu89 is offline   Reply With Quote
Old 08-12-2022, 05:16 PM   #971
sonictim
Human being with feelings
 
sonictim's Avatar
 
Join Date: Feb 2020
Location: Los Angeles
Posts: 463
Default

If I adjust the playrate via config variables (SNM_SetDoubleConfigVar)... How do I get the Transport to visually update showing the change? UpdateTimeline() and UpdateArrange() don't seem to be doing the trick...

Thanks for your help!
__________________
My Reapack Repository: I write scripts for my own personal use.
I offer no support, but if you find one that helps you, go for it!
sonictim is offline   Reply With Quote
Old 08-12-2022, 06:02 PM   #972
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
Default

Quote:
Originally Posted by sonictim View Post
If I adjust the playrate via config variables (SNM_SetDoubleConfigVar)... How do I get the Transport to visually update showing the change? UpdateTimeline() and UpdateArrange() don't seem to be doing the trick...

Thanks for your help!
You can also adjust it via CSurf_OnPlayRateChange which does visually update, if that helps.
nofish is offline   Reply With Quote
Old 08-12-2022, 10:16 PM   #973
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Jazzy
Use js_reascriptAPI extension in this case, it can parse reaper windows, and you can display xommand id in a coluln, and get listitems selected in a listview.
X-Raym is offline   Reply With Quote
Old 08-13-2022, 06:10 AM   #974
sonictim
Human being with feelings
 
sonictim's Avatar
 
Join Date: Feb 2020
Location: Los Angeles
Posts: 463
Default

Quote:
Originally Posted by nofish View Post
You can also adjust it via CSurf_OnPlayRateChange which does visually update, if that helps.
I was using that originally, but it adds an undo point. My script sets playback rate to half speed then immediately returns the play rate to its previous setting upon stop. So I end up with 2 undo points every time I run it which aren’t really necessary in the grand scheme of things. My script is a great way to check sync of sound fx, but with 2 undos being generated every time I was using my script to check sync, it became cumbersome. Which is why I switched to the adjust “play rate” config var. no undos, but no visual feedback.

And now I’m just curious… is there a way to update the transport?
__________________
My Reapack Repository: I write scripts for my own personal use.
I offer no support, but if you find one that helps you, go for it!
sonictim is offline   Reply With Quote
Old 08-25-2022, 10:55 AM   #975
smithoid
Human being with feelings
 
Join Date: Apr 2016
Posts: 19
Default Calling API with EEL2 script

Probably being really stupid here...
I want to call EnumProjects so as to detect a change of project tab.
I thought this should work with EEL2 scripting under @block section:

tab = EnumProjects(-1, '');

I was expecting the call to return a number representing the active tab... then I can detect change of tab and run a refresh to my custom midi controller. Instead I get "undefined" and other errors as I play with the syntax.
All the other code works great and I love the scripting environment :-)
Thanks in advance for any help!
All the best
Paul
smithoid is offline   Reply With Quote
Old 08-26-2022, 07:04 AM   #976
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 smithoid View Post
Probably being really stupid here...
I want to call EnumProjects so as to detect a change of project tab.
I thought this should work with EEL2 scripting under @block section:

tab = EnumProjects(-1, '');

I was expecting the call to return a number representing the active tab... then I can detect change of tab and run a refresh to my custom midi controller. Instead I get "undefined" and other errors as I play with the syntax.
All the other code works great and I love the scripting environment :-)
Thanks in advance for any help!
All the best
Paul


I wrote two snippets, that show you, how to do such things.

The first one demonstrates, how to find out, if the currently active project-tab has changed and shows a messagebox in this case.
It's running permanently using a defer-loop.

Code:
function main()(
  // get the current tab
  NewProjectTab=EnumProjects(-1);
  
  // check, if the new-tab is the same as,
  // the old tab and if not show a messagebox
  NewProjectTab!=OldProjectTab ? (
    MB("Tab has changed", "Changed", 0);
  );
  
  //remember current tab for next defer-loop
  OldProjectTab=NewProjectTab; 

  // restart the loop to repeat the checking again
  defer("main()")
);


// initialize value, so the script doesn't begin
// with a "oh, tab has changes"-messagebox
OldProjectTab=EnumProjects(-1);
main();

And just for fun, I wrote a function, that returns the index of the currently active project-tab:
Code:
function GetCurrentProjectTab() 
  /* return the index of the currently active project-tab,
     starting with 0 for the first one
     Meo-Ada Mespotine - licensed under MIT-license*/

  // make internally used variables local, so they will not be 
  // accidentally overwritten by other code
  local (ProjectTab) 
  local (index) 
  (
  ProjectTab=EnumProjects(-1); // get project in active tab
  index=0; // count-variable for the next loop
  
  // check, if any of the enumerable projects 
  // are the same as the currently active one
  // if yes, end the loop and return its index
  while(EnumProjects(index)!=ProjectTab)(
    index=index+1;
  );
  index; // return the index after loop ended
);

A2=GetCurrentProjectTab();
So if you prefer working with the projecttab-index instead, this might help you a little to get it going.
__________________
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 08-27-2022, 12:40 AM   #977
smithoid
Human being with feelings
 
Join Date: Apr 2016
Posts: 19
Default

Hi
Thanks for the response!
I tried cut-and-pasting your complete second clip into my code (next to my other functions in @init section) and this is what I got on compiling:

@init:77 'EnumProjects'.undefined: 'ProjectTab= <!> EnumProjects(-1);

I didn't even call the function.
Any thoughts?
Really appreciate your help
All the best
Paul
smithoid is offline   Reply With Quote
Old 08-27-2022, 05:14 AM   #978
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Ahh, you were trying to do JSFX, not ReaScript(missed that in your first post). Jsfx don't support ReaScript functions so this will not work.
The only stuff accepted for JSFX is described here:
https://www.reaper.fm/sdk/js/js.php
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...

Last edited by Meo-Ada Mespotine; 08-27-2022 at 05:28 AM.
Meo-Ada Mespotine is offline   Reply With Quote
Old 08-28-2022, 05:40 AM   #979
smithoid
Human being with feelings
 
Join Date: Apr 2016
Posts: 19
Default

Hi
Thanks for the info. I thought from the API documentation that I should be able to make the call in EEL2 but obviously not!
So, am now trying a different tack....
I have a homemade midi controller and have set up a "scene" type arrangement in JS for live performance (happy to share when it's all sorted if anyone interested). The missing piece of the puzzle is loading each song as required. I should add that Reaper is running "headless" and all I can see are LED's on the (wireless) midi controller.
Project tabs seemed the way to go but I am now thinking about a complete new project load for each song with no project tabs. So my question:

Is there a way of scripting a full project load? I can name the projects 1.rpp, 2.rpp etc. I would send a midi note to trigger the load, e.g. note 48 opens 1.rpp, 49 opens 2.rpp etc. I have been looking at actions (including SWS) but can only get as far as opening the windows-load-project dialogue box. Maybe there is some way of "faking" keypresses to select from the files? I've spent the last few hours looking to no avail :-(
Thanks in advance for any help
All the best
Paul
smithoid is offline   Reply With Quote
Old 08-28-2022, 06:49 AM   #980
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
Default

@smithoid
Not a direct answer to your question, but have you seen cfillion's song switcher? Maybe an alternative?
https://forum.cockos.com/showthread.php?t=181159
nofish is offline   Reply With Quote
Old 08-28-2022, 07:36 AM   #981
smithoid
Human being with feelings
 
Join Date: Apr 2016
Posts: 19
Default

No I hadn't seen... cheers for that :-)
Looks like it uses a folder for each song? Could get messy with a big set?
I will experiment.
Still keen to try and load a complete project if anyone has any ideas?
Thanks!
Paul
smithoid is offline   Reply With Quote
Old 08-28-2022, 07:55 AM   #982
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
Default

Quote:
Originally Posted by smithoid View Post
Still keen to try and load a complete project if anyone has any ideas?
With ReaScript Main_openProject.
nofish is offline   Reply With Quote
Old 08-28-2022, 09:43 AM   #983
smithoid
Human being with feelings
 
Join Date: Apr 2016
Posts: 19
Default

Thank you, you are a star :-)
Through all of this I have been getting confused between JSFX (where I wrote my code) and ReaScript. I couldn't get API's to run in JSFX because they don't...
But the penny has finally dropped and I have created some "Actions" that load the projects perfectly.
Thank you again!
All the best
Paul
smithoid is offline   Reply With Quote
Old 08-28-2022, 09:52 AM   #984
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 smithoid View Post
Thank you, you are a star :-)
Through all of this I have been getting confused between JSFX (where I wrote my code) and ReaScript. I couldn't get API's to run in JSFX because they don't...
But the penny has finally dropped and I have created some "Actions" that load the projects perfectly.
Thank you again!
All the best
Paul
Yeah, JSFX and ReaScript both allow using the same programming-language(EEL2) though they both access different areas of Reaper which might be confusing at first.
As a somewhat rule of thumb:
JSFX access everything sound-wise, like the actual sound you hear and actually played midi-notes.
ReaScript access everything you see, move and touch in the user-interface in Reaper, like Items, Projects, Tracks, etc.

There are some grey areas where the lines are blurred(MIDI notes are processed in JSFX but the notes in the MIDI-Editor are accessible by ReaScript), but mostly, this is the distinction that gives you some basic feeling on how to differentiate between them.
__________________
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 08-29-2022, 12:09 PM   #985
maaaxim
Human being with feelings
 
maaaxim's Avatar
 
Join Date: Jul 2022
Location: Amsterdam
Posts: 2
Default Call ReaSamplOmatic5000's "Detect pitch" function with ReaScript

Is it possible to use ReaScript to call the "Detect pitch" function within a ReaSamplOmatic5000 instance?

I'm currently creating a script where you can distribute ReaSamplOmatic5000 instances visually in a keyboard layout. Right now you need to manually hit "Detect pitch" button whenever a sample is added, which is quite tedious. I'm hoping this could be automated with ReaScript
maaaxim is offline   Reply With Quote
Old 08-29-2022, 03:29 PM   #986
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,913
Default

Quote:
Originally Posted by maaaxim View Post
Is it possible to use ReaScript to call the "Detect pitch" function within a ReaSamplOmatic5000 instance?

I'm currently creating a script where you can distribute ReaSamplOmatic5000 instances visually in a keyboard layout. Right now you need to manually hit "Detect pitch" button whenever a sample is added, which is quite tedious. I'm hoping this could be automated with ReaScript
Welcome to the forum.

If the RS5K plugin window(s) are visible (floating or in fx chain) one quick/dirty way would be to search all windows that have the text "Detect pitch", then run them as an action. Quick test on Win10 seems to work OK here... This is Lua script that requires the js_ReaScriptAPI extension...
Code:
function Main()-- RS5K button "Detect pitch" Command ID = 0x425
  local arr = reaper.new_array({}, 128)
  reaper.JS_Window_ArrayFind("Detect pitch", true, arr) 
  local adds = arr.table() 
  for i = 1, #adds do
    reaper.JS_Window_OnCommand(reaper.JS_Window_GetParent(reaper.JS_Window_HandleFromAddress(adds[i])), 0x425)
  end 
end

if not reaper.APIExists('JS_Window_OnCommand') then
  reaper.MB('js_ReaScriptAPI extension is required for this script.', 'Missing API', 0) 
else
  Main()
end
reaper.defer(function () end)
Edgemeal is offline   Reply With Quote
Old 08-30-2022, 05:15 AM   #987
maaaxim
Human being with feelings
 
maaaxim's Avatar
 
Join Date: Jul 2022
Location: Amsterdam
Posts: 2
Default

Thanks for your reply! The RS5K plugin window will be visible, so your script works perfectly
maaaxim is offline   Reply With Quote
Old 08-31-2022, 02:33 PM   #988
adu89
Human being with feelings
 
Join Date: Mar 2019
Posts: 8
Default Question about GetSetProjectInfo_String (c++)

Writing a c++ extension...

How can I know how large the valuestrNeedBig buffer should be before passing it to retrieve a value with GetSetProjectInfo_String?

bool (*GetSetProjectInfo_String)(ReaProject* project, const char* desc, char* valuestrNeedBig, bool is_set)

Im using it to get RENDER_STATS from reaper. The amount of data is variable and would depend on how many items/tracks where rendered.

Also, how does REAPER know how big the buffer is if I don't send it a buffer size? This is odd to me as other REAPER functions expect a buffer size in conjunction with the buffer itself.
adu89 is offline   Reply With Quote
Old 09-01-2022, 04:06 AM   #989
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
Default

Quote:
Originally Posted by adu89 View Post
Writing a c++ extension...

How can I know how large the valuestrNeedBig buffer should be before passing it to retrieve a value with GetSetProjectInfo_String?
Hi,

I asked the same question for GetEnvelopeStateChunk() with no real solving answer.
In the end we wrote our own wrapper function in the SWS extension to get it savely:
https://github.com/reaper-oss/sws/bl...y/envelope.cpp

There's a feature request with a comment from Justin but what he suggests there has happened yet afaik.
https://forum.cockos.com/showthread....45#post2142245

Quote:
Also, how does REAPER know how big the buffer is if I don't send it a buffer size? This is odd to me as other REAPER functions expect a buffer size in conjunction with the buffer itself.
Seems surprising indeed that the strNeedBig_sz parameter is missing there, maybe an oversight in the API (or just in the doc, have you actually tried to pass it a size)?

Last edited by nofish; 09-01-2022 at 04:21 AM.
nofish is offline   Reply With Quote
Old 09-01-2022, 08:38 AM   #990
adu89
Human being with feelings
 
Join Date: Mar 2019
Posts: 8
Default

Quote:
Originally Posted by nofish View Post
Hi,

I asked the same question for GetEnvelopeStateChunk() with no real solving answer.
In the end we wrote our own wrapper function in the SWS extension to get it savely:
https://github.com/reaper-oss/sws/bl...y/envelope.cpp

There's a feature request with a comment from Justin but what he suggests there has happened yet afaik.
https://forum.cockos.com/showthread....45#post2142245



Seems surprising indeed that the strNeedBig_sz parameter is missing there, maybe an oversight in the API (or just in the doc, have you actually tried to pass it a size)?
Thanks for the reply. Unfortunately, I had no luck trying to send a buffer size to GetSetProjectInfo_String. I am using the technique you use with GetEnvelopeStateChunk() for other reaper functions that take in a buffer size and it works well.
adu89 is offline   Reply With Quote
Old 09-01-2022, 01:30 PM   #991
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
Default

Quote:
Originally Posted by adu89 View Post
Thanks for the reply. Unfortunately, I had no luck trying to send a buffer size to GetSetProjectInfo_String. I am using the technique you use with GetEnvelopeStateChunk() for other reaper functions that take in a buffer size and it works well.
Hm...than maybe report as bug?
I can't see how it's supposed to work without taking a buffer size at least.
nofish is offline   Reply With Quote
Old 09-19-2022, 07:08 AM   #992
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default

How do I ...

Send a string from one JSFX to another?

Using options: gmem=some_unique_name we can use gmem[] to pass values between JS FX. So far, so good.

For strings, I have used an ugly method: extracting each character from the string into a gmem location, and reversing that in the receiving JS FX. Is there a better way?
__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is offline   Reply With Quote
Old 09-19-2022, 09:22 AM   #993
adu89
Human being with feelings
 
Join Date: Mar 2019
Posts: 8
Default Question about RENDER_STATS

Hello,

Does any one use GetSetProjectInfo_String to get RENDER_STATS? How does one parse this information correctly? Splitting the string using ";" can lead to bad results since ";" is a valid path character. If anyone has any insight on this, please share!
adu89 is offline   Reply With Quote
Old 09-21-2022, 02:47 AM   #994
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default

How do I ... initialise / clear a named gmem area?

mwmset(...) does not seem to work.

Is a loop, setting each element, the only way?
__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is offline   Reply With Quote
Old 10-31-2022, 12:24 PM   #995
fazmakesmusic
Human being with feelings
 
Join Date: Feb 2022
Posts: 44
Default Load Track Template from Path (lua)

Hey guys!

What's the cleanest way to load a track template from a path in lua?

os.execute('open "path"')

... works... however if i follow up with further commands, these are interrupted by the track template(s) loading. The script doesn't wait for the file to load.

Thanks in advance!


EDIT: found it! reaper.Main_openProject("path")

Last edited by fazmakesmusic; 10-31-2022 at 12:38 PM. Reason: ...dug a little deeper.
fazmakesmusic is offline   Reply With Quote
Old 11-01-2022, 08:25 AM   #996
jonboy3650
Human being with feelings
 
jonboy3650's Avatar
 
Join Date: Jan 2022
Location: England
Posts: 45
Default How do I keep track of pending region moves?

Background (for live looping with song sections):

I have a record script that is triggered from an external midi button.
1) First button press begins recording on an empty track.
2) Next button press cancels record, creates a region from the take, and plays the region in a loop.
3) Next button press waits until the end of the playing loop and begins recording.

(subsequent button presses loop through 2, and 3).

Next I have 'up' and 'down' (or 'next' and 'previous') buttons that will take me to the next/previous region. I have prototyped this, and it's working fine.

My want is to be able to repeatedly press the 'next' and 'previous' buttons, to go forward/back more than one region at a time (when the current region gets to the end).

Further info: I have previously used separate buttons to enact "SWS/S&M: Go to/select region X (obeys smooth seek)" for regions 1 to 4, and if I select two different regions before the current region finishes playing it always goes to the last one selected. So I know I can overwrite any pending moves. But can I find out if there is a move pending, and how many, so that I can go to the region before (or after) the last one selected?

- possible thoughts at this stage include going into a loop after the first next/previous press, lasting until the end of the current playing region (working out how much time is left from the play position), and waiting to see if any more button presses occur, which I guess I can do by reading in any midi messages.
jonboy3650 is offline   Reply With Quote
Old 11-04-2022, 04:59 AM   #997
signoc
Human being with feelings
 
signoc's Avatar
 
Join Date: Aug 2008
Location: Sweden
Posts: 96
Default Midieditor view mode

The MIDIEditor_GetMode(HWND midieditor) reports if editor is in piano-roll or event list.

But how do I determine if the view mode is "Mode: named notes" or "Mode: piano roll" ?
signoc is offline   Reply With Quote
Old 11-04-2022, 05:15 AM   #998
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 signoc View Post
The MIDIEditor_GetMode(HWND midieditor) reports if editor is in piano-roll or event list.

But how do I determine if the view mode is "Mode: named notes" or "Mode: piano roll" ?
reaper.ini->[midiedit] -> lastdrummode stores the last used midi-editor view, with the exception of musical notation.

0 - piano roll
1 - named notes
4 - event list
__________________
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-04-2022, 06:29 AM   #999
signoc
Human being with feelings
 
signoc's Avatar
 
Join Date: Aug 2008
Location: Sweden
Posts: 96
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
reaper.ini->[midiedit] -> lastdrummode stores the last used midi-editor view, with the exception of musical notation.

0 - piano roll
1 - named notes
4 - event list
Thanks!

First time reading the ini i tried different functions for reading config vars, but the only that gave any value was the code below, if anyone is searching for this.

retval, lastdrummode = reaper.BR_Win32_GetPrivateProfileString("midiedit" , "lastdrummode", "Error", reaper.get_ini_file())
signoc is offline   Reply With Quote
Old 11-08-2022, 02:01 PM   #1000
fazmakesmusic
Human being with feelings
 
Join Date: Feb 2022
Posts: 44
Default How can I get the time at which audio crosses a volume threshold? (lua)

Is it possible to get the first time at which audio crosses a certain threshold(in lua)?

With regards to a selected track or item (preferably track).

I'm trying to create a script that will reorder tracks based on the audio start time (not the item start time).

I feel like the Audio Accessor functions would come in to play here but I have no idea where to start with it.

Any help much appreciated!
fazmakesmusic 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 08:07 AM.


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