Skip to content

Commit ceec777

Browse files
committed
update RCModEQ to v1.2.0
1 parent 7bf997d commit ceec777

5 files changed

Lines changed: 269 additions & 62 deletions

File tree

JSFX/Audio/RCModEQ/RCModEQ.jsfx

Lines changed: 184 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ JSFX Name: RCModEQ
33
Author: RCJacH
44
Release Date: Aug 2025
55
Link: https://github.com/RCJacH/ReaScripts
6-
Version: 1.1.0
6+
Version: 1.2.0
77
Provides:
88
dependencies/*
99
Reference:
@@ -16,6 +16,11 @@ About:
1616
It lets you stack up to eight filters and drive their parameters with
1717
up to eight shape-selectable and deformable LFOs.
1818
Changelog:
19+
* v1.2.0 (2026-01-27)
20+
+ Add Threshold and RMS to Sidechain
21+
* Fix bandwidth being modulated instead of gain
22+
* Fix lfo spread
23+
* Fix BandPass and Unity-gain BandPass icons being swapped
1924
* v1.1.0 (2025-12-14)
2025
+ Add Morph Parameter to filters
2126
* Fix double click to add filter
@@ -28,7 +33,7 @@ Changelog:
2833

2934
desc: RCModEQ
3035
<?
31-
CURRENT_VERSION = 1.1;
36+
CURRENT_VERSION = 1.2;
3237
TOTAL_FILTER_COUNT = 8;
3338
TOTAL_LFO_COUNT = 8;
3439
TOTAL_SIDECHAIN_COUNT = 8;
@@ -68,6 +73,13 @@ desc: RCModEQ
6873
printf("slider%d:lfo%d_spread=0<-1, 1>%sLFO %d Spread\n", sl_idx, idx, hide, idx); sl_idx += 1;
6974
idx += 1;
7075
);
76+
idx = 1;
77+
loop(TOTAL_SIDECHAIN_COUNT,
78+
printf("slider%d:sc%d_active=0<0,1,1>-SideChain %d On/Off\n", sl_idx, idx, idx); sl_idx += 1;
79+
printf("slider%d:sc%d_thres=0<-90,0,0.1:log=-20.>-SideChain %d Threshold\n", sl_idx, idx, idx); sl_idx += 1;
80+
printf("slider%d:sc%d_rms=0<0,500,0.1:log=50.>-SideChain %d RMS\n", sl_idx, idx, idx); sl_idx += 1;
81+
idx += 1;
82+
);
7183
?>
7284

7385
import dependencies/svf_filter.jsfx-inc
@@ -612,6 +624,51 @@ out_pin:Right Output
612624
?>
613625
);
614626

627+
function notify_touched_sidechain_active(idx, active, end) (
628+
// Notify Reaper that a parameter change has happened
629+
<?
630+
i = 1;
631+
loop(TOTAL_SIDECHAIN_COUNT,
632+
printf("idx == %d ? (\n", i-1);
633+
printf("sc%i_active = active;\n", i);
634+
printf("sliderchange(sc%i_active);\n", i);
635+
printf("slider_automate(sc%i_active, end);\n", i);
636+
printf(")%s\n", i == TOTAL_SIDECHAIN_COUNT ? ";" : " :");
637+
i += 1;
638+
);
639+
?>
640+
);
641+
642+
function notify_touched_sidechain_threshold(idx, threshold, end) (
643+
// Notify Reaper that a parameter change has happened
644+
<?
645+
i = 1;
646+
loop(TOTAL_SIDECHAIN_COUNT,
647+
printf("idx == %d ? (\n", i-1);
648+
printf("sc%i_thres = threshold;\n", i);
649+
printf("sliderchange(sc%i_thres);\n", i);
650+
printf("slider_automate(sc%i_thres, end);\n", i);
651+
printf(")%s\n", i == TOTAL_SIDECHAIN_COUNT ? ";" : " :");
652+
i += 1;
653+
);
654+
?>
655+
);
656+
657+
function notify_touched_sidechain_rms(idx, rms, end) (
658+
// Notify Reaper that a parameter change has happened
659+
<?
660+
i = 1;
661+
loop(TOTAL_SIDECHAIN_COUNT,
662+
printf("idx == %d ? (\n", i-1);
663+
printf("sc%i_rms = rms;\n", i);
664+
printf("sliderchange(sc%i_rms);\n", i);
665+
printf("slider_automate(sc%i_rms, end);\n", i);
666+
printf(")%s\n", i == TOTAL_SIDECHAIN_COUNT ? ";" : " :");
667+
i += 1;
668+
);
669+
?>
670+
);
671+
615672
function set_filter_active(idx, is_active)
616673
global()
617674
(
@@ -856,6 +913,37 @@ out_pin:Right Output
856913
notify_touched_lfo_spread(idx, spread, is_end);
857914
);
858915

916+
function set_sidechain_active(idx, is_active)
917+
global(TOTAL_LFO_COUNT)
918+
(
919+
set_SideChain_active(idx, is_active);
920+
notify_touched_sidechain_active(idx, is_active, 1);
921+
set_dirty_for_router_routes_with_src_mod(idx + TOTAL_LFO_COUNT);
922+
sliderchange(-1);
923+
);
924+
925+
function toggle_sidechain_active(idx)
926+
local(is_active)
927+
global()
928+
(
929+
is_active = !is_SideChain_active(idx);
930+
set_sidechain_active(idx, is_active);
931+
);
932+
933+
function set_sidechain_threshold(idx, threshold, is_end)
934+
global()
935+
(
936+
set_SideChain_thres(idx, threshold);
937+
notify_touched_sidechain_threshold(idx, threshold, is_end);
938+
);
939+
940+
function set_sidechain_rms(idx, rms, is_end)
941+
global()
942+
(
943+
set_SideChain_rms(idx, rms);
944+
notify_touched_sidechain_rms(idx, rms, is_end);
945+
);
946+
859947
function set_makeup_gain(gain_dB, is_end)
860948
global(makeup_gain_db, makeup_gain_linear)
861949
(
@@ -1002,6 +1090,13 @@ out_pin:Right Output
10021090
i += 1;
10031091
);
10041092
?>
1093+
<?
1094+
i = 1;
1095+
loop(TOTAL_LFO_COUNT,
1096+
printf("on_SideChain_slider_change(%d, sc%d_active, sc%d_thres, sc%d_rms);\n", i-1,i,i,i);
1097+
i += 1;
1098+
);
1099+
?>
10051100
makeup_gain_linear = dB_to_A(makeup_gain_db);
10061101
limiter_threshold_linear = dB_to_A(limiter_threshold);
10071102

@@ -1742,6 +1837,14 @@ out_pin:Right Output
17421837
r_dragging ? r_dragged = 1;
17431838
r_dragging = r_click = 0;
17441839
);
1840+
r_dragging ? (
1841+
mouse_cap&1 && !l_dragging? (
1842+
l_click = 1;
1843+
) : l_click ? (
1844+
l_clicked = 1;
1845+
l_click = 0;
1846+
); // Reset dragging on left click
1847+
);
17451848
!(l_dragging || r_dragging) ? in_section = 0;
17461849
);
17471850

@@ -1782,34 +1885,40 @@ out_pin:Right Output
17821885
);
17831886
);
17841887
r_dragging ? (
1785-
mouse_cap&4 ? ( // Holding Ctrl/Command assigns value based on mouse position
1786-
v_xr = (mouse_x - x) / w;
1787-
v_yr = (y - mouse_y) / h;
1788-
type&16 ? v_xr = v_xr * 2. - 1.;
1789-
type&32 ? v_yr = v_yr * 2. - 1.;
1790-
) : ( // otherwise change value relatively
1791-
dx = (mouse_x - prev_x) / w; dy = (mouse_y - prev_y) / h;
1792-
d_ratio = mouse_cap&8 ? .01 : .1; // Holding shift finetunes
1793-
v_xr += dx * d_ratio;
1794-
v_yr -= dy * d_ratio;
1795-
);
1796-
mouse_cap&16 ? ( // Holding alt/opt changes value on one axis only
1797-
abs(mouse_x - omp_xr) > abs(mouse_y - omp_yr) ? (
1798-
v_yr = ov_yr;
1799-
) : (
1800-
v_xr = ov_xr;
1888+
l_clicked ? (
1889+
v_xr = ov_xr; v_yr = ov_yr;
1890+
r_dragged = r_dragging;
1891+
r_dragging = r_click = l_click = r_clicked = l_clicked = in_section = 0;
1892+
) : (
1893+
mouse_cap&4 ? ( // Holding Ctrl/Command assigns value based on mouse position
1894+
v_xr = (mouse_x - x) / w;
1895+
v_yr = (y - mouse_y) / h;
1896+
type&16 ? v_xr = v_xr * 2. - 1.;
1897+
type&32 ? v_yr = v_yr * 2. - 1.;
1898+
) : ( // otherwise change value relatively
1899+
dx = (mouse_x - prev_x) / w; dy = (mouse_y - prev_y) / h;
1900+
d_ratio = mouse_cap&8 ? .01 : .1; // Holding shift finetunes
1901+
v_xr += dx * d_ratio;
1902+
v_yr -= dy * d_ratio;
1903+
);
1904+
mouse_cap&16 ? ( // Holding alt/opt changes value on one axis only
1905+
abs(mouse_x - omp_xr) > abs(mouse_y - omp_yr) ? (
1906+
v_yr = ov_yr;
1907+
) : (
1908+
v_xr = ov_xr;
1909+
);
18011910
);
1911+
v_xr = clamp(v_xr, type&16?-1.:0., 1.);
1912+
v_yr = clamp(v_yr, type&32?-1.:0., 1.);
18021913
);
1803-
v_xr = clamp(v_xr, type&16?-1.:0., 1.);
1804-
v_yr = clamp(v_yr, type&32?-1.:0., 1.);
18051914
);
18061915
prev_x = mouse_x; prev_y = mouse_y;
18071916
status;
18081917
);
18091918

18101919
function ui_drawSlider(x, y, w, h, type, color_mem_pos, is_active, s)
1811-
local(mw, x0, y0, w0, h0)
1812-
instance(status, v_xl)
1920+
local(mw, x0, y0, w0, h0, v)
1921+
instance(status, v_xl, v_xr)
18131922
global(
18141923
g_button_border_size,
18151924
BUTTON_BORDER_OFFSET, BUTTON_BG_OFFSET, BUTTON_MAIN_OFFSET,
@@ -1825,11 +1934,12 @@ out_pin:Right Output
18251934
set_HSL_button_color(color_mem_pos, status, BUTTON_BG_OFFSET);
18261935
gfx_rect(x0, y0, w0, h0);
18271936
set_HSL_button_color(color_mem_pos, status, BUTTON_MAIN_OFFSET);
1937+
v = type&8 ? v_xr : v_xl;
18281938
type&2 ? (
18291939
mw = w0 * .5;
1830-
w0 = mw * abs(v_xl); x0 = v_xl < 0? x0 + mw - w0 : x0 + mw;
1940+
w0 = mw * abs(v); x0 = v < 0? x0 + mw - w0 : x0 + mw;
18311941
gfx_rect(x0, y0, w0, h0);
1832-
) : gfx_rect(x0, y0, w0 * v_xl, h0);
1942+
) : gfx_rect(x0, y0, w0 * v, h0);
18331943
set_HSL_button_color(color_mem_pos, status, BUTTON_TEXT_OFFSET);
18341944
ui_drawButtonText(x, y, w, h, s);
18351945
);
@@ -3289,21 +3399,21 @@ out_pin:Right Output
32893399
ctrl_gain_mod.l_dragging ? (
32903400
adjust_router_filter_param(
32913401
g_mod_route_idx, idx, ROUTER_FILTER_GAIN,
3292-
get_SVF_mem_pos(idx) + SVF_BANDWIDTH_MOD_OFFSET, ctrl_gain_mod.v_yl
3402+
get_SVF_mem_pos(idx) + SVF_GAIN_MOD_OFFSET, ctrl_gain_mod.v_yl
32933403
);
32943404
sliderchange(-1);
32953405
);
32963406
ctrl_gain_mod.l_clicked < 0 ? (
32973407
adjust_router_filter_param(
32983408
g_mod_route_idx, idx, ROUTER_FILTER_GAIN,
3299-
get_SVF_mem_pos(idx) + SVF_BANDWIDTH_MOD_OFFSET, 0.
3409+
get_SVF_mem_pos(idx) + SVF_GAIN_MOD_OFFSET, 0.
33003410
);
33013411
sliderchange(-1);
33023412
ctrl_gain_mod.l_clicked = 0;
33033413
);
33043414
ctrl_gain_mod.r_clicked ? (
33053415
ui_handleMODContextMenu(
3306-
idx, ROUTER_FILTER_GAIN, get_SVF_mem_pos(idx) + SVF_BANDWIDTH_MOD_OFFSET
3416+
idx, ROUTER_FILTER_GAIN, get_SVF_mem_pos(idx) + SVF_GAIN_MOD_OFFSET
33073417
);
33083418
ctrl_gain_mod.r_clicked = 0;
33093419
);
@@ -3927,11 +4037,13 @@ out_pin:Right Output
39274037

39284038
function ui_drawSCs(x, y, w, h)
39294039
local(
3930-
i, open_i, count, color_mem, amp, is_active, is_cur_route_src,
4040+
i, open_i, count, color_mem, is_active, is_cur_route_src,
4041+
thres, rms, is_show_thres, is_show_rms, is_cycle_rms, tm_diff
39314042
mod_idx, columns, rows,
39324043
padding, gap, total_w, str_w, str_h, x0, y0, w0, h0, status,
4044+
v
39334045
)
3934-
instance(selected_idx, tb_sc, sl_amp, bt_link, bt_unlink, bt_delete)
4046+
instance(selected_idx, tb_sc, sl_amp, bt_link, bt_unlink, bt_delete, rmb_time, prev_time)
39354047
(
39364048
color_mem = get_band_color_mem(selected_idx + TOTAL_FILTER_COUNT + TOTAL_LFO_COUNT);
39374049
mod_idx = selected_idx + TOTAL_LFO_COUNT;
@@ -3983,33 +4095,68 @@ out_pin:Right Output
39834095
tb_sc.l_clicked = 0;
39844096
);
39854097
tb_sc.r_clicked ? (
3986-
toggle_SideChain_active(tb_sc.hover_idx);
4098+
toggle_sidechain_active(tb_sc.hover_idx);
39874099
set_dirty_for_router_routes_with_src_mod(tb_sc.hover_idx + TOTAL_LFO_COUNT);
39884100
tb_sc.r_clicked = 0;
39894101
);
39904102

39914103
selected_idx >= 0 ? (
39924104
x0 = x + padding; y0 = y; w0 *= columns; w0 = w - w0 - gap * 2.; h0 = (h - gap * 3.) * .25;
39934105
is_active = is_SideChain_active(selected_idx);
4106+
is_show_thres = sl_amp.l_click || sl_amp.l_dragging;
4107+
is_show_rms = sl_amp.r_click || sl_amp.r_dragging;
4108+
!(sl_amp.in_section || is_show_thres || is_show_rms) ? (
4109+
rmb_time += time_precise() - prev_time;
4110+
rmb_time = rmb_time - floor(rmb_time / 10.) * 10.;
4111+
);
4112+
prev_time = time_precise();
4113+
is_cycle_rms = rmb_time > 5.;
39944114
set_HSL_color(COLOR_HIGHLIGHT);
39954115
!is_active ? uix_darkenColor(.5);
3996-
ui_drawCenteredText(x0, y0, w0, h0, "AMP");
4116+
ui_drawCenteredText(x0, y0, w0, h0, is_show_rms ? "RMS" : is_show_thres ? "THRES" : is_cycle_rms ? "RMS: RMB" : "TH: LMB");
39974117

3998-
amp = get_SideChain_amp(selected_idx);
39994118
y0 += h0;
4000-
sl_amp.v_xl = amp;
4001-
sl_amp.ui_drawSlider(x0, y0, w0, h0, 1, color_mem, is_active, sprintf(#, "%.1f%%", amp * 100.));
4119+
thres = get_SideChain_thres(selected_idx);
4120+
rms = get_SideChain_rms(selected_idx);
4121+
sl_amp.v_xl = (1. - sqrt(abs(thres) / 90));
4122+
sl_amp.v_xr = pow(log(rms + 1.) / log(501), 1. / 0.661);
4123+
is_show_rms || (!is_show_thres && is_cycle_rms && !sl_amp.in_section) ? (
4124+
sl_amp.ui_drawSlider(
4125+
x0, y0, w0, h0, 12, color_mem, is_active,
4126+
sprintf(#, rms < 100. ? "%.1f ms" : "%.0f ms", rms)
4127+
);
4128+
) : (
4129+
sl_amp.ui_drawSlider(
4130+
x0, y0, w0, h0, 1, color_mem, is_active,
4131+
sprintf(#, "%.1f dB", thres)
4132+
);
4133+
);
4134+
40024135
sl_amp.l_clicked < 0 ? (
4003-
set_SideChain_amp(selected_idx, 0.);
4136+
set_sidechain_threshold(selected_idx, 0., 0);
40044137
sl_amp.l_clicked = 0;
40054138
sliderchange(-1);
40064139
);
4007-
sl_amp.l_dragging ? set_SideChain_amp(selected_idx, sl_amp.v_xl);
4140+
v = -90 * pow(1. - sl_amp.v_xl, 2.);
4141+
sl_amp.l_dragging ? set_sidechain_threshold(selected_idx, v, 0);
40084142
sl_amp.l_dragged ? (
4009-
set_SideChain_amp(selected_idx, sl_amp.v_xl);
4143+
set_sidechain_threshold(selected_idx, v, 1);
40104144
sl_amp.l_dragged = 0;
40114145
sliderchange(-1);
40124146
);
4147+
4148+
sl_amp.r_clicked < 0 ? (
4149+
set_sidechain_rms(selected_idx, 0.0, 0);
4150+
sl_amp.r_clicked = 0;
4151+
sliderchange(-1);
4152+
);
4153+
v = pow(501., pow(sl_amp.v_xr, 0.661)) - 1;
4154+
sl_amp.r_dragging ? set_sidechain_rms(selected_idx, v, 0);
4155+
sl_amp.r_dragged ? (
4156+
set_sidechain_rms(selected_idx, v, 1);
4157+
sl_amp.r_dragged = 0;
4158+
sliderchange(-1);
4159+
);
40134160
y0 += h0 + gap;
40144161

40154162
bt_link.fill_type = 1;

JSFX/Audio/RCModEQ/dependencies/lfo.jsfx-inc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ LFO_PREV_RND_OFFSET = lfo_offset_inc;
4444
LFO_PREV_RND_L_OFFSET = lfo_offset_inc; lfo_offset_inc += 1;
4545
LFO_PREV_RND_R_OFFSET = lfo_offset_inc; lfo_offset_inc += 1;
4646
LFO_CUR_RND_OFFSET = lfo_offset_inc;
47-
LFO_CUR_RND_OFFSET = lfo_offset_inc; lfo_offset_inc += 1;
48-
LFO_CUR_RND_OFFSET = lfo_offset_inc; lfo_offset_inc += 1;
47+
LFO_CUR_RND_L_OFFSET = lfo_offset_inc; lfo_offset_inc += 1;
48+
LFO_CUR_RND_R_OFFSET = lfo_offset_inc; lfo_offset_inc += 1;
4949
LFO_MIDI_TRIG_OFFSET = lfo_offset_inc; lfo_offset_inc += 1; // set to offset in @block on Note-On
5050

5151
LFO_TOTAL_MEM = lfo_offset_inc;
@@ -355,7 +355,7 @@ function set_LFO_spread(idx, v)
355355
delta ? (
356356
/* L phase gets −delta, R phase +delta */
357357
mem[LFO_PHASE_L_OFFSET] = mod_phase(mem[LFO_PHASE_L_OFFSET] - delta);
358-
mem[LFO_PHASE_R_OFFSET + 1] = mod_phase(mem[LFO_PHASE_R_OFFSET + 1] + delta);
358+
mem[LFO_PHASE_R_OFFSET] = mod_phase(mem[LFO_PHASE_R_OFFSET] + delta);
359359
mem[LFO_SPREAD_OFFSET] = v;
360360
);
361361
);

JSFX/Audio/RCModEQ/dependencies/router.jsfx-inc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,15 @@ function unlink_router_routes_with_src_lfo(src_mod_idx)
233233

234234
function set_dirty_for_router_routes_with_src_mod(src_mod_idx)
235235
local(i, mem, is_dirty_mem)
236-
global(g_router_active_route_count, ROUTER_IS_DIRTY_MEM_POS_OFFSET)
236+
global(g_router_active_route_count, ROUTER_SRC_IDX_OFFSET, ROUTER_IS_DIRTY_MEM_POS_OFFSET)
237237
(
238238
i = 0;
239239
loop(g_router_active_route_count,
240240
mem = get_router_active_mem_pos(i);
241-
is_dirty_mem = mem[ROUTER_IS_DIRTY_MEM_POS_OFFSET];
242-
is_dirty_mem ? is_dirty_mem[] = 1;
241+
mem[ROUTER_SRC_IDX_OFFSET] == src_mod_idx ? (
242+
is_dirty_mem = mem[ROUTER_IS_DIRTY_MEM_POS_OFFSET];
243+
is_dirty_mem ? is_dirty_mem[] = 1;
244+
);
243245
i += 1;
244246
);
245247
);

0 commit comments

Comments
 (0)