|
|
|
11-29-2018, 08:13 PM
|
#1
|
Human being with feelings
Join Date: Apr 2016
Posts: 39
|
Reascript Global Memory?
Hello forum,
I'm hoping someone can shine some light on this: Is there a way to access (read/write) global reascript memory. I'm desperately looking for a solution to share a few objects between multiple deferred scripts, and seem to be killing my system reading/writing from extstate.
I found a post discussing gmem[] specifically in JS/OSCIIBOT, but am interested if there is the equivalent in reascript, there's no mention within the API.
Post in question:
https://forum.cockos.com/showthread.php?t=181580
Thanks for any info!
|
|
|
11-30-2018, 03:53 AM
|
#2
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,875
|
Untested, but from prerelease:
Code:
v5.961+dev1029 - October 29 2018 + ReaScript: add reaper.gmem_attach()/gmem_read()/gmem_write() to Lua for interacting with JSFX/Video Processors/EEL2 ReaScripts gmem[] segments
I wonder if this works through different ReaScripts or only between JSFX and ReaScripts.
|
|
|
11-30-2018, 05:45 AM
|
#3
|
Human being with feelings
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
|
Yes, it works for anything.
|
|
|
12-01-2018, 08:01 AM
|
#4
|
Human being with feelings
Join Date: Jan 2007
Location: mcr:uk
Posts: 3,889
|
As I understand it, EEL ReaScripts have had gmem for a long time. The upcoming pre stuff is just for interaction between JSFX and ReaScripts.
https://www.cockos.com/EEL2/index.php#basic (5th and 6th bullet points)
I've never actually used it in a script though. Don't know if Lua and Python have anything similar.
|
|
|
02-24-2019, 05:37 PM
|
#5
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,875
|
Has anyone a small code snippet to share to show the usage of this functions ? Not sure to understand the difference between attach and read and how to pass string values.
|
|
|
02-24-2019, 10:12 PM
|
#6
|
Human being with feelings
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
|
Quote:
Originally Posted by X-Raym
Not sure to understand the difference between attach and read and how to pass string values.
|
Easiest example here: https://forum.cockos.com/showthread.php?t=217291
You can`t pass strings, only floats. But I guess you can pass strings as character codes (would be nice to share strings though!).
http://reaper.fm/sdk/js/basiccode.php#op_gmem:
Quote:
If 'gmem' is specified as the left parameter to the brackets, then the global shared buffer is used, which is approximately 1 million (1,048,576) slots that are shared across all instances of all JSFX effects.
|
So if you not define name of the buffer, it makes that simply a global buffer with no name.
Quote:
The plug-in can also specify a line (before code sections):
options:gmem=someUniquelyNamedSpace which will make gmem[] refer to a larger shared buffer, accessible by any plugin that uses options:gmem=<the same name>.
|
It is gmem.attach in Lua. Other words you can have multiple global buffers, each of those should have a unique name (which it referenced by).
Quote:
So, if you have a single plug-in, or a few plug-ins that access the shared namespace, they can communicate without having to worry about other plug-ins. This option also increases the size of gmem[] to be 8 million entries (from the default 1 million). -- REAPER 4.6+
|
Last edited by mpl; 02-24-2019 at 10:25 PM.
|
|
|
02-24-2019, 10:22 PM
|
#7
|
Human being with feelings
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
|
JSFX:
Code:
desc:test_plug
options:gmem=test_name
@init
gmem[1] = 1;
ReaScript:
Code:
gmem_attach('test_name')
test_output = gmem_read(1)
|
|
|
02-24-2019, 10:23 PM
|
#8
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Storing null-terminated strings:
Code:
function gmem_write_string(index, value)
for c in value:gmatch('.') do
reaper.gmem_write(index, string.byte(c))
index = index + 1
end
reaper.gmem_write(index, 0)
end
function gmem_read_string(index)
local chars = {}
while true do
local value = reaper.gmem_read(index)
if value == 0 then break end
table.insert(chars, string.char(value))
index = index + 1
end
return table.concat(chars)
end
JSFX equivalent:
Code:
desc:Storing strings in global memory space
version:1.0
author:cfillion
options:gmem=some_namespace
@block
function gmem_write_string(index, value) local(offset) (
offset = 0;
loop(strlen(value),
gmem[index] = str_getchar(value, offset);
offset += 1;
index += 1;
);
gmem[index] = 0;
);
trigger ? gmem_write_string(0, "foo");
@gfx
function gmem_read_string(index, output) local(offset, buf) (
offset = 0;
buf = #;
while (
gmem[index] ? (
str_setchar(buf, offset, gmem[index]);
offset += 1;
index += 1;
) : 0;
);
strcpy_substr(output, buf, 0, offset); // truncates the output
);
gfx_r = gfx_g = gfx_b = 1;
gfx_x = 0;
str = #;
gmem_read_string(0, str);
gfx_drawstr(str);
Last edited by cfillion; 02-24-2019 at 10:33 PM.
|
|
|
02-25-2019, 02:24 AM
|
#9
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,875
|
Ok thanks for the code !
Here is a demo with write from ReaScript to Video Processor:
Code:
reaper.gmem_attach('testname')
function gmem_write_string(index, value)
for c in value:gmatch('.') do
reaper.gmem_write(index, string.byte(c))
index = index + 1
end
reaper.gmem_write(index, 0)
end
function Main()
gmem_write_string(0, tostring(reaper.GetCursorPosition()) )
reaper.defer(Main)
end
Main()
Code:
// JT: Essential Text Overlay
//@gmem=testname
function gmem_read_string(index, output) local(offset, buf) (
offset = 0;
buf = #;
while (
gmem[index] ? (
str_setchar(buf, offset, gmem[index]);
offset += 1;
index += 1;
) : 0;
);
strcpy_substr(output, buf, 0, offset); // truncates the output
);
gmem_read_string(0, text); // set to string to override
text=gmem[0];
font="Futura";
//@param1:size 'Text height' 0.1 0.01 0.3 0.1 0.01
//@param2:xpos 'X position' 0.5 -0.5 1.5 0.5 0.01
//@param3:ypos 'Y position' 0.5 -0.5 1.5 0.5 0.01
//@param5:txtr 'Text R' 1 0 1 0.5 0.01
//@param6:txtg 'Text G' 1 0 1 0.5 0.01
//@param7:txtb 'Text B' 1 0 1 0.5 0.01
//@param8:fga 'Text opacity' 1 0 1 0.5 0.01
//@param10:border 'BG Size' 0.25 -0.5 15 2 0.25
//@param11:bgred 'BG R' 0 0 1 0.5 0.01
//@param12:bggreen 'BG G' 0 0 1 0.5 0.01
//@param13:bgblue 'BG B' 0 0 1 0.5 0.01
//@param14:bga 'BG opacity' 0 0 1 0.5 0.01
gfx_blit(0,1);
gfx_setfont(size*project_h,font);
gfx_str_measure(text,txtw,txth);
yt = (project_h- txth*(1+border*2))*ypos;
gfx_r=(bgred);
gfx_g=(bggreen);
gfx_b=(bgblue);
gfx_set(bgred,bggreen,bgblue,bga);
gfx_fillrect(0, yt, project_w, txth*(1+border*2));
gfx_r=(txtr);
gfx_g=(txtg);
gfx_b=(txtb);
gfx_set(txtr,txtg,txtb,fga);
gfx_str_draw(text,xpos * (project_w-txtw),yt+txth*border);
But note that Video Processor is really unefficient for this. As explain in the video processor doc:
Quote:
Note that when synchronizing with ReaScripts or JSFX, all processing is asynchronous, so your code will have to deal with synchronization issues (including vast differences between project_time and playback_position, and including race conditions).
|
Even getting something like playstate or curpos fails if playstate == stop.
Too bad... This is makes poorly reliable. Same with play state which is even more problematic.
|
|
|
02-25-2019, 02:56 AM
|
#10
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
reaper.GetCursorPosition() is already a number, so it can be stored directly: reaper.gmem_write(0, reaper.GetCursorPosition()).
Code:
gmem_read_string(0, text);
text=gmem[0];
The second line sets text to point to a different string slot depending on the value in gmem[0] (first character). So what is being displayed later isn't always the same string slot that gmem_read_string wrote into.
However most of the time the frame will be drawn before the script can update gmem (and updating gmem doesn't trigger a redraw).
Last edited by cfillion; 02-25-2019 at 03:31 AM.
|
|
|
02-25-2019, 04:27 AM
|
#11
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,875
|
Quote:
reaper.GetCursorPosition() is already a number, so it can be stored directly: reaper.gmem_write(0, reaper.GetCursorPosition()).
|
I was testing other things as well (like getting markers etc) :P
Quote:
However most of the time the frame will be drawn before the script can update gmem (and updating gmem doesn't trigger a redraw).
|
Yes, this is the main issue here, though the error happens a bit less more with your fix, but it is still not reliable enough. It can display "1" for record/play state despite the fact it is not.
Priority issue...
|
|
|
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 11:58 AM.
|