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
|
/*
* Copyright (C) 2025 Linux Studio Plugins Project <https://lsp-plug.in/>
* (C) 2025 Vladimir Sadovnikov <sadko4u@gmail.com>
*
* This file is part of lsp-plugins-ringmod-sc
* Created on: 29 авг 2025 г.
*
* lsp-plugins-ringmod-sc 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-ringmod-sc 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-ringmod-sc. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef PRIVATE_PLUGINS_RINGMOD_SC_H_
#define PRIVATE_PLUGINS_RINGMOD_SC_H_
#include <lsp-plug.in/dsp-units/ctl/Bypass.h>
#include <lsp-plug.in/dsp-units/util/Delay.h>
#include <lsp-plug.in/dsp-units/util/MeterGraph.h>
#include <lsp-plug.in/dsp-units/util/RingBuffer.h>
#include <lsp-plug.in/plug-fw/plug.h>
#include <lsp-plug.in/plug-fw/core/IDBuffer.h>
#include <private/meta/ringmod_sc.h>
namespace lsp
{
namespace plugins
{
/**
* Base class for the latency compensation delay
*/
class ringmod_sc: public plug::Module
{
protected:
enum sc_type_t
{
SC_TYPE_INTERNAL,
SC_TYPE_EXTERNAL,
SC_TYPE_SHM_LINK,
};
enum sc_source_t
{
SC_SRC_LEFT_RIGHT,
SC_SRC_RIGHT_LEFT,
SC_SRC_LEFT,
SC_SRC_RIGHT,
SC_SRC_MID_SIDE,
SC_SRC_SIDE_MID,
SC_SRC_MIDDLE,
SC_SRC_SIDE,
SC_SRC_MIN,
SC_SRC_MAX
};
enum meter_graph_t
{
MG_IN,
MG_SC,
MG_GAIN,
MG_OUT,
MG_TOTAL
};
typedef struct io_buffers_t
{
float *vIn;
float *vOut;
float *vScIn;
float *vShmIn;
float *vMixSc;
} io_buffers_t;
typedef struct premix_t
{
float fInToSc; // Input -> Sidechain mix
float fInToLink; // Input -> Link mix
float fLinkToIn; // Link -> Input mix
float fLinkToSc; // Link -> Sidechain mix
float fScToIn; // Sidechain -> Input mix
float fScToLink; // Sidechain -> Link mix
float *vIn[2]; // Input buffer
float *vOut[2]; // Output buffer
float *vSc[2]; // Sidechain buffer
float *vLink[2]; // Link buffer
float *vTmpIn[2]; // Replacement buffer for input
float *vTmpLink[2]; // Replacement buffer for link
float *vTmpSc[2]; // Replacement buffer for sidechain
plug::IPort *pInToSc; // Input -> Sidechain mix
plug::IPort *pInToLink; // Input -> Link mix
plug::IPort *pLinkToIn; // Link -> Input mix
plug::IPort *pLinkToSc; // Link -> Sidechain mix
plug::IPort *pScToIn; // Sidechain -> Input mix
plug::IPort *pScToLink; // Sidechain -> Link mix
} premix_t;
typedef struct channel_t
{
// DSP processing modules
dspu::Bypass sBypass; // Bypass
dspu::Delay sInDelay; // Input signal delay
dspu::Delay sScDelay; // Sidechain input delay
dspu::RingBuffer sEnvDelay; // Sidechain envelope delay buffer
dspu::MeterGraph vGraph[MG_TOTAL]; // Meter graphs
float fPeak; // Current sidechain peak value
uint32_t nHold; // Hold counter
bool vVisible[MG_TOTAL]; // Meter visibility
float vValues[MG_TOTAL]; // Meter values
float *vInData; // Input signal data
float *vBuffer; // Temporary data
// Ports
plug::IPort *pIn; // Input port
plug::IPort *pOut; // Output port
plug::IPort *pScIn; // Sidechain input port
plug::IPort *pShmIn; // Shared memory link input port
plug::IPort *vVisibility[MG_TOTAL]; // Meters visibility
plug::IPort *vMeters[MG_TOTAL]; // Meters
} channel_t;
protected:
uint32_t nChannels; // Number of channels
channel_t *vChannels; // Processing channels
float *vEmptyBuffer; // Empty buffer for audio processing
float *vTime; // Mesh time points
float *vBuffer; // Temporary buffer for audio processing
float *vIDisplay; // Inline display buffer
premix_t sPremix; // Sidechain pre-mix
uint32_t nType; // Sidechain type
uint32_t nSource; // Sidechain source
uint32_t nLookahead; // Lookahead
uint32_t nDuck; // Ducking
uint32_t nHold; // Hold signal
float fTauRelease; // Release time constant
float fStereoLink; // Stereo linking
float fInGain; // Input gain
float fOutGain; // Output gain
float fScGain; // Sidechain gain
float fAmount; // The amount of data to subtract
float fDry; // Dry amount of signal
float fWet; // Wet amount of signal
bool bOutIn; // Output inpug signal
bool bOutSc; // Output sidechain value
bool bActive; // Sidechain processing is active
bool bInvert; // Invert sidechain processing
bool bPause; // Pause output graph
bool bClear; // Clear output graph
bool bUISync; // Synchronize mesh with UI
core::IDBuffer *pIDisplay; // Inline display buffer
plug::IPort *pBypass; // Bypass
plug::IPort *pGainIn; // Input gain
plug::IPort *pGainSc; // Sidechain gain
plug::IPort *pGainOut; // Output gain
plug::IPort *pOutIn; // Output input signal
plug::IPort *pOutSc; // Output sidechain
plug::IPort *pActive; // Sidechain processing is active
plug::IPort *pInvert; // Invert sidechain processing
plug::IPort *pType; // Sidechain type
plug::IPort *pSource; // Sidechain source
plug::IPort *pStereoLink; // Stereo linking
plug::IPort *pHold; // Hold time
plug::IPort *pRelease; // Release time
plug::IPort *pLookahead; // Lookahead time
plug::IPort *pDuck; // Duck time
plug::IPort *pAmount; // Amount
plug::IPort *pDry; // Dry gain
plug::IPort *pWet; // Wet gain
plug::IPort *pDryWet; // Dry/Wet balance
plug::IPort *pGraphMesh; // Meter graph mesh
plug::IPort *pPause; // Pause graph processing
plug::IPort *pClear; // Clear
uint8_t *pData; // Allocated data
protected:
void do_destroy();
void update_premix();
void premix_channels(io_buffers_t *io, size_t samples);
void process_sidechain_type(float **sc, io_buffers_t *io_buf, size_t samples);
void process_sidechain_envelope(float **sc, size_t samples);
void process_sidechain_delays(float **sc, size_t samples);
void process_sidechain_stereo_link(float **sc, size_t samples);
void apply_sidechain_signal(io_buffers_t *io_buf, size_t samples);
void output_meters();
void output_meshes();
public:
explicit ringmod_sc(const meta::plugin_t *meta);
ringmod_sc (const ringmod_sc &) = delete;
ringmod_sc (ringmod_sc &&) = delete;
virtual ~ringmod_sc() override;
ringmod_sc & operator = (const ringmod_sc &) = delete;
ringmod_sc & operator = (ringmod_sc &&) = 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 ui_activated() override;
virtual void process(size_t samples) 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_RINGMOD_SC_H_ */
|