T13: NativeMixer mirror server pipeline (track gain/pan constant-power + brickwall limiter tanh, wired VST2/VST3 bridge, golden test 0.0001dB)

This commit is contained in:
2026-08-11 16:53:15 +07:00
parent 8f1e89ce50
commit b9817e1aed
7 changed files with 404 additions and 3 deletions
+90
View File
@@ -0,0 +1,90 @@
// NativeMixer.cpp — xem NativeMixer.h cho cong thuc mirror.
#include "NativeMixer.h"
namespace sonicforge {
namespace {
// Mirror _clamp(v, lo, hi, default) cua mastering_engine.py: NaN -> default.
float clampDb (float v, float lo, float hi, float def)
{
if (!(v == v)) // NaN
return def;
if (v < lo)
return lo;
if (v > hi)
return hi;
return v;
}
} // namespace
TrackGainPan TrackGainPan::fromDbPan (float gainDb, float pan)
{
TrackGainPan t;
t.gainLin = std::pow (10.0f, gainDb / 20.0f);
float p = pan;
if (p < -1.0f)
p = -1.0f;
else if (p > 1.0f)
p = 1.0f;
if (p == 0.0f)
{
t.panL = 1.0f;
t.panR = 1.0f;
}
else
{
const float theta = ((p + 1.0f) / 2.0f) * (3.14159265358979323846f / 2.0f);
t.panL = std::cos (theta);
t.panR = std::sin (theta);
}
return t;
}
void NativeMixer::setLimiter (bool active, float thresholdDb)
{
m_limActive = active;
if (!active)
{
m_limK = 1.0f;
m_limTk = 1.0f;
return;
}
const float t = clampDb (thresholdDb, -24.0f, 0.0f, -1.0f);
const float tLin = std::pow (10.0f, t / 20.0f);
m_limK = 1.0f / (tLin > 0.02f ? tLin : 0.02f);
m_limTk = std::tanh (m_limK);
}
void NativeMixer::processInPlace (float* outL, float* outR, int32 frames) const
{
if (!outL || !outR || frames <= 0)
return;
const float gl = m_track.gainLin * m_track.panL;
const float gr = m_track.gainLin * m_track.panR;
for (int32 i = 0; i < frames; ++i)
{
float l = outL[i] * gl;
float r = outR[i] * gr;
if (m_limActive)
{
l = std::tanh (l * m_limK) / m_limTk;
r = std::tanh (r * m_limK) / m_limTk;
// Hard clip [-1,1] — mirror render_project sau apply_mastering
// (chi khi mastering on; limiter off => khong clip).
if (l > 1.0f)
l = 1.0f;
else if (l < -1.0f)
l = -1.0f;
if (r > 1.0f)
r = 1.0f;
else if (r < -1.0f)
r = -1.0f;
}
outL[i] = l;
outR[i] = r;
}
}
} // namespace sonicforge