1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
|
/*
* Copyright (C) 2023 Linux Studio Plugins Project <https://lsp-plug.in/>
* (C) 2023 Vladimir Sadovnikov <sadko4u@gmail.com>
*
* This file is part of lsp-plugins-clipper
* Created on: 01 дек 2023 г.
*
* lsp-plugins-clipper is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* lsp-plugins-clipper is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with lsp-plugins-clipper. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef PRIVATE_PLUGINS_CLIPPER_H_
#define PRIVATE_PLUGINS_CLIPPER_H_
#include <lsp-plug.in/dsp-units/ctl/Bypass.h>
#include <lsp-plug.in/dsp-units/dynamics/SimpleAutoGain.h>
#include <lsp-plug.in/dsp-units/meters/LoudnessMeter.h>
#include <lsp-plug.in/dsp-units/misc/sigmoid.h>
#include <lsp-plug.in/dsp-units/util/Delay.h>
#include <lsp-plug.in/dsp-units/util/Dither.h>
#include <lsp-plug.in/dsp-units/util/MeterGraph.h>
#include <lsp-plug.in/dsp-units/util/Sidechain.h>
#include <lsp-plug.in/plug-fw/core/IDBuffer.h>
#include <lsp-plug.in/plug-fw/plug.h>
#include <private/meta/clipper.h>
namespace lsp
{
namespace plugins
{
/**
* Clipper plugin
*/
class clipper: public plug::Module
{
protected:
enum clipper_flags_t
{
CF_BOOSTING = 1 << 0, // Enable gain boosting
CF_LUFS_LIMITER = 1 << 1, // Enable LUFS limiter
CF_CLIP_ENABLED = 1 << 2, // Output clipper enabled
CF_ODP_ENABLED = 1 << 3, // Overdrive protection enabled
CF_SYNC_ODP = 1 << 4, // Sync overdrive protection curve
CF_SYNC_CLIP = 1 << 5, // Sync sigmoid clipping curve
CF_SYNC_ALL = CF_SYNC_ODP | CF_SYNC_CLIP
};
enum channel_flags_t
{
CH_IN_GRAPH = 1 << 0, // Input graph visibility
CH_OUT_GRAPH = 1 << 1, // Output graph visibility
CH_RED_GRAPH = 1 << 2 // Gain graph visibility
};
typedef struct compressor_t
{
float x0, x1, x2;
float t;
float a, b, c;
} compressor_t;
// Overdrive protection module
typedef struct odp_params_t
{
float fThreshold; // Threshold
float fKnee; // Knee
plug::IPort *pOn; // Enable overdrive protection
plug::IPort *pThreshold; // Threshold
plug::IPort *pKnee; // Knee
plug::IPort *pReactivity; // Reactivity
plug::IPort *pCurveMesh; // Curve chart mesh
} odp_params_t;
typedef struct clip_params_t
{
dspu::sigmoid::function_t pFunc; // Sigmoid function
float fThreshold; // Threshold
float fPumping; // Pumping
float fScaling; // Sigmoid scaling
float fKnee; // Knee
plug::IPort *pOn; // Enable sigmoid function
plug::IPort *pFunction; // Sigmoid function
plug::IPort *pThreshold; // Sigmoid threshold
plug::IPort *pPumping; // Sigmoid pumping
plug::IPort *pCurveMesh; // Curve chart mesh
} clip_params_t;
typedef struct lufs_limiter_t
{
dspu::LoudnessMeter sMeter; // Input LUFS meter
dspu::SimpleAutoGain sGain; // Input LUFS limiter
float fIn; // Input level
float fRed; // Gain reduction
plug::IPort *pOn; // Enable LUFS limiter
plug::IPort *pIn; // LUFS input level
plug::IPort *pRed; // LUFS gain reduction
plug::IPort *pThreshold; // LUFS limiter threshold
} lufs_limiter_t;
typedef struct channel_t
{
// DSP processing modules
dspu::Bypass sBypass; // Bypass
dspu::Delay sDryDelay; // Delay for the dry signal
dspu::Delay sScDelay; // Sidechain compensation delay
dspu::Sidechain sSc; // Sidechain
dspu::Dither sDither; // Dither
dspu::MeterGraph sInGraph; // Input meter graph
dspu::MeterGraph sOutGraph; // Output meter graph
// Channel flags
uint32_t nFlags; // Channel flags
// Meter values
float fIn; // Input level meter
float fOut; // Output level meter
float fRed; // Reduction level meter
float fOdpIn; // Overdrive protection input level
float fOdpOut; // Overdrive protection out level
float fOdpRed; // Overdrive protection reduction level
float fClipIn; // Clipping input level measured
float fClipOut; // Clipping output level measured
float fClipRed; // Clipping reduction level measured
// Buffers
float *vIn; // Input buffer
float *vOut; // Output buffer
float *vData; // Data buffer
float *vSc; // Sidechain buffer
// Input ports
plug::IPort *pDataIn; // Input port
plug::IPort *pDataOut; // Output port
// Metering
plug::IPort *pInVisible; // Input visibility
plug::IPort *pOutVisible; // Output visibility
plug::IPort *pRedVisible; // Reduction visibility
plug::IPort *pIn; // Input level meter
plug::IPort *pOut; // Output level meter
plug::IPort *pRed; // Reduction level meter
plug::IPort *pOdpIn; // ODP input level meter
plug::IPort *pOdpOut; // ODP output level meter
plug::IPort *pOdpRed; // ODP reduction level meter
plug::IPort *pClipIn; // Clipping input level meter
plug::IPort *pClipOut; // Clipping output level meter
plug::IPort *pClipRed; // Clipping reduction level meter
plug::IPort *pTimeMesh; // Input, output and gain reduction graph mesh
} channel_t;
protected:
static dspu::sigmoid::function_t vSigmoidFunctions[];
protected:
size_t nChannels; // Number of channels
channel_t *vChannels; // Delay channels
dspu::LoudnessMeter sInMeter; // Input LUFS meter
dspu::LoudnessMeter sOutMeter; // Output LUFS meter
compressor_t sComp; // Simple compressor
odp_params_t sOdp; // Overdrive protection params
clip_params_t sClip; // Clipping parameters
lufs_limiter_t sLufs; // LUFS limiter
float fInGain; // Input gain
float fOutGain; // Output gain
float fInLufs; // Output LUFS
float fOutLufs; // Output LUFS
float fThresh; // Threshold
float fStereoLink; // Stereo link
uint32_t nFlags; // Global flags
float *vBuffer; // Temporary buffer
float *vOdp; // Overdrive protection curve input gain values
float *vLinSigmoid; // Linear scale for sigmoid
float *vLogSigmoid; // Logarithmic scale for sigmoid
float *vTime; // Time graph
core::IDBuffer *pIDisplay; // Inline display buffer
plug::IPort *pBypass; // Bypass
plug::IPort *pGainIn; // Input gain
plug::IPort *pGainOut; // Output gain
plug::IPort *pLufsIn; // Input LUFS meter
plug::IPort *pLufsOut; // Output LUFS meter
plug::IPort *pThresh; // Threshold
plug::IPort *pBoosting; // Boosting mode
plug::IPort *pStereoLink; // Stereo linking for output clipper
plug::IPort *pDithering; // Dithering mode
uint8_t *pData; // Allocated data
protected:
static size_t decode_dithering(size_t mode);
static bool update_odp_params(odp_params_t *params);
static bool update_clip_params(clip_params_t *params);
static void calc_odp_compressor(compressor_t *c, const odp_params_t *params);
static inline float odp_curve(const compressor_t *c, float x);
static inline float odp_gain(const compressor_t *c, float x);
static void odp_curve(float *dst, const float *x, const compressor_t *c, size_t count);
static void odp_gain(float *dst, const float *x, const compressor_t *c, size_t count);
static void odp_link(float *dst, const float *src, float link, size_t count);
static float clip_curve(const clip_params_t *p, float x);
static void clip_curve(float *dst, const float *x, const clip_params_t *p, size_t count);
protected:
void do_destroy();
void bind_input_buffers();
void process_clipper(size_t samples);
void output_signal(size_t samples);
void advance_buffers(size_t samples);
void output_meters();
void output_mesh_curves(size_t samples);
public:
explicit clipper(const meta::plugin_t *meta);
clipper (const clipper &) = delete;
clipper (clipper &&) = delete;
virtual ~clipper() override;
clipper & operator = (const clipper &) = delete;
clipper & operator = (clipper &&) = delete;
virtual void init(plug::IWrapper *wrapper, plug::IPort **ports) override;
virtual void destroy() override;
public:
virtual void update_sample_rate(long sr) override;
virtual void update_settings() override;
virtual void process(size_t samples) override;
virtual void ui_activated() override;
virtual bool inline_display(plug::ICanvas *cv, size_t width, size_t height) override;
virtual void dump(dspu::IStateDumper *v) const override;
};
} /* namespace plugins */
} /* namespace lsp */
#endif /* PRIVATE_PLUGINS_CLIPPER_H_ */
|