mirror of
https://github.com/LMMS/lmms.git
synced 2026-04-29 02:16:20 -04:00
801 lines
23 KiB
C++
801 lines
23 KiB
C++
/* dynamic.cpp
|
|
|
|
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
|
|
2000-2002 Richard W.E. Furse. The author may be contacted at
|
|
richard@muse.demon.co.uk.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public Licence as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
Licence, or (at your option) any later version.
|
|
|
|
This library 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
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
02111-1307, USA. */
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* This module provides unsophisticated implementations of compressor,
|
|
expander and limiter plugins. Note that attack and decay times are
|
|
applied at the LEVEL DETECTION stage rather than at gain processing
|
|
(the reason no noise gate is provided). No delay is applied to the
|
|
main signal. These are useful (and efficient) tools and extended
|
|
compressors should probably allocate new IDs rather than break
|
|
compatibility in parameter set and sound for this set. */
|
|
|
|
// Having said this, I'm not sure the attack/decay parameters are the
|
|
// right way around.
|
|
|
|
/*****************************************************************************/
|
|
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/*****************************************************************************/
|
|
|
|
#include "cmt.h"
|
|
#include "utils.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
class DynamicProcessor {
|
|
protected:
|
|
|
|
/** This state variable is used to track the input envelope (peak or
|
|
rms). The state is stored here so that the run function can
|
|
perform low-pass filtering to produce a smoothed envelope. */
|
|
LADSPA_Data m_fEnvelopeState;
|
|
|
|
/** The sample rate in the world this instance exists in. */
|
|
LADSPA_Data m_fSampleRate;
|
|
|
|
DynamicProcessor(const LADSPA_Data fSampleRate)
|
|
: m_fSampleRate(fSampleRate) {
|
|
}
|
|
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
#define CE_THRESHOLD 0
|
|
#define CE_RATIO 1
|
|
#define CE_ATTACK 2
|
|
#define CE_DECAY 3
|
|
#define CE_INPUT 4
|
|
#define CE_OUTPUT 5
|
|
|
|
/** This class is used to implement simple compressor and expander
|
|
plugins. Attack and decay times are applied at the level detection
|
|
stage rather than at gain processing. No delay is applied to the
|
|
main signal. Both peak and RMS support is included. */
|
|
class CompressorExpander
|
|
: public CMT_PluginInstance, public DynamicProcessor {
|
|
public:
|
|
|
|
CompressorExpander(const LADSPA_Descriptor *,
|
|
unsigned long lSampleRate)
|
|
: CMT_PluginInstance(6),
|
|
DynamicProcessor(lSampleRate) {
|
|
}
|
|
|
|
friend void activateCompressorExpander(void * pvHandle);
|
|
friend void runCompressor_Peak(LADSPA_Handle Instance,
|
|
unsigned long SampleCount);
|
|
friend void runCompressor_RMS(LADSPA_Handle Instance,
|
|
unsigned long SampleCount);
|
|
friend void runExpander_Peak(LADSPA_Handle Instance,
|
|
unsigned long SampleCount);
|
|
friend void runExpander_RMS(LADSPA_Handle Instance,
|
|
unsigned long SampleCount);
|
|
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
#define LN_THRESHOLD 0
|
|
#define LN_ATTACK 1
|
|
#define LN_DECAY 2
|
|
#define LN_INPUT 3
|
|
#define LN_OUTPUT 4
|
|
|
|
/** This class is used to implement simple limiter plugins. Attack and
|
|
decay times are applied at the level detection stage rather than
|
|
at gain processing. No delay is applied to the main signal. Both
|
|
peak and RMS support is included. */
|
|
class Limiter
|
|
: public CMT_PluginInstance, public DynamicProcessor {
|
|
public:
|
|
|
|
Limiter(const LADSPA_Descriptor *,
|
|
unsigned long lSampleRate)
|
|
: CMT_PluginInstance(5),
|
|
DynamicProcessor(lSampleRate) {
|
|
}
|
|
|
|
friend void activateLimiter(void * pvHandle);
|
|
friend void runLimiter_Peak(LADSPA_Handle Instance,
|
|
unsigned long SampleCount);
|
|
friend void runLimiter_RMS(LADSPA_Handle Instance,
|
|
unsigned long SampleCount);
|
|
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
activateCompressorExpander(void * pvHandle) {
|
|
CompressorExpander * poProcessor = (CompressorExpander *)pvHandle;
|
|
poProcessor->m_fEnvelopeState = 0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
activateLimiter(void * pvHandle) {
|
|
Limiter * poProcessor = (Limiter *)pvHandle;
|
|
poProcessor->m_fEnvelopeState = 0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
runCompressor_Peak(LADSPA_Handle Instance,
|
|
unsigned long SampleCount) {
|
|
|
|
CompressorExpander * poProcessor = (CompressorExpander *)Instance;
|
|
|
|
LADSPA_Data fThreshold
|
|
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[CE_THRESHOLD]),
|
|
0);
|
|
LADSPA_Data fOneOverThreshold
|
|
= 1 / fThreshold;
|
|
LADSPA_Data fRatioMinusOne
|
|
= *(poProcessor->m_ppfPorts[CE_RATIO]) - 1;
|
|
LADSPA_Data * pfInput
|
|
= poProcessor->m_ppfPorts[CE_INPUT];
|
|
LADSPA_Data * pfOutput
|
|
= poProcessor->m_ppfPorts[CE_OUTPUT];
|
|
|
|
LADSPA_Data fEnvelopeDrag_Attack
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
|
|
poProcessor->m_fSampleRate);
|
|
LADSPA_Data fEnvelopeDrag_Decay
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
|
|
poProcessor->m_fSampleRate);
|
|
|
|
LADSPA_Data &rfEnvelopeState
|
|
= poProcessor->m_fEnvelopeState;
|
|
|
|
for (unsigned long lSampleIndex = 0;
|
|
lSampleIndex < SampleCount;
|
|
lSampleIndex++) {
|
|
|
|
LADSPA_Data fInput = *(pfInput++);
|
|
LADSPA_Data fEnvelopeTarget = fabs(fInput);
|
|
if (fEnvelopeTarget > rfEnvelopeState)
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
|
|
else
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
|
|
|
|
/* Perform the mapping. This questions this plugin's claim of
|
|
being `hard-realtime.' */
|
|
LADSPA_Data fGain;
|
|
if (rfEnvelopeState < fThreshold)
|
|
fGain = 1;
|
|
else {
|
|
fGain = pow(rfEnvelopeState * fOneOverThreshold, fRatioMinusOne);
|
|
if (isnan(fGain))
|
|
fGain = 0;
|
|
}
|
|
|
|
/* Perform output. */
|
|
*(pfOutput++) = fInput * fGain;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
runCompressor_RMS(LADSPA_Handle Instance,
|
|
unsigned long SampleCount) {
|
|
|
|
CompressorExpander * poProcessor = (CompressorExpander *)Instance;
|
|
|
|
LADSPA_Data fThreshold
|
|
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[CE_THRESHOLD]),
|
|
0);
|
|
LADSPA_Data fOneOverThreshold
|
|
= 1 / fThreshold;
|
|
LADSPA_Data fRatioMinusOne
|
|
= *(poProcessor->m_ppfPorts[CE_RATIO]) - 1;
|
|
LADSPA_Data * pfInput
|
|
= poProcessor->m_ppfPorts[CE_INPUT];
|
|
LADSPA_Data * pfOutput
|
|
= poProcessor->m_ppfPorts[CE_OUTPUT];
|
|
|
|
LADSPA_Data fEnvelopeDrag_Attack
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
|
|
poProcessor->m_fSampleRate);
|
|
LADSPA_Data fEnvelopeDrag_Decay
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
|
|
poProcessor->m_fSampleRate);
|
|
|
|
LADSPA_Data &rfEnvelopeState
|
|
= poProcessor->m_fEnvelopeState;
|
|
|
|
for (unsigned long lSampleIndex = 0;
|
|
lSampleIndex < SampleCount;
|
|
lSampleIndex++) {
|
|
|
|
LADSPA_Data fInput = *(pfInput++);
|
|
LADSPA_Data fEnvelopeTarget = fInput * fInput;
|
|
if (fEnvelopeTarget > rfEnvelopeState)
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
|
|
else
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
|
|
|
|
LADSPA_Data fEnvelopeAmplitude = sqrt(rfEnvelopeState);
|
|
|
|
/* Perform the mapping. This questions this plugin's claim of
|
|
being `hard-realtime.' */
|
|
LADSPA_Data fGain;
|
|
if (fEnvelopeAmplitude < fThreshold)
|
|
fGain = 1;
|
|
else {
|
|
fGain = pow(fEnvelopeAmplitude * fOneOverThreshold, fRatioMinusOne);
|
|
if (isnan(fGain))
|
|
fGain = 0;
|
|
}
|
|
|
|
/* Perform output. */
|
|
*(pfOutput++) = fInput * fGain;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
runExpander_Peak(LADSPA_Handle Instance,
|
|
unsigned long SampleCount) {
|
|
|
|
CompressorExpander * poProcessor = (CompressorExpander *)Instance;
|
|
|
|
LADSPA_Data fThreshold
|
|
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[CE_THRESHOLD]),
|
|
0);
|
|
LADSPA_Data fOneOverThreshold
|
|
= 1 / fThreshold;
|
|
LADSPA_Data fOneMinusRatio
|
|
= 1 - *(poProcessor->m_ppfPorts[CE_RATIO]);
|
|
LADSPA_Data * pfInput
|
|
= poProcessor->m_ppfPorts[CE_INPUT];
|
|
LADSPA_Data * pfOutput
|
|
= poProcessor->m_ppfPorts[CE_OUTPUT];
|
|
|
|
LADSPA_Data fEnvelopeDrag_Attack
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
|
|
poProcessor->m_fSampleRate);
|
|
LADSPA_Data fEnvelopeDrag_Decay
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
|
|
poProcessor->m_fSampleRate);
|
|
|
|
LADSPA_Data &rfEnvelopeState
|
|
= poProcessor->m_fEnvelopeState;
|
|
|
|
for (unsigned long lSampleIndex = 0;
|
|
lSampleIndex < SampleCount;
|
|
lSampleIndex++) {
|
|
|
|
LADSPA_Data fInput = *(pfInput++);
|
|
LADSPA_Data fEnvelopeTarget = fabs(fInput);
|
|
if (fEnvelopeTarget > rfEnvelopeState)
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
|
|
else
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
|
|
|
|
/* Perform the mapping. This questions this plugin's claim of
|
|
being `hard-realtime.' */
|
|
LADSPA_Data fGain;
|
|
if (rfEnvelopeState > fThreshold)
|
|
fGain = 1;
|
|
else {
|
|
fGain = pow(rfEnvelopeState * fOneOverThreshold, fOneMinusRatio);
|
|
if (isnan(fGain))
|
|
fGain = 0;
|
|
}
|
|
|
|
/* Perform output. */
|
|
*(pfOutput++) = fInput * fGain;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
runExpander_RMS(LADSPA_Handle Instance,
|
|
unsigned long SampleCount) {
|
|
|
|
CompressorExpander * poProcessor = (CompressorExpander *)Instance;
|
|
|
|
LADSPA_Data fThreshold
|
|
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[CE_THRESHOLD]),
|
|
0);
|
|
LADSPA_Data fOneOverThreshold
|
|
= 1 / fThreshold;
|
|
LADSPA_Data fOneMinusRatio
|
|
= 1 - *(poProcessor->m_ppfPorts[CE_RATIO]);
|
|
LADSPA_Data * pfInput
|
|
= poProcessor->m_ppfPorts[CE_INPUT];
|
|
LADSPA_Data * pfOutput
|
|
= poProcessor->m_ppfPorts[CE_OUTPUT];
|
|
|
|
LADSPA_Data fEnvelopeDrag_Attack
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
|
|
poProcessor->m_fSampleRate);
|
|
LADSPA_Data fEnvelopeDrag_Decay
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
|
|
poProcessor->m_fSampleRate);
|
|
|
|
LADSPA_Data &rfEnvelopeState
|
|
= poProcessor->m_fEnvelopeState;
|
|
|
|
for (unsigned long lSampleIndex = 0;
|
|
lSampleIndex < SampleCount;
|
|
lSampleIndex++) {
|
|
|
|
LADSPA_Data fInput = *(pfInput++);
|
|
LADSPA_Data fEnvelopeTarget = fInput * fInput;
|
|
if (fEnvelopeTarget > rfEnvelopeState)
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
|
|
else
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
|
|
|
|
LADSPA_Data fEnvelopeAmplitude = sqrt(rfEnvelopeState);
|
|
|
|
/* Perform the mapping. This questions this plugin's claim of
|
|
being `hard-realtime.' */
|
|
LADSPA_Data fGain;
|
|
if (fEnvelopeAmplitude > fThreshold)
|
|
fGain = 1;
|
|
else {
|
|
fGain = pow(fEnvelopeAmplitude * fOneOverThreshold, fOneMinusRatio);
|
|
if (isnan(fGain))
|
|
fGain = 0;
|
|
}
|
|
|
|
/* Perform output. */
|
|
*(pfOutput++) = fInput * fGain;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
runLimiter_Peak(LADSPA_Handle Instance,
|
|
unsigned long SampleCount) {
|
|
|
|
Limiter * poProcessor = (Limiter *)Instance;
|
|
|
|
LADSPA_Data fThreshold
|
|
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[LN_THRESHOLD]),
|
|
0);
|
|
LADSPA_Data * pfInput
|
|
= poProcessor->m_ppfPorts[LN_INPUT];
|
|
LADSPA_Data * pfOutput
|
|
= poProcessor->m_ppfPorts[LN_OUTPUT];
|
|
|
|
LADSPA_Data fEnvelopeDrag_Attack
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
|
|
poProcessor->m_fSampleRate);
|
|
LADSPA_Data fEnvelopeDrag_Decay
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
|
|
poProcessor->m_fSampleRate);
|
|
|
|
LADSPA_Data &rfEnvelopeState
|
|
= poProcessor->m_fEnvelopeState;
|
|
|
|
for (unsigned long lSampleIndex = 0;
|
|
lSampleIndex < SampleCount;
|
|
lSampleIndex++) {
|
|
|
|
LADSPA_Data fInput = *(pfInput++);
|
|
LADSPA_Data fEnvelopeTarget = fabs(fInput);
|
|
if (fEnvelopeTarget > rfEnvelopeState)
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
|
|
else
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
|
|
|
|
/* Perform the mapping. This questions this plugin's claim of
|
|
being `hard-realtime.' */
|
|
LADSPA_Data fGain;
|
|
if (rfEnvelopeState < fThreshold)
|
|
fGain = 1;
|
|
else {
|
|
fGain = fThreshold / rfEnvelopeState;
|
|
if (isnan(fGain))
|
|
fGain = 0;
|
|
}
|
|
|
|
/* Perform output. */
|
|
*(pfOutput++) = fInput * fGain;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
runLimiter_RMS(LADSPA_Handle Instance,
|
|
unsigned long SampleCount) {
|
|
|
|
Limiter * poProcessor = (Limiter *)Instance;
|
|
|
|
LADSPA_Data fThreshold
|
|
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[LN_THRESHOLD]),
|
|
0);
|
|
LADSPA_Data * pfInput
|
|
= poProcessor->m_ppfPorts[LN_INPUT];
|
|
LADSPA_Data * pfOutput
|
|
= poProcessor->m_ppfPorts[LN_OUTPUT];
|
|
|
|
LADSPA_Data fEnvelopeDrag_Attack
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
|
|
poProcessor->m_fSampleRate);
|
|
LADSPA_Data fEnvelopeDrag_Decay
|
|
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
|
|
poProcessor->m_fSampleRate);
|
|
|
|
LADSPA_Data &rfEnvelopeState
|
|
= poProcessor->m_fEnvelopeState;
|
|
|
|
for (unsigned long lSampleIndex = 0;
|
|
lSampleIndex < SampleCount;
|
|
lSampleIndex++) {
|
|
|
|
LADSPA_Data fInput = *(pfInput++);
|
|
LADSPA_Data fEnvelopeTarget = fInput * fInput;
|
|
if (fEnvelopeTarget > rfEnvelopeState)
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
|
|
else
|
|
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
|
|
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
|
|
|
|
LADSPA_Data fEnvelopeAmplitude = sqrt(rfEnvelopeState);
|
|
|
|
/* Perform the mapping. This questions this plugin's claim of
|
|
being `hard-realtime.' */
|
|
LADSPA_Data fGain;
|
|
if (fEnvelopeAmplitude < fThreshold)
|
|
fGain = 1;
|
|
else {
|
|
fGain = fThreshold / fEnvelopeAmplitude;
|
|
if (isnan(fGain))
|
|
fGain = 0;
|
|
}
|
|
|
|
/* Perform output. */
|
|
*(pfOutput++) = fInput * fGain;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
initialise_dynamic() {
|
|
|
|
CMT_Descriptor * psDescriptor;
|
|
|
|
psDescriptor = new CMT_Descriptor
|
|
(1072,
|
|
"compress_peak",
|
|
LADSPA_PROPERTY_HARD_RT_CAPABLE,
|
|
"Simple Compressor (Peak Envelope Tracking)",
|
|
CMT_MAKER("Richard W.E. Furse"),
|
|
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
|
|
NULL,
|
|
CMT_Instantiate<CompressorExpander>,
|
|
activateCompressorExpander,
|
|
runCompressor_Peak,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Threshold",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_LOGARITHMIC
|
|
| LADSPA_HINT_DEFAULT_1),
|
|
0,
|
|
0);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Compression Ratio",
|
|
(LADSPA_HINT_BOUNDED_ABOVE
|
|
| LADSPA_HINT_DEFAULT_MIDDLE),
|
|
0,
|
|
1);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Attack (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Decay (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
|
"Input");
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
|
"Output");
|
|
registerNewPluginDescriptor(psDescriptor);
|
|
|
|
psDescriptor = new CMT_Descriptor
|
|
(1073,
|
|
"compress_rms",
|
|
LADSPA_PROPERTY_HARD_RT_CAPABLE,
|
|
"Simple Compressor (RMS Envelope Tracking)",
|
|
CMT_MAKER("Richard W.E. Furse"),
|
|
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
|
|
NULL,
|
|
CMT_Instantiate<CompressorExpander>,
|
|
activateCompressorExpander,
|
|
runCompressor_RMS,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Threshold",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_LOGARITHMIC
|
|
| LADSPA_HINT_DEFAULT_1),
|
|
0,
|
|
0);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Compression Ratio",
|
|
(LADSPA_HINT_BOUNDED_ABOVE
|
|
| LADSPA_HINT_DEFAULT_MIDDLE),
|
|
0,
|
|
1);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Attack (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Decay (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
|
"Input");
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
|
"Output");
|
|
registerNewPluginDescriptor(psDescriptor);
|
|
|
|
psDescriptor = new CMT_Descriptor
|
|
(1074,
|
|
"expand_peak",
|
|
LADSPA_PROPERTY_HARD_RT_CAPABLE,
|
|
"Simple Expander (Peak Envelope Tracking)",
|
|
CMT_MAKER("Richard W.E. Furse"),
|
|
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
|
|
NULL,
|
|
CMT_Instantiate<CompressorExpander>,
|
|
activateCompressorExpander,
|
|
runExpander_Peak,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Threshold",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_LOGARITHMIC
|
|
| LADSPA_HINT_DEFAULT_1),
|
|
0,
|
|
0);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Expansion Ratio",
|
|
(LADSPA_HINT_BOUNDED_ABOVE
|
|
| LADSPA_HINT_DEFAULT_MIDDLE),
|
|
0,
|
|
1);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Attack (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Decay (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
|
"Input");
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
|
"Output");
|
|
registerNewPluginDescriptor(psDescriptor);
|
|
|
|
psDescriptor = new CMT_Descriptor
|
|
(1075,
|
|
"expand_rms",
|
|
LADSPA_PROPERTY_HARD_RT_CAPABLE,
|
|
"Simple Expander (RMS Envelope Tracking)",
|
|
CMT_MAKER("Richard W.E. Furse"),
|
|
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
|
|
NULL,
|
|
CMT_Instantiate<CompressorExpander>,
|
|
activateCompressorExpander,
|
|
runExpander_RMS,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Threshold",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_LOGARITHMIC
|
|
| LADSPA_HINT_DEFAULT_1),
|
|
0,
|
|
0);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Expansion Ratio",
|
|
(LADSPA_HINT_BOUNDED_ABOVE
|
|
| LADSPA_HINT_DEFAULT_MIDDLE),
|
|
0,
|
|
1);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Attack (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Decay (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
|
"Input");
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
|
"Output");
|
|
registerNewPluginDescriptor(psDescriptor);
|
|
|
|
psDescriptor = new CMT_Descriptor
|
|
(1076,
|
|
"limit_peak",
|
|
LADSPA_PROPERTY_HARD_RT_CAPABLE,
|
|
"Simple Limiter (Peak Envelope Tracking)",
|
|
CMT_MAKER("Richard W.E. Furse"),
|
|
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
|
|
NULL,
|
|
CMT_Instantiate<Limiter>,
|
|
activateLimiter,
|
|
runLimiter_Peak,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Threshold",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_LOGARITHMIC
|
|
| LADSPA_HINT_DEFAULT_1),
|
|
0,
|
|
0);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Attack (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Decay (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
|
"Input");
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
|
"Output");
|
|
registerNewPluginDescriptor(psDescriptor);
|
|
|
|
psDescriptor = new CMT_Descriptor
|
|
(1077,
|
|
"limit_rms",
|
|
LADSPA_PROPERTY_HARD_RT_CAPABLE,
|
|
"Simple Limiter (RMS Envelope Tracking)",
|
|
CMT_MAKER("Richard W.E. Furse"),
|
|
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
|
|
NULL,
|
|
CMT_Instantiate<Limiter>,
|
|
activateLimiter,
|
|
runLimiter_RMS,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Threshold",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_LOGARITHMIC
|
|
| LADSPA_HINT_DEFAULT_1),
|
|
0,
|
|
0);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Attack (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
|
"Output Envelope Decay (s)",
|
|
(LADSPA_HINT_BOUNDED_BELOW
|
|
| LADSPA_HINT_DEFAULT_MAXIMUM),
|
|
0,
|
|
0.1f);
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
|
"Input");
|
|
psDescriptor->addPort
|
|
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
|
"Output");
|
|
registerNewPluginDescriptor(psDescriptor);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* EOF */
|