[SCM] calf/master: save before testing own limiter
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:40:41 UTC 2013
The following commit has been merged in the master branch:
commit 2d3c66fb1197d361c11a8fe019c2828127af6d4c
Author: Markus Schmidt <schmidt at boomshop.net>
Date: Sun Nov 27 08:51:26 2011 +0100
save before testing own limiter
diff --git a/src/audio_fx.cpp b/src/audio_fx.cpp
index 78e56bb..819ba73 100644
--- a/src/audio_fx.cpp
+++ b/src/audio_fx.cpp
@@ -542,39 +542,43 @@ bool simple_lfo::get_dot(float &x, float &y, int &size, cairo_iface *context) co
lookahead_limiter::lookahead_limiter() {
is_active = false;
+
buffer_time = 0.0053;
- num_chunks = 16;
buffer_len = 128;
buffer_pos = 0;
-
+ num_chunks = 16; // length of chunks array
+
/* Find size for power-of-two interleaved delay buffer */
while(buffer_len < srate * buffer_time * 2) {
- buffer_len *= 2;
+ buffer_len *= 2; // (512 @ 48kHz) length of buffer array
}
buffer = (float*) calloc(buffer_len, sizeof(float));
- delay = (int)(0.005 * srate);
+ memset(buffer, 0, num_chunks * sizeof(float)); // reset buffer to zero
+ delay = (int)(0.005 * srate); // (240 @ 48kHz) delay of returned samples in buffer
- chunk_pos = 0;
- chunk_num = 0;
- chunk_size = srate / 2000;
+ chunk_pos = 0; // position in chunk
+ chunk_num = 0; // count of processed chunks
- /* find a chunk size (in smaples) thats roughly 0.5ms */
- //chunk_size = srate / 2000;
chunks = (float*) calloc(num_chunks, sizeof(float));
-
- peak = 0.0f;
- atten = 1.0f;
- atten_lp = 1.0f;
+
+
+ peak = 0.0f; // holds the latest maximum of the input values left and right
+ atten = 1.0f; // holds the "pure" attenuation level
+ atten_lp = 1.0f; // holds the calculated attenuation level
delta = 0.0f;
- atten_max = 1.0;
+
+ atten_max = 1.0; // holds the latest attenuation level since last get_attenuation()
}
void lookahead_limiter::activate()
{
is_active = true;
- memset(buffer, 0, num_chunks * sizeof(float));
+
+ memset(buffer, 0, num_chunks * sizeof(float)); // reset buffer to zero
+
chunk_pos = 0;
chunk_num = 0;
+
peak = 0.0f;
atten = 1.0f;
atten_lp = 1.0f;
@@ -598,75 +602,82 @@ float lookahead_limiter::get_attenuation()
void lookahead_limiter::set_sample_rate(uint32_t sr)
{
srate = sr;
+ /* find a chunk size (in smaples) thats roughly 0.5ms */
+ chunk_size = srate / 2000; // 24 @ 48kHz
}
-void lookahead_limiter::set_params(float l, float r, float g, uint32_t sr)
+void lookahead_limiter::set_params(float l, float r, float g, uint32_t sr, bool d)
{
limit = l;
- release = r / 1000;
+ release = r / 1000.f;
gain = g;
srate = sr;
+ debug = d;
}
void lookahead_limiter::process(float &left, float &right)
{
- const float trim = 1.f;
- float sig;
+ const float trim = 1.f; // output multiplicator (added on input)
+ float sig; // cache for choosing max between peak and max between left and right
unsigned int i;
-
if (chunk_pos++ == chunk_size) {
/* we've got a full chunk */
-
- delta = (1.0f - atten) / (srate * release);
+ // one chunk contains a peak inside [chunk_size] sample blocks
+ delta = (1.0f - atten) / (srate * release); // (0.002083 @ 48kHz/50ms)
round_to_zero(&delta);
+ if(debug) printf("%.5f\n", atten);
for (i=0; i<10; i++) {
+ // cycle over last 10 chunks
const int p = (chunk_num - 9 + i) & (num_chunks - 1);
- const float this_delta = (limit / chunks[p] - atten) /
- ((float)(i) * srate * 0.0005f + 1.0f);
-
+ const float this_delta = (limit / chunks[p] - atten) /
+ ((float)(i) * srate * 0.0005f + 1.0f);
+ if(debug) printf("%.5f - %.5f\n", this_delta, delta);
if (this_delta < delta) {
delta = this_delta;
}
}
+ if(debug) printf("\n");
+ // store actual peak and reset peak to 0.f
chunks[chunk_num++ & (num_chunks - 1)] = peak;
peak = 0.0f;
+
chunk_pos = 0;
+ //if(debug) printf("\ratt: %.4f - - cnum: %d",
+ // atten, chunk_num);
}
-
+
+ // store left and right in buffer array
buffer[(buffer_pos * 2) & (buffer_len - 1)] = left * trim + 1.0e-30;
buffer[(buffer_pos * 2 + 1) & (buffer_len - 1)] = right * trim + 1.0e-30;
-
+
+ // find absolute max between left and right and store it in peak if bigger
sig = fabs(left) > fabs(right) ? fabs(left) : fabs(right);
sig += 1.0e-30;
if (sig * trim > peak) {
peak = sig * trim;
}
-
+
+ // calculate atten and atten_lp
atten += delta;
atten_lp = atten * 0.1f + atten_lp * 0.9f;
if (delta > 0.0f && atten > 1.0f) {
atten = 1.0f;
delta = 0.0f;
}
- atten_max = (atten < atten_max) ? atten : atten_max;
+
+ // return left and right from buffer and multiply with atten_lp
left = buffer[(buffer_pos * 2 - delay * 2) & (buffer_len - 1)] * atten_lp;
right = buffer[(buffer_pos * 2 - delay * 2 + 1) & (buffer_len - 1)] * atten_lp;
+
+ // post treatment (denormal, limit)
round_to_zero(&left);
round_to_zero(&right);
-
- if (left < -limit) {
- left = -limit;
- } else if (left > limit) {
- left = limit;
- }
- if (right < -limit) {
- right = -limit;
- } else if (right > limit) {
- right = limit;
- }
-
- left /= limit;
- right /= limit;
+ std::max(left, -limit);
+ std::min(left, limit);
+ std::max(right, -limit);
+ std::min(right, limit);
+
+ atten_max = (atten < atten_max) ? atten : atten_max; // store max atten for meter output
- buffer_pos++;
+ buffer_pos++; // iterator
}
diff --git a/src/calf/audio_fx.h b/src/calf/audio_fx.h
index 3400acf..7aa5480 100644
--- a/src/calf/audio_fx.h
+++ b/src/calf/audio_fx.h
@@ -600,12 +600,13 @@ private:
unsigned int chunk_size;
float * chunks;
bool is_active;
+ bool debug;
public:
int id;
lookahead_limiter();
void process(float &left, float &right);
void set_sample_rate(uint32_t sr);
- void set_params(float l, float r, float g, uint32_t sr);
+ void set_params(float l, float r, float g, uint32_t sr, bool d = false);
float get_attenuation();
void activate();
void deactivate();
diff --git a/src/modules_limit.cpp b/src/modules_limit.cpp
index 40005f7..b768c17 100644
--- a/src/modules_limit.cpp
+++ b/src/modules_limit.cpp
@@ -134,10 +134,10 @@ void multibandlimiter_audio_module::params_changed()
q_old[2] = *params[param_q2];
}
// set the params of all strips
- strip[0].set_params(*params[param_limit] * 0.66, std::min(1.f / 30, *params[param_release]), 1.f, srate);
- strip[1].set_params(*params[param_limit] * 0.66, std::min(1.f / *params[param_freq0], *params[param_release]), 1.f, srate);
- strip[2].set_params(*params[param_limit] * 0.66, std::min(1.f / *params[param_freq1], *params[param_release]), 1.f, srate);
- strip[3].set_params(*params[param_limit] * 0.66, std::min(1.f / *params[param_freq2], *params[param_release]), 1.f, srate);
+ strip[0].set_params(*params[param_limit], std::max(1.f / 30, *params[param_release]), 1.f, srate);
+ strip[1].set_params(*params[param_limit], std::max(1.f / *params[param_freq0], *params[param_release]), 1.f, srate);
+ strip[2].set_params(*params[param_limit], std::max(1.f / *params[param_freq1], *params[param_release]), 1.f, srate);
+ strip[3].set_params(*params[param_limit], std::max(1.f / *params[param_freq2], *params[param_release]), 1.f, srate, true);
}
void multibandlimiter_audio_module::set_sample_rate(uint32_t sr)
@@ -201,11 +201,14 @@ uint32_t multibandlimiter_audio_module::process(uint32_t offset, uint32_t numsam
// out vars
float outL = 0.f;
float outR = 0.f;
+ int j1;
+ float left;
+ float right;
for (int i = 0; i < strips; i++) {
- float left = inL;
- float right = inR;
+ left = inL;
+ right = inR;
// send trough filters
- int j1;
+
switch(mode) {
case 0:
j1 = 0;
@@ -316,11 +319,13 @@ bool multibandlimiter_audio_module::get_graph(int index, int subindex, float *da
{
if (!is_active or subindex > 3)
return false;
+ float ret;
+ double freq;
+ int j1;
for (int i = 0; i < points; i++)
{
- float ret = 1.f;
- double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
- int j1;
+ ret = 1.f;
+ freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
switch(mode) {
case 0:
j1 = 0;
@@ -347,9 +352,14 @@ bool multibandlimiter_audio_module::get_graph(int index, int subindex, float *da
break;
}
}
- data[i] = dB_grid(ret, 32, 0);
+ data[i] = dB_grid(ret);
+ }
+ if (*params[param_bypass] > 0.5f)
+ context->set_source_rgba(0.35, 0.4, 0.2, 0.3);
+ else {
+ context->set_source_rgba(0.35, 0.4, 0.2, 1);
+ context->set_line_width(1.5);
}
- context->set_line_width(1.5);
return true;
}
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list