desc: EKIX Gain Matcher 

in_pin:Input L
in_pin:Input R
in_pin:Sidechain L
in_pin:Sidechain R
out_pin:Output L
out_pin:Output R

slider1:250<50,3000,10> Averaging Time (ms)
slider2:0<-24,24,0.1> Gain Offset (dB)
slider3:5<0.1,5,0.1> Max Gain (x)
slider4:0.11<0.1,5,0.1> Min Gain (x)
slider5:0.1<0.001,1,0.001> Gain Smoothing (0=hart, 1=sehr weich)
slider6:1<0,1,0.01> Mix (0=kein Matching, 1=volles Matching)

@init
rms_in = 0;
rms_sc = 0;
smoothed_gain = 1;

@slider
window_samples = max(1, srate * (slider1 / 1000));
alpha = 1 / window_samples;
gain_offset_db = slider2;
max_gain = slider3;
min_gain = slider4;
gain_smooth = slider5;
mix = slider6;

@sample
// Read samples
input_L = spl0;
input_R = spl1;
sc_L = spl2;
sc_R = spl3;

// Energy calculation
input_energy = (input_L*input_L + input_R*input_R)*0.5;
sc_energy = (sc_L*sc_L + sc_R*sc_R)*0.5;

// RMS smoothing
rms_in += (input_energy - rms_in) * alpha;
rms_sc += (sc_energy - rms_sc) * alpha;

// Prevent division by zero
rms_in = max(rms_in, 0.0000001);
rms_sc = max(rms_sc, 0.0000001);

// Calculate loudness
input_loudness_db = 10 * log10(rms_in);
sc_loudness_db = 10 * log10(rms_sc);

// Calculate ideal gain
target_gain = 10^((sc_loudness_db - input_loudness_db + gain_offset_db)/20);

// Apply smoothing
smoothed_gain += (target_gain - smoothed_gain) * gain_smooth;

// Limit gain range
smoothed_gain = max(min(smoothed_gain, max_gain), min_gain);

// Scale the gain adjustment by mix value
adjusted_gain = 1 + (smoothed_gain - 1) * mix;

// Apply adjusted gain
spl0 *= adjusted_gain;
spl1 *= adjusted_gain;

