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
|
/*
* Copyright (C) 2021 Linux Studio Plugins Project <https://lsp-plug.in/>
* (C) 2021 Vladimir Sadovnikov <sadko4u@gmail.com>
*
* This file is part of lsp-plugins-impulse-responses
* Created on: 3 авг. 2021 г.
*
* lsp-plugins-impulse-responses 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-impulse-responses 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-impulse-responses. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef PRIVATE_PLUGINS_IMPULSE_RESPONSES_H_
#define PRIVATE_PLUGINS_IMPULSE_RESPONSES_H_
#include <lsp-plug.in/plug-fw/plug.h>
#include <lsp-plug.in/dsp-units/ctl/Toggle.h>
#include <lsp-plug.in/dsp-units/ctl/Bypass.h>
#include <lsp-plug.in/dsp-units/filters/Equalizer.h>
#include <lsp-plug.in/dsp-units/sampling/Sample.h>
#include <lsp-plug.in/dsp-units/sampling/SamplePlayer.h>
#include <lsp-plug.in/dsp-units/util/Convolver.h>
#include <lsp-plug.in/dsp-units/util/Delay.h>
#include <private/meta/impulse_responses.h>
namespace lsp
{
namespace plugins
{
/**
* Impulse Responses Plugin Series
*/
class impulse_responses: public plug::Module
{
protected:
class IRLoader;
typedef struct af_descriptor_t
{
dspu::Toggle sListen; // Listen toggle
dspu::Sample *pOriginal; // Original file sample
dspu::Sample *pProcessed; // Processed file sample by the reconfigure() call
float *vThumbs[meta::impulse_responses_metadata::TRACKS_MAX]; // Thumbnails
float fNorm; // Norming factor
status_t nStatus;
bool bSync; // Synchronize file
float fHeadCut;
float fTailCut;
float fFadeIn;
float fFadeOut;
IRLoader *pLoader; // Audio file loader task
plug::IPort *pFile; // Port that contains file name
plug::IPort *pHeadCut;
plug::IPort *pTailCut;
plug::IPort *pFadeIn;
plug::IPort *pFadeOut;
plug::IPort *pListen;
plug::IPort *pStatus; // Status of file loading
plug::IPort *pLength; // Length of file
plug::IPort *pThumbs; // Thumbnails of file
} af_descriptor_t;
typedef struct channel_t
{
dspu::Bypass sBypass;
dspu::Delay sDelay;
dspu::SamplePlayer sPlayer;
dspu::Equalizer sEqualizer; // Wet signal equalizer
dspu::Convolver *pCurr;
dspu::Convolver *pSwap;
float *vIn;
float *vOut;
float *vBuffer;
float fDryGain;
float fWetGain;
size_t nSource;
plug::IPort *pIn;
plug::IPort *pOut;
plug::IPort *pSource;
plug::IPort *pMakeup;
plug::IPort *pActivity;
plug::IPort *pPredelay;
plug::IPort *pWetEq; // Wet equalization flag
plug::IPort *pLowCut; // Low-cut flag
plug::IPort *pLowFreq; // Low-cut frequency
plug::IPort *pHighCut; // High-cut flag
plug::IPort *pHighFreq; // Low-cut frequency
plug::IPort *pFreqGain[meta::impulse_responses_metadata::EQ_BANDS]; // Gain for each band of the Equalizer
} channel_t;
class IRLoader: public ipc::ITask
{
private:
impulse_responses *pCore;
af_descriptor_t *pDescr;
public:
explicit IRLoader(impulse_responses *base, af_descriptor_t *descr);
virtual ~IRLoader();
public:
virtual status_t run();
void dump(dspu::IStateDumper *v) const;
};
class IRConfigurator: public ipc::ITask
{
private:
impulse_responses *pCore;
public:
explicit IRConfigurator(impulse_responses *base);
virtual ~IRConfigurator();
public:
virtual status_t run();
void dump(dspu::IStateDumper *v) const;
};
class GCTask: public ipc::ITask
{
private:
impulse_responses *pCore;
public:
explicit GCTask(impulse_responses *base);
virtual ~GCTask();
public:
virtual status_t run();
void dump(dspu::IStateDumper *v) const;
};
protected:
bool has_active_loading_tasks();
status_t load(af_descriptor_t *descr);
status_t reconfigure();
void process_configuration_tasks();
void process_loading_tasks();
void process_gc_events();
void process_listen_events();
void perform_convolution(size_t samples);
void output_parameters();
void perform_gc();
protected:
static void destroy_samples(dspu::Sample *gc_list);
static void destroy_sample(dspu::Sample * &s);
static void destroy_convolver(dspu::Convolver * &c);
static void destroy_file(af_descriptor_t *af);
static void destroy_channel(channel_t *c);
static size_t get_fft_rank(size_t rank);
protected:
IRConfigurator sConfigurator;
GCTask sGCTask;
size_t nChannels;
channel_t *vChannels;
af_descriptor_t *vFiles;
ipc::IExecutor *pExecutor;
size_t nReconfigReq;
size_t nReconfigResp;
float fGain;
size_t nRank;
dspu::Sample *pGCList; // Garbage collection list
plug::IPort *pBypass;
plug::IPort *pRank;
plug::IPort *pDry;
plug::IPort *pWet;
plug::IPort *pOutGain;
uint8_t *pData;
public:
explicit impulse_responses(const meta::plugin_t *meta);
virtual ~impulse_responses();
virtual void init(plug::IWrapper *wrapper, plug::IPort **ports);
virtual void destroy();
public:
virtual void ui_activated();
virtual void update_settings();
virtual void update_sample_rate(long sr);
virtual void process(size_t samples);
virtual void dump(dspu::IStateDumper *v) const;
};
} // namespace plugins
} // namespace lsp
#endif /* PRIVATE_PLUGINS_IMPULSE_RESPONSES_H_ */
|