|
|
|
06-16-2022, 10:09 AM
|
#961
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by Meo-Ada Mespotine
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
|
|
|
06-16-2022, 11:25 AM
|
#962
|
Human being with feelings
Join Date: Jul 2020
Posts: 84
|
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.
|
|
|
06-23-2022, 08:59 AM
|
#963
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
Quote:
Originally Posted by BethHarmon
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.
|
|
|
06-23-2022, 09:02 AM
|
#964
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
Quote:
Originally Posted by nscotto
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
|
|
|
06-23-2022, 09:30 AM
|
#965
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by Meo-Ada Mespotine
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...
|
|
|
06-24-2022, 03:44 PM
|
#966
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
Quote:
Originally Posted by BethHarmon
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.
|
|
|
06-25-2022, 12:12 PM
|
#967
|
Human being with feelings
Join Date: Feb 2021
Posts: 2,261
|
Quote:
Originally Posted by Meo-Ada Mespotine
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.
Last edited by chmaha; 06-25-2022 at 03:16 PM.
|
|
|
07-08-2022, 07:50 AM
|
#968
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
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...
|
|
|
07-08-2022, 09:02 AM
|
#969
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,875
|
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 ^^
|
|
|
08-10-2022, 12:31 PM
|
#970
|
Human being with feelings
Join Date: Mar 2019
Posts: 8
|
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.
|
|
|
08-12-2022, 05:16 PM
|
#971
|
Human being with feelings
Join Date: Feb 2020
Location: Los Angeles
Posts: 463
|
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!
|
|
|
08-12-2022, 06:02 PM
|
#972
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Quote:
Originally Posted by sonictim
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.
|
|
|
08-12-2022, 10:16 PM
|
#973
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,875
|
@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.
|
|
|
08-13-2022, 06:10 AM
|
#974
|
Human being with feelings
Join Date: Feb 2020
Location: Los Angeles
Posts: 463
|
Quote:
Originally Posted by nofish
|
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!
|
|
|
08-25-2022, 10:55 AM
|
#975
|
Human being with feelings
Join Date: Apr 2016
Posts: 19
|
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
|
|
|
08-26-2022, 07:04 AM
|
#976
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
Quote:
Originally Posted by smithoid
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.
|
|
|
08-27-2022, 12:40 AM
|
#977
|
Human being with feelings
Join Date: Apr 2016
Posts: 19
|
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
|
|
|
08-27-2022, 05:14 AM
|
#978
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
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
Last edited by Meo-Ada Mespotine; 08-27-2022 at 05:28 AM.
|
|
|
08-28-2022, 05:40 AM
|
#979
|
Human being with feelings
Join Date: Apr 2016
Posts: 19
|
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
|
|
|
08-28-2022, 06:49 AM
|
#980
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
@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
|
|
|
08-28-2022, 07:36 AM
|
#981
|
Human being with feelings
Join Date: Apr 2016
Posts: 19
|
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
|
|
|
08-28-2022, 07:55 AM
|
#982
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Quote:
Originally Posted by smithoid
Still keen to try and load a complete project if anyone has any ideas?
|
With ReaScript Main_openProject.
|
|
|
08-28-2022, 09:43 AM
|
#983
|
Human being with feelings
Join Date: Apr 2016
Posts: 19
|
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
|
|
|
08-28-2022, 09:52 AM
|
#984
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
Quote:
Originally Posted by smithoid
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.
|
|
|
08-29-2022, 12:09 PM
|
#985
|
Human being with feelings
Join Date: Jul 2022
Location: Amsterdam
Posts: 2
|
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
|
|
|
08-29-2022, 03:29 PM
|
#986
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,913
|
Quote:
Originally Posted by maaaxim
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)
|
|
|
08-30-2022, 05:15 AM
|
#987
|
Human being with feelings
Join Date: Jul 2022
Location: Amsterdam
Posts: 2
|
Thanks for your reply! The RS5K plugin window will be visible, so your script works perfectly
|
|
|
08-31-2022, 02:33 PM
|
#988
|
Human being with feelings
Join Date: Mar 2019
Posts: 8
|
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.
|
|
|
09-01-2022, 04:06 AM
|
#989
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Quote:
Originally Posted by adu89
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.
|
|
|
09-01-2022, 08:38 AM
|
#990
|
Human being with feelings
Join Date: Mar 2019
Posts: 8
|
Quote:
Originally Posted by nofish
|
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.
|
|
|
09-01-2022, 01:30 PM
|
#991
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Quote:
Originally Posted by adu89
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.
|
|
|
09-19-2022, 07:08 AM
|
#992
|
Human being with feelings
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
|
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 ...
|
|
|
09-19-2022, 09:22 AM
|
#993
|
Human being with feelings
Join Date: Mar 2019
Posts: 8
|
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!
|
|
|
09-21-2022, 02:47 AM
|
#994
|
Human being with feelings
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
|
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 ...
|
|
|
10-31-2022, 12:24 PM
|
#995
|
Human being with feelings
Join Date: Feb 2022
Posts: 44
|
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.
|
|
|
11-01-2022, 08:25 AM
|
#996
|
Human being with feelings
Join Date: Jan 2022
Location: England
Posts: 45
|
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.
|
|
|
11-04-2022, 04:59 AM
|
#997
|
Human being with feelings
Join Date: Aug 2008
Location: Sweden
Posts: 96
|
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" ?
|
|
|
11-04-2022, 05:15 AM
|
#998
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
Quote:
Originally Posted by signoc
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
|
|
|
11-04-2022, 06:29 AM
|
#999
|
Human being with feelings
Join Date: Aug 2008
Location: Sweden
Posts: 96
|
Quote:
Originally Posted by Meo-Ada Mespotine
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())
|
|
|
11-08-2022, 02:01 PM
|
#1000
|
Human being with feelings
Join Date: Feb 2022
Posts: 44
|
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!
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 08:07 AM.
|