# HG changeset patch # User Chris Cannam # Date 1405604247 -3600 # Node ID 57990edc441b5c58b9295dd616e2502c92c495f0 # Parent f21753c504e1355828346c2e84b34cac1cf80e9d Various fixes diff -r f21753c504e1 -r 57990edc441b Makefile --- a/Makefile Thu Jul 17 13:27:07 2014 +0100 +++ b/Makefile Thu Jul 17 14:37:27 2014 +0100 @@ -1,5 +1,7 @@ -CXXFLAGS := -DLADSPA -fpic -O3 -ffast-math -msse -msse2 -mfpmath=sse -ftree-vectorize +#CXXFLAGS := -DLADSPA -fpic -O3 -ffast-math -msse -msse2 -mfpmath=sse -ftree-vectorize + +CXXFLAGS := -DLADSPA -fpic -g SOURCES := flattendynamics-ladspa.cpp OBJECTS := flattendynamics-ladspa.o diff -r f21753c504e1 -r 57990edc441b flattendynamics-ladspa.cpp --- a/flattendynamics-ladspa.cpp Thu Jul 17 13:27:07 2014 +0100 +++ b/flattendynamics-ladspa.cpp Thu Jul 17 14:37:27 2014 +0100 @@ -2,11 +2,15 @@ #include "flattendynamics-ladspa.h" -#include #include #include +using std::cerr; +using std::endl; + const float historySeconds = 4.f; +const float catchUpSeconds = 0.5f; +const float targetRMS = 0.1f; const char *const FlattenDynamics::portNames[PortCount] = @@ -41,7 +45,7 @@ 0xf0b375, // "Unique" ID "flattendynamics", // Label properties, - "FlattenDynamics", // Name + "Flatten Dynamics", // Name "Queen Mary, University of London", // Maker "BSD", // Copyright PortCount, @@ -96,7 +100,7 @@ void FlattenDynamics::connectPort(LADSPA_Handle handle, - unsigned long port, LADSPA_Data *location) + unsigned long port, LADSPA_Data *location) { FlattenDynamics *flatten = (FlattenDynamics *)handle; @@ -140,7 +144,8 @@ { delete m_history; m_histlen = int(round(m_sampleRate * historySeconds)); - m_history = new float(m_histlen); + if (m_histlen < 1) m_histlen = 1; + m_history = new float[m_histlen]; m_histwrite = 0; m_histread = 0; @@ -166,10 +171,7 @@ // * peak level does not clip // We aim to take M seconds to move to our target gain - int i = 0; - const int sc = sampleCount; - - while (i < sc) { + for (int i = 0; i < sampleCount; ++i) { m_output[i] = process(m_input[i]); } } @@ -178,6 +180,20 @@ FlattenDynamics::process(float f) { updateRMS(f); + + if (m_rms == 0.f) { + return f; + } + + float targetGain = targetRMS / m_rms; + float catchUpSamples = catchUpSeconds * m_sampleRate; + // asymptotic, could improve? + m_gain = m_gain + (targetGain - m_gain) / catchUpSamples; + if (fabsf(f) * m_gain > 1.f) { + m_gain = 1.f / fabsf(f); + } +// cerr << "target gain = " << targetGain << ", gain = " << m_gain << endl; + return f * m_gain; } void @@ -186,26 +202,26 @@ int nextWrite = (m_histwrite + 1) % m_histlen; float lose; - int fill; if (nextWrite == m_histread) { // full lose = m_history[m_histread]; m_histread = (m_histread + 1) % m_histlen; - fill = m_histlen; } else { // not full lose = 0.f; - fill = (m_histwrite - m_histread + m_histlen) % m_histlen; } m_history[m_histwrite] = f; m_histwrite = nextWrite; + int fill = (m_histwrite - m_histread + m_histlen) % m_histlen; + m_sumOfSquares -= lose * lose; m_sumOfSquares += f * f; m_rms = sqrt(m_sumOfSquares / fill); +// cerr << "rms = " << m_rms << " (from " << fill << " samples of " << m_histlen << ", latest " << f << ")" << endl; } const LADSPA_Descriptor *