@prefix : . @prefix swh: . @prefix foaf: . @prefix doap: . @prefix swhext: . @prefix pg: . @prefix epp: . swh:se4-main_in a pg:Group ; a pg:StereoGroup ; :symbol "main_in" . swh:se4-main_out a pg:Group ; a pg:StereoGroup ; :symbol "main_out" . swh:se4 a :Plugin ; a :CompressorPlugin ; doap:name "SE4" ; doap:maintainer [ foaf:name "Steve Harris"; foaf:homepage ; foaf:mbox ; ] ; doap:license ; :documentation ; :pluginProperty :hardRtCapable ; :port [ a :InputPort, :ControlPort ; :name "RMS/peak" ; :index 0 ; :symbol "rms_peak" ; :minimum 0 ; :maximum 1 ; :default 0 ; ] ; :port [ a :InputPort, :ControlPort ; :name "Attack time (ms)" ; :index 1 ; :symbol "attack" ; :minimum 1.5 ; :maximum 400 ; :default 101.125 ; ] ; :port [ a :InputPort, :ControlPort ; :name "Release time (ms)" ; :index 2 ; :symbol "release" ; :minimum 2 ; :maximum 800 ; :default 401 ; ] ; :port [ a :InputPort, :ControlPort ; :name "Threshold level (dB)" ; :index 3 ; :symbol "threshold" ; :minimum -30 ; :maximum 0 ; :default 0 ; ] ; :port [ a :InputPort, :ControlPort ; :name "Ratio (1:n)" ; :index 4 ; :symbol "ratio" ; :minimum 1 ; :maximum 20 ; :default 1.0 ; ] ; :port [ a :InputPort, :ControlPort ; :name "Knee radius (dB)" ; :index 5 ; :symbol "knee" ; :minimum 1 ; :maximum 10 ; :default 3.25 ; ] ; :port [ a :InputPort, :ControlPort ; :name "Attenuation (dB)" ; :index 6 ; :symbol "attenuation" ; :minimum -24 ; :maximum 0 ; :default 0.0 ; ] ; :port [ a :OutputPort, :ControlPort ; :name "Amplitude (dB)" ; :index 7 ; :symbol "amplitude" ; :minimum -40 ; :maximum +12 ; ] ; :port [ a :OutputPort, :ControlPort ; :name "Gain expansion (dB)" ; :index 8 ; :symbol "gain_exp" ; :minimum 0 ; :maximum +24 ; ] ; :port [ a :InputPort, :AudioPort ; :name "Left input" ; :index 9 ; :symbol "left_in" ; pg:inGroup swh:se4-main_in ; pg:role pg:leftChannel ; ] ; :port [ a :InputPort, :AudioPort ; :name "Right input" ; :index 10 ; :symbol "right_in" ; pg:inGroup swh:se4-main_in ; pg:role pg:rightChannel ; ] ; :port [ a :OutputPort, :AudioPort ; :name "Left output" ; :index 11 ; :symbol "left_out" ; pg:inGroup swh:se4-main_out ; pg:role pg:leftChannel ; ] ; :port [ a :OutputPort, :AudioPort ; :name "Right output" ; :index 12 ; :symbol "right_out" ; pg:inGroup swh:se4-main_out ; pg:role pg:rightChannel ; ] ; swhext:code """ #include "util/db.h" #include "util/rms.h" #define A_TBL 256 """ ; swhext:callback [ swhext:event "instantiate" ; swhext:code """ unsigned int i; float sample_rate = (float)s_rate; rms = rms_env_new(); sum = 0.0f; amp = 0.0f; gain = 0.0f; gain_t = 0.0f; env = 0.0f; env_rms = 0.0f; env_peak = 0.0f; count = 0; as = malloc(A_TBL * sizeof(float)); as[0] = 1.0f; for (i=1; irms); free(plugin_data->as); """ ; ] ; swhext:callback [ swhext:event "run" ; swhext:code """ unsigned long pos; const float ga = attack < 2.0f ? 0.0f : as[f_round(attack * 0.001f * (float)(A_TBL-1))]; const float gr = as[f_round(release * 0.001f * (float)(A_TBL-1))]; const float rs = ratio / (ratio - 1.0f); const float mug = db2lin(attenuation); const float knee_min = db2lin(threshold - knee); const float knee_max = db2lin(threshold + knee); const float ef_a = ga * 0.25f; const float ef_ai = 1.0f - ef_a; for (pos = 0; pos < sample_count; pos++) { const float la = fabs(left_in[pos]); const float ra = fabs(right_in[pos]); const float lev_in = f_max(la, ra); sum += lev_in * lev_in; if (amp > env_rms) { env_rms = env_rms * ga + amp * (1.0f - ga); } else { env_rms = env_rms * gr + amp * (1.0f - gr); } if (lev_in > env_peak) { env_peak = env_peak * ga + lev_in * (1.0f - ga); } else { env_peak = env_peak * gr + lev_in * (1.0f - gr); } if ((count++ & 3) == 3) { amp = rms_env_process(rms, sum * 0.25f); sum = 0.0f; if (isnan(env_rms)) { // This can happen sometimes, but I don't know why env_rms = 0.0f; } env = LIN_INTERP(rms_peak, env_rms, env_peak); if (env <= knee_min) { gain_t = 1.0f; } else if (env < knee_max) { const float x = -(threshold - knee - lin2db(env)) / knee; gain_t = db2lin(-knee * rs * x * x * 0.25f); } else { gain_t = db2lin((threshold - lin2db(env)) * rs); } } gain = gain * ef_a + gain_t * ef_ai; buffer_write(left_out[pos], left_in[pos] * gain * mug); buffer_write(right_out[pos], right_in[pos] * gain * mug); } plugin_data->sum = sum; plugin_data->amp = amp; plugin_data->gain = gain; plugin_data->gain_t = gain_t; plugin_data->env = env; plugin_data->env_rms = env_rms; plugin_data->env_peak = env_peak; plugin_data->count = count; *(plugin_data->amplitude) = lin2db(env); *(plugin_data->gain_exp) = lin2db(gain); """ ; ] ; swhext:createdBy .