I have found some weird behaviour in JSFX, weird enough that I think it's a bug.
Description
Under certain circumstances, "srate" is = 0 in @init when triggered by play/seek. I have narrowed down a set of conditions where I can reproduce it - it only happens for me if all three are met:
- Latency must be non-zero (e.g. place "Time Adjustment Delay" with negative delay before effect)
- The JSFX must have its interface visible
- The JSFX must have a @gfx section defined
Under these circumstances, most of the time I observe two @init calls happening on play/seek - once with srate=0, the immediately afterwards with a proper value.
Here are some screenshots (or
backup link) illustrating the issue, including the fact that it doesn't happen if the conditions above are not met.
Expected Behaviour
I expected srate to be reliably non-zero. It is under all other circumstances I have found.
Consequences
Some of my @gfx code assumed/required srate-derived values to be non-zero in order to terminate. This meant REAPER would sometimes became unresponsive and needed to be forced closed (losing project state) upon play/seek.
The hang is inconsistent because the @gfx call needs to happen at exactly the right time (between two @init executions), and is project-specific (because it requires some latency from earlier effects).
Workaround
I can add this line to @init:
Code:
!srate ? srate = 44100;
This fixes the problem and makes all my srate-derived values sane, but it's a weird thing to put in all of my effects.
Since there is
immediately another call to @init (with a non-zero srate value) it doesn't matter whether this value is accurate, it just should be plausible (non-zero) to avoid problems in @gfx.
Steps to reproduce
Place the built-in "Time Adjustment Delay" with the delay time set to -1000ms.
After that, add the debugging effect below. Open up the debugger, repeatedly hit play/pause, and observe the values of debug.srateN.
Here is a debugging JSFX that lets you see the 6 most recent srate values in the debugger:
Code:
desc:srate logger
@init
// Show the last 6 srate values in the debugger
debug.srate6 = debug.srate5;
debug.srate5 = debug.srate4;
debug.srate4 = debug.srate3;
debug.srate3 = debug.srate2;
debug.srate2 = debug.srate;
debug.srate = srate;
@serialize
// stop it from resetting the variables on playback start
foo = 1;
@gfx
// Block must be defined for the bug to appear - actual content isn't relevant
gfx_r = rand();
gfx_g = rand();
gfx_b = rand();
gfx_a = 1;
gfx_rect(gfx_w*rand(), gfx_h*rand(), 10, 10);
System
Found with REAPER v5.92/64 on Mac (OS X El Capitan, 10.11.6).