mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-18 17:10:05 +02:00
Add Compressor2 realtime debugging utilities.
Signed-off-by: Max Maisel <max.maisel@posteo.de>
This commit is contained in:
parent
aa619de49c
commit
dfffeb76dc
63
scripts/debug/compressor2_trace.m
Normal file
63
scripts/debug/compressor2_trace.m
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
## plot realtime trace data from Compressor2 effect
|
||||||
|
|
||||||
|
stereo = true;
|
||||||
|
bfile = fopen("/tmp/audio.out");
|
||||||
|
|
||||||
|
if stereo
|
||||||
|
width = 15;
|
||||||
|
else
|
||||||
|
width = 13;
|
||||||
|
end
|
||||||
|
|
||||||
|
raw_data = reshape(fread(bfile, 'float'), width, []).';
|
||||||
|
|
||||||
|
data = struct;
|
||||||
|
data.threshold_DB = raw_data(:,1);
|
||||||
|
data.ratio = raw_data(:,2);
|
||||||
|
data.kneewidth_DB = raw_data(:,3);
|
||||||
|
data.attack_time = raw_data(:,4);
|
||||||
|
data.release_time = raw_data(:,5);
|
||||||
|
data.lookahead_time = raw_data(:,6);
|
||||||
|
data.lookbehind_time = raw_data(:,7);
|
||||||
|
data.makeup_gain_pct = raw_data(:,8);
|
||||||
|
data.dry_wet_pct = raw_data(:,9);
|
||||||
|
|
||||||
|
if stereo
|
||||||
|
data.in = horzcat(raw_data(:,10), raw_data(:,11));
|
||||||
|
data.env = raw_data(:,12);
|
||||||
|
data.gain = raw_data(:,13);
|
||||||
|
data.out = horzcat(raw_data(:,14), raw_data(:,15));
|
||||||
|
else
|
||||||
|
data.in = raw_data(:,10);
|
||||||
|
data.env = raw_data(:,11);
|
||||||
|
data.gain = raw_data(:,12);
|
||||||
|
data.out = raw_data(:,13);
|
||||||
|
end
|
||||||
|
|
||||||
|
figure(1);
|
||||||
|
plot(data.in.*100, 'b');
|
||||||
|
hold on;
|
||||||
|
plot(data.out.*100, 'g');
|
||||||
|
plot(data.threshold_DB, 'r');
|
||||||
|
plot(data.ratio, 'r');
|
||||||
|
plot(data.kneewidth_DB, 'r');
|
||||||
|
plot(data.attack_time.*10, 'c', "linewidth", 2);
|
||||||
|
plot(data.release_time.*10, 'c', "linewidth", 2);
|
||||||
|
plot(data.lookahead_time, 'm');
|
||||||
|
plot(data.lookbehind_time, 'm');
|
||||||
|
plot(data.makeup_gain_pct, 'r');
|
||||||
|
plot(data.dry_wet_pct, 'r');
|
||||||
|
plot(data.env.*100, 'k', "linewidth", 2);
|
||||||
|
plot(data.gain.*50, 'k', "linestyle", '--');
|
||||||
|
hold off;
|
||||||
|
grid;
|
||||||
|
|
||||||
|
if stereo
|
||||||
|
legend("in*100", "in*100", "out*100", "out*100", "threshold", "ratio", ...
|
||||||
|
"kneewidth", "attack*10", "release*10", "lookahead", "lookbehind", ...
|
||||||
|
"makeup", "dry/wet", "env*100", "gain*50");
|
||||||
|
else
|
||||||
|
legend("in*100", "out*100", "threshold", "ratio", ...
|
||||||
|
"kneewidth", "attack*10", "release*10", "lookahead", "lookbehind", ...
|
||||||
|
"makeup", "dry/wet", "env*100", "gain*50");
|
||||||
|
end
|
@ -41,10 +41,12 @@
|
|||||||
//#define DEBUG_COMPRESSOR2_DUMP_BUFFERS
|
//#define DEBUG_COMPRESSOR2_DUMP_BUFFERS
|
||||||
//#define DEBUG_COMPRESSOR2_ENV
|
//#define DEBUG_COMPRESSOR2_ENV
|
||||||
//#define DEBUG_COMPRESSOR2_TRACE
|
//#define DEBUG_COMPRESSOR2_TRACE
|
||||||
|
//#define DEBUG_COMPRESSOR2_TRACE2
|
||||||
|
|
||||||
#ifdef DEBUG_COMPRESSOR2_DUMP_BUFFERS
|
#if defined(DEBUG_COMPRESSOR2_DUMP_BUFFERS) or defined(DEBUG_COMPRESSOR2_TRACE2)
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
int buf_num;
|
int buf_num;
|
||||||
|
std::fstream debugfile;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum kAlgorithms
|
enum kAlgorithms
|
||||||
@ -243,6 +245,15 @@ EnvelopeDetector::EnvelopeDetector(size_t buffer_size)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float EnvelopeDetector::AttackFactor()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
float EnvelopeDetector::DecayFactor()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
float EnvelopeDetector::ProcessSample(float value)
|
float EnvelopeDetector::ProcessSample(float value)
|
||||||
{
|
{
|
||||||
float retval = mProcessedBuffer[mPos];
|
float retval = mProcessedBuffer[mPos];
|
||||||
@ -386,6 +397,15 @@ Pt1EnvelopeDetector::Pt1EnvelopeDetector(
|
|||||||
SetParams(rate, attackTime, releaseTime);
|
SetParams(rate, attackTime, releaseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Pt1EnvelopeDetector::AttackFactor()
|
||||||
|
{
|
||||||
|
return mAttackFactor;
|
||||||
|
}
|
||||||
|
float Pt1EnvelopeDetector::DecayFactor()
|
||||||
|
{
|
||||||
|
return mReleaseFactor;
|
||||||
|
}
|
||||||
|
|
||||||
void Pt1EnvelopeDetector::SetParams(
|
void Pt1EnvelopeDetector::SetParams(
|
||||||
float sampleRate, float attackTime, float releaseTime)
|
float sampleRate, float attackTime, float releaseTime)
|
||||||
{
|
{
|
||||||
@ -577,6 +597,12 @@ bool EffectCompressor2::RealtimeAddProcessor(
|
|||||||
mPreproc = InitPreprocessor(mSampleRate);
|
mPreproc = InitPreprocessor(mSampleRate);
|
||||||
mEnvelope = InitEnvelope(mSampleRate, mPipeline[0].size);
|
mEnvelope = InitEnvelope(mSampleRate, mPipeline[0].size);
|
||||||
|
|
||||||
|
mProgressVal = 0;
|
||||||
|
#ifdef DEBUG_COMPRESSOR2_TRACE2
|
||||||
|
debugfile.close();
|
||||||
|
debugfile.open("/tmp/audio.out", std::ios::trunc | std::ios::out);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,6 +616,9 @@ bool EffectCompressor2::RealtimeFinalize()
|
|||||||
mLookaheadTimeCtrl->Enable(true);
|
mLookaheadTimeCtrl->Enable(true);
|
||||||
if(mAlgorithm == kExpFit)
|
if(mAlgorithm == kExpFit)
|
||||||
mAttackTimeCtrl->Enable(true);
|
mAttackTimeCtrl->Enable(true);
|
||||||
|
#ifdef DEBUG_COMPRESSOR2_TRACE2
|
||||||
|
debugfile.close();
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,6 +760,11 @@ bool EffectCompressor2::Process()
|
|||||||
AllocPipeline();
|
AllocPipeline();
|
||||||
mProgressVal = 0;
|
mProgressVal = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG_COMPRESSOR2_TRACE2
|
||||||
|
debugfile.close();
|
||||||
|
debugfile.open("/tmp/audio.out", std::ios::trunc | std::ios::out);
|
||||||
|
#endif
|
||||||
|
|
||||||
for(auto track : mOutputTracks->Selected<WaveTrack>()
|
for(auto track : mOutputTracks->Selected<WaveTrack>()
|
||||||
+ (mStereoInd ? &Track::Any : &Track::IsLeader))
|
+ (mStereoInd ? &Track::Any : &Track::IsLeader))
|
||||||
{
|
{
|
||||||
@ -769,6 +803,9 @@ bool EffectCompressor2::Process()
|
|||||||
mPreproc.reset(nullptr);
|
mPreproc.reset(nullptr);
|
||||||
mEnvelope.reset(nullptr);
|
mEnvelope.reset(nullptr);
|
||||||
FreePipeline();
|
FreePipeline();
|
||||||
|
#ifdef DEBUG_COMPRESSOR2_TRACE2
|
||||||
|
debugfile.close();
|
||||||
|
#endif
|
||||||
return bGoodResult;
|
return bGoodResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1401,6 +1438,34 @@ inline float EffectCompressor2::EnvelopeSample(PipelineBuffer& pbuf, size_t rp)
|
|||||||
inline void EffectCompressor2::CompressSample(float env, size_t wp)
|
inline void EffectCompressor2::CompressSample(float env, size_t wp)
|
||||||
{
|
{
|
||||||
float gain = (1.0 - mDryWet) + CompressorGain(env) * mDryWet;
|
float gain = (1.0 - mDryWet) + CompressorGain(env) * mDryWet;
|
||||||
|
|
||||||
|
#ifdef DEBUG_COMPRESSOR2_TRACE2
|
||||||
|
float ThresholdDB = mThresholdDB;
|
||||||
|
float Ratio = mRatio;
|
||||||
|
float KneeWidthDB = mKneeWidthDB;
|
||||||
|
float AttackTime = mAttackTime;
|
||||||
|
float ReleaseTime = mReleaseTime;
|
||||||
|
float LookaheadTime = mLookaheadTime;
|
||||||
|
float LookbehindTime = mLookbehindTime;
|
||||||
|
float MakeupGainPct = mMakeupGainPct;
|
||||||
|
float DryWetPct = mDryWetPct;
|
||||||
|
|
||||||
|
debugfile.write((char*)&ThresholdDB, sizeof(float));
|
||||||
|
debugfile.write((char*)&Ratio, sizeof(float));
|
||||||
|
debugfile.write((char*)&KneeWidthDB, sizeof(float));
|
||||||
|
debugfile.write((char*)&AttackTime, sizeof(float));
|
||||||
|
debugfile.write((char*)&ReleaseTime, sizeof(float));
|
||||||
|
debugfile.write((char*)&LookaheadTime, sizeof(float));
|
||||||
|
debugfile.write((char*)&LookbehindTime, sizeof(float));
|
||||||
|
debugfile.write((char*)&MakeupGainPct, sizeof(float));
|
||||||
|
debugfile.write((char*)&DryWetPct, sizeof(float));
|
||||||
|
debugfile.write((char*)&mPipeline[0][0][wp], sizeof(float));
|
||||||
|
if(mProcStereo)
|
||||||
|
debugfile.write((char*)&mPipeline[0][1][wp], sizeof(float));
|
||||||
|
debugfile.write((char*)&env, sizeof(float));
|
||||||
|
debugfile.write((char*)&gain, sizeof(float));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_COMPRESSOR2_ENV
|
#ifdef DEBUG_COMPRESSOR2_ENV
|
||||||
if(wp < 100)
|
if(wp < 100)
|
||||||
mPipeline[0][0][wp] = 0;
|
mPipeline[0][0][wp] = 0;
|
||||||
@ -1411,6 +1476,12 @@ inline void EffectCompressor2::CompressSample(float env, size_t wp)
|
|||||||
#endif
|
#endif
|
||||||
if(mProcStereo)
|
if(mProcStereo)
|
||||||
mPipeline[0][1][wp] = mPipeline[0][1][wp] * gain;
|
mPipeline[0][1][wp] = mPipeline[0][1][wp] * gain;
|
||||||
|
|
||||||
|
#ifdef DEBUG_COMPRESSOR2_TRACE2
|
||||||
|
debugfile.write((char*)&mPipeline[0][0][wp], sizeof(float));
|
||||||
|
if(mProcStereo)
|
||||||
|
debugfile.write((char*)&mPipeline[0][1][wp], sizeof(float));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EffectCompressor2::PipelineHasData()
|
bool EffectCompressor2::PipelineHasData()
|
||||||
|
@ -90,6 +90,9 @@ class EnvelopeDetector
|
|||||||
virtual void SetParams(float sampleRate, float attackTime,
|
virtual void SetParams(float sampleRate, float attackTime,
|
||||||
float releaseTime) = 0;
|
float releaseTime) = 0;
|
||||||
|
|
||||||
|
virtual float AttackFactor();
|
||||||
|
virtual float DecayFactor();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t mPos;
|
size_t mPos;
|
||||||
float mInitialCondition;
|
float mInitialCondition;
|
||||||
@ -126,6 +129,8 @@ class Pt1EnvelopeDetector : public EnvelopeDetector
|
|||||||
|
|
||||||
virtual void SetParams(float sampleRate, float attackTime,
|
virtual void SetParams(float sampleRate, float attackTime,
|
||||||
float releaseTime);
|
float releaseTime);
|
||||||
|
virtual float AttackFactor();
|
||||||
|
virtual float DecayFactor();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mCorrectGain;
|
bool mCorrectGain;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user