24 , mCompressor {
std::move(other.mCompressor) }
25 , mSlaves {
std::move(other.mSlaves) }
26 , mSampleCounter {
std::move(other.mSampleCounter) }
27 , mSampleRate {
std::move(other.mSampleRate) }
28 , mOutputQueue {
std::move(other.mOutputQueue) }
29 , mCompressionValueQueue {
std::move(other.mCompressionValueQueue) }
42 mSlaves.front().mCompressor->GetSettings().lookaheadMs;
46 std::weak_ptr<DynamicRangeProcessorOutputPacketQueue> outputQueue)
50 slave.mOutputQueue = outputQueue;
54 std::weak_ptr<DynamicRangeProcessorMeterValuesQueue> queue)
58 slave.mCompressionValueQueue = queue;
87 auto leastRatio = 0.f;
88 for (
size_t i = 0; i < blockLen; ++i)
90 const auto absIn = std::abs(in[i]);
93 leastRatio = std::max(std::abs(out[i]) / absIn, leastRatio);
95 return leastRatio == 0 ? -std::numeric_limits<float>::infinity() :
102 float*
const* outBlock,
size_t blockLen)
123 slave.mCompressor->Reinit();
158 float*
const* outbuf,
size_t numSamples)
163 auto& compressor = *slave.mCompressor;
164 const auto numProcessedSamples =
166 if (
const auto queue = slave.mOutputQueue.lock())
168 const auto& frameStats = compressor.GetLastFrameStats();
169 const auto& compressorSettings = compressor.GetSettings();
170 const float netGain = compressorSettings.outCompressionThreshDb -
171 compressorSettings.inCompressionThreshDb;
172 const auto targetCompressionDb =
173 compressor.EvaluateTransferFunction(frameStats.maxInputSampleDb) -
174 frameStats.maxInputSampleDb - netGain;
180 newPacket.
inputDb = frameStats.maxInputSampleDb;
182 queue->Put(newPacket);
185 if (
const auto queue = slave.mCompressionValueQueue.lock())
187 compressor.GetLastFrameStats().dbGainOfMaxInputSample,
189 compressor.GetLastFrameStats(), compressor.GetSettings()) });
191 slave.mSampleCounter += numProcessedSamples;
192 return numProcessedSamples;
203 mSlaves[group].mSampleCounter += numSamples;
219 const float*
const* inBlock,
float*
const* outBlock,
size_t blockLen)
222 instance.
Process(inBlock, outBlock, blockLen);
constexpr float FastLog2(float x)
Approximates the base-2 logarithm of a float to two decimal places, adapted from https://stackoverflo...
static constexpr float log2ToDb
static Settings & settings()
void SetMeterValuesQueue(std::weak_ptr< DynamicRangeProcessorMeterValuesQueue > queue)
size_t InstanceProcess(EffectSettings &settings, CompressorProcessor &instance, const float *const *inBlock, float *const *outBlock, size_t blockLen)
bool ProcessInitialize(EffectSettings &settings, double sampleRate, ChannelNames chanMap) override
std::weak_ptr< DynamicRangeProcessorMeterValuesQueue > mCompressionValueQueue
float GetLatencyMs() const
EffectInstance::SampleCount GetLatency(const EffectSettings &settings, double sampleRate) const override
bool RealtimeInitialize(EffectSettings &settings, double sampleRate) override
std::optional< double > mSampleRate
const std::optional< double > & GetSampleRate() const
std::weak_ptr< DynamicRangeProcessorOutputPacketQueue > mOutputQueue
CompressorInstance(const PerTrackEffect &effect)
bool RealtimeFinalize(EffectSettings &settings) noexcept override
void RealtimePassThrough(size_t group, EffectSettings &settings, const float *const *inbuf, size_t numSamples) override
Called instead of RealtimeProcess when the effect is bypassed. Default implementation does nothing.
size_t ProcessBlock(EffectSettings &settings, const float *const *inBlock, float *const *outBlock, size_t blockLen) override
Called for destructive effect computation.
void InstanceInit(EffectSettings &settings, CompressorInstance &instance, int numChannels, float sampleRate)
size_t RealtimeProcess(size_t group, EffectSettings &settings, const float *const *inbuf, float *const *outbuf, size_t numSamples) override
unsigned GetAudioInCount() const override
How many input buffers to allocate at once.
std::unique_ptr< CompressorProcessor > mCompressor
unsigned GetAudioOutCount() const override
How many output buffers to allocate at once.
std::vector< CompressorInstance > mSlaves
void SetOutputQueue(std::weak_ptr< DynamicRangeProcessorOutputPacketQueue >)
bool ProcessFinalize() noexcept override
bool RealtimeResume() override
bool RealtimeAddProcessor(EffectSettings &settings, EffectOutputs *pOutputs, unsigned numChannels, float sampleRate) override
void ApplySettingsIfNeeded(const DynamicRangeProcessorSettings &settings)
void Process(const float *const *inBlock, float *const *outBlock, int blockLen)
static float GetMakeupGainDb(const DynamicRangeProcessorSettings &settings)
size_t SetBlockSize(size_t maxBlockSize) override
size_t GetBlockSize() const override
Hold values to send to effect output meters.
CallbackReturn Publish(const Message &message)
Send a message to connected callbacks.
const PerTrackEffect & mProcessor
Base class for many of the effects in Audacity.
constexpr auto sampleRate
DynamicRangeProcessorSettings GetDynamicRangeProcessorSettings(const EffectSettings &settings)
auto GetMaxDbIncrease(const float *in, const float *out, size_t blockLen)
float GetOutputDb(const CompressorProcessor::FrameStats &stats, const DynamicRangeProcessorSettings &settings)
float dbGainOfMaxInputSample
long long indexOfFirstSample
float targetCompressionDb
float actualCompressionDb
Externalized state of a plug-in.