Files
SonicForgeStudio/native_host/NativeMixer.h
T

55 lines
1.8 KiB
C++

// NativeMixer.h — track gain/pan + master brickwall limiter (T13).
//
// MIRROR server render pipeline (`app/core/render_engine.py` track volume/pan
// + `app/core/mastering_engine.py` _apply_limiter):
// - track gain: 10^(dB/20)
// - pan constant-power: theta = ((pan+1)/2)*pi/2, L *= cos(theta), R *= sin(theta)
// (pan == 0 -> unity, khong nhan — dung nhu render_engine.py)
// - master: tong cac track (processInPlace ap dung gain/pan roi limiter)
// - brickwall limiter: t_lin = 10^(thresholdDb/20) (clamp -24..0, default -1);
// k = 1/max(0.02, t_lin); tk = tanh(k); out = tanh(x*k)/tk; roi hard clip [-1,1]
// (clip giong render_project sau apply_mastering).
//
// Audio thread an toan: chi setTrack/setLimiter tu UI thread truoc khi
// AudioStart; processInPlace doc state da set, khong lock, khong cap phat.
#pragma once
#include <cstdint>
#include <cmath>
namespace sonicforge {
using int32 = int32_t;
struct TrackGainPan
{
float gainLin = 1.0f; // 10^(dB/20)
float panL = 1.0f; // cos(theta)
float panR = 1.0f; // sin(theta)
static TrackGainPan fromDbPan (float gainDb, float pan);
};
class NativeMixer
{
public:
// gainDb: -inf..+inf dB; pan: -1..+1 (clamp). Mirrors render_engine.py.
void setTrack (const TrackGainPan& t) { m_track = t; }
// thresholdDb clamp -24..0, NaN -> -1 (mirror _clamp trong mastering_engine).
void setLimiter (bool active, float thresholdDb);
// Ap track gain/pan vao buffer roi (neu active) limiter + hard clip [-1,1]
// ngay tai buffer (in-place). frames > 0.
void processInPlace (float* outL, float* outR, int32 frames) const;
bool limiterActive () const { return m_limActive; }
private:
TrackGainPan m_track;
bool m_limActive = false;
float m_limK = 1.0f; // 1/max(0.02, t_lin)
float m_limTk = 1.0f; // tanh(k)
};
} // namespace sonicforge