Mercurial > hg > flattendynamics
diff flattendynamics-ladspa.cpp @ 17:ca4e31d86436
The complicated long-and-short-term approach is not working any better than a simple long-term window. Revert to that, with some decay.
author | Chris Cannam |
---|---|
date | Wed, 23 Jul 2014 15:17:47 +0100 |
parents | c12cab43141d |
children | d25a2e91e9d8 |
line wrap: on
line diff
--- a/flattendynamics-ladspa.cpp Wed Jul 23 10:29:26 2014 +0100 +++ b/flattendynamics-ladspa.cpp Wed Jul 23 15:17:47 2014 +0100 @@ -8,10 +8,9 @@ using std::cerr; using std::endl; -const float longTermSeconds = 4.f; -const float shortTermSeconds = 1.f; +const float historySeconds = 4.f; const float catchUpSeconds = 0.2f; -const float targetMaxRMS = 0.04f; +const float targetMaxRMS = 0.05f; const float rmsMaxDecay = 0.999f; // per sample const float maxGain = 20.f; @@ -82,12 +81,9 @@ m_histlen(0), m_histwrite(0), m_histread(0), - m_sumOfSquaresLongTerm(0.f), - m_sumOfSquaresShortTerm(0.f), - m_rmsLongTerm(0.f), - m_rmsShortTerm(0.f), - m_maxRmsLongTerm(0.f), - m_maxRmsShortTerm(0.f), + m_sumOfSquares(0.f), + m_rms(0.f), + m_maxRms(0.f), m_gain(1.f) { reset(); @@ -168,7 +164,7 @@ FlattenDynamics::reset() { delete[] m_history; - m_histlen = int(round(m_sampleRate * longTermSeconds)); + m_histlen = int(round(m_sampleRate * historySeconds)); if (m_histlen < 1) m_histlen = 1; m_history = new float[m_histlen]; for (int i = 0; i < m_histlen; ++i) { @@ -177,12 +173,9 @@ m_histwrite = 0; m_histread = 0; - m_sumOfSquaresLongTerm = 0.0; - m_sumOfSquaresShortTerm = 0.0; - m_rmsLongTerm = 0.f; - m_rmsShortTerm = 0.f; - m_maxRmsLongTerm = 0.f; - m_maxRmsShortTerm = 0.f; + m_sumOfSquares = 0.0; + m_rms = 0.f; + m_maxRms = 0.f; m_gain = 1.f; } @@ -209,30 +202,17 @@ { updateRMS(f); - if (m_rmsLongTerm == 0.f) { + if (m_rms == 0.f) { return f; } - if (m_rmsLongTerm >= m_maxRmsLongTerm) { - m_maxRmsLongTerm = m_rmsLongTerm; - } else if (m_rmsLongTerm < m_maxRmsLongTerm * rmsMaxDecay) { - m_maxRmsLongTerm *= rmsMaxDecay; + if (m_rms >= m_maxRms) { + m_maxRms = m_rms; + } else { + m_maxRms = m_rms + (m_maxRms - m_rms) * rmsMaxDecay; } - if (m_rmsShortTerm > m_maxRmsShortTerm) { - m_maxRmsShortTerm = m_rmsShortTerm; - } - - float fixedGain = targetMaxRMS / m_maxRmsLongTerm; - - float frac = m_rmsShortTerm / m_maxRmsShortTerm; - - // push up toward top of 0,1 range - frac = pow(frac, 0.3); - - float targetRMS = (frac * m_maxRmsShortTerm); - - float targetGain = fixedGain * (targetRMS / m_rmsShortTerm); + float targetGain = targetMaxRMS / m_maxRms; if (targetGain > maxGain) { targetGain = maxGain; @@ -262,36 +242,23 @@ int nextWrite = (m_histwrite + 1) % m_histlen; - float loseLongTerm = 0.f; - float loseShortTerm = 0.f; + float lose = 0.f; if (nextWrite == m_histread) { // full - loseLongTerm = m_history[m_histread]; + lose = m_history[m_histread]; m_histread = (m_histread + 1) % m_histlen; } - int shortTermLength = round(shortTermSeconds * m_sampleRate); - int shortTermLoseIndex = nextWrite - shortTermLength; - if (shortTermLoseIndex < 0) { - shortTermLoseIndex += m_histlen; - } - // This depends on history being zero-initialised, to be correct at start: - loseShortTerm = m_history[shortTermLoseIndex]; - m_history[m_histwrite] = f; m_histwrite = nextWrite; int fill = (m_histwrite - m_histread + m_histlen) % m_histlen; - m_sumOfSquaresLongTerm -= loseLongTerm * loseLongTerm; - m_sumOfSquaresLongTerm += f * f; + m_sumOfSquares -= lose * lose; + m_sumOfSquares += f * f; - m_sumOfSquaresShortTerm -= loseShortTerm * loseShortTerm; - m_sumOfSquaresShortTerm += f * f; - - m_rmsLongTerm = sqrt(m_sumOfSquaresLongTerm / fill); - m_rmsShortTerm = sqrt(m_sumOfSquaresShortTerm / shortTermLength); + m_rms = sqrt(m_sumOfSquares / fill); // cerr << "rms = " << m_rms << " (from " << fill << " samples of " << m_histlen << ", latest " << f << ")" << endl; }