@@ -3,7 +3,7 @@ JSFX Name: RCModEQ
33Author: RCJacH
44Release Date: Aug 2025
55Link: https://github.com/RCJacH/ReaScripts
6- Version: 1.1 .0
6+ Version: 1.2 .0
77Provides:
88 dependencies/*
99Reference:
@@ -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.
1818Changelog:
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
2934desc: 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
7385import 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;
0 commit comments