From df8ddde8743cd690d497b94d49be4a0513f50e9d Mon Sep 17 00:00:00 2001 From: Steve Daulton Date: Fri, 24 Jul 2015 21:59:34 +0100 Subject: [PATCH] Added dB - linear amplitude conversion macros. --- src/Audacity.h | 5 ++++- src/Envelope.cpp | 2 +- src/TrackArtist.cpp | 16 +++++++-------- src/TrackPanel.cpp | 4 ++-- src/effects/Amplify.cpp | 36 +++++++++++++++++----------------- src/effects/AutoDuck.cpp | 4 ++-- src/effects/BassTreble.cpp | 2 +- src/effects/Compressor.cpp | 4 ++-- src/effects/Contrast.cpp | 2 +- src/effects/Equalization.cpp | 8 ++++---- src/effects/NoiseReduction.cpp | 6 +++--- src/effects/NoiseRemoval.cpp | 6 ++---- src/effects/Normalize.cpp | 5 ++--- src/effects/ScienFilter.cpp | 6 +++--- src/widgets/ASlider.cpp | 6 +++--- src/widgets/Meter.cpp | 4 ++-- 16 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/Audacity.h b/src/Audacity.h index 7b934bca4..536ba922d 100644 --- a/src/Audacity.h +++ b/src/Audacity.h @@ -152,8 +152,11 @@ void QuitAudacity(); #endif #endif -// This macro is used widely, so declared here. +// These macros are used widely, so declared here. #define QUANTIZED_TIME(time, rate) ((double)((sampleCount)floor(((double)(time) * (rate)) + 0.5))) / (rate) +// dB - linear amplitude convesions +#define DB_TO_LINEAR(x) pow(10.0, x / 20.0) +#define LINEAR_TO_DB(x) 20.0 * log10(x) // Marks strings for extraction only...must use wxGetTranslation() to translate. #define XO(s) wxT(s) diff --git a/src/Envelope.cpp b/src/Envelope.cpp index e2eec3ffd..3b62da9c1 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -185,7 +185,7 @@ double Envelope::toDB(double value) double sign = (value >= 0 ? 1 : -1); wxASSERT( dBRange > 0 ); - double db = 20 * log10(fabs(value)); + double db = LINEAR_TO_DB(fabs(value)); double val = (db + dBRange) / dBRange; val = Limit( 0.0, val, 1.0 ); diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 88dbf69e1..993556367 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -706,7 +706,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect) wt->SetDisplay(WaveTrack::WaveformDisplay); // this makes the last display not WaveformDBDisplay float sign = (min >= 0 ? 1 : -1); if (min != 0.) { - min = pow(10., (fabs(min)*mdBrange - mdBrange)/20.0); + min = DB_TO_LINEAR(fabs(min)*mdBrange - mdBrange); if (min < 0.0) min = 0.0; min *= sign; @@ -714,7 +714,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect) sign = (max >= 0 ? 1 : -1); if (max != 0.) { - max = pow(10., (fabs(max)*mdBrange - mdBrange)/20.0); + max = DB_TO_LINEAR(fabs(max)*mdBrange - mdBrange); if (max < 0.0) max = 0.0; max *= sign; @@ -744,7 +744,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect) wt->SetDisplay(WaveTrack::WaveformDBDisplay); // this makes the last display not WaveformDisplay float sign = (min >= 0 ? 1 : -1); if (min != 0.) { - min = (20.0 * log10(fabs(min)) + mdBrange) / mdBrange; + min = (LINEAR_TO_DB(fabs(min)) + mdBrange) / mdBrange; if (min < 0.0) min = 0.0; min *= sign; @@ -752,7 +752,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect) sign = (max >= 0 ? 1 : -1); if (max != 0.) { - max = (20.0 * log10(fabs(max)) + mdBrange) / mdBrange; + max = (LINEAR_TO_DB(fabs(max)) + mdBrange) / mdBrange; if (max < 0.0) max = 0.0; max *= sign; @@ -900,7 +900,7 @@ int GetWaveYPos(float value, float min, float max, float sign = (value >= 0 ? 1 : -1); if (value != 0.) { - float db = 20.0 * log10(fabs(value)); + float db = LINEAR_TO_DB(fabs(value)); value = (db + dBr) / dBr; if (!outer) { value -= 0.5; @@ -941,7 +941,7 @@ float FromDB(float value, double dBRange) return 0; double sign = (value >= 0 ? 1 : -1); - return pow(10.0, ((fabs(value) * dBRange) - dBRange) / 20.0)*sign; + return DB_TO_LINEAR((fabs(value) * dBRange) - dBRange) * sign; } float ValueOfPixel(int yy, int height, bool offset, @@ -3188,8 +3188,8 @@ void TrackArtist::DrawTimeTrack(TimeTrack *track, if(track->GetDisplayLog()) { // MB: silly way to undo the work of GetWaveYPos while still getting a logarithmic scale double dBRange = gPrefs->Read(wxT("/GUI/EnvdBRange"), ENV_DB_RANGE); - lower = 20.0 * log10(std::max(1.0e-7, lower)) / dBRange + 1.0; - upper = 20.0 * log10(std::max(1.0e-7, upper)) / dBRange + 1.0; + lower = LINEAR_TO_DB(std::max(1.0e-7, lower)) / dBRange + 1.0; + upper = LINEAR_TO_DB(std::max(1.0e-7, upper)) / dBRange + 1.0; } track->GetEnvelope()->DrawPoints(dc, envRect, zoomInfo, track->GetDisplayLog(), lower, upper); diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 50633c706..1a55caeb1 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -3810,8 +3810,8 @@ void TrackPanel::ForwardEventToTimeTrackEnvelope(wxMouseEvent & event) if(ptimetrack->GetDisplayLog()) { // MB: silly way to undo the work of GetWaveYPos while still getting a logarithmic scale double dBRange = gPrefs->Read(wxT("/GUI/EnvdBRange"), ENV_DB_RANGE); - lower = 20.0 * log10(std::max(1.0e-7, lower)) / dBRange + 1.0; - upper = 20.0 * log10(std::max(1.0e-7, upper)) / dBRange + 1.0; + lower = LINEAR_TO_DB(std::max(1.0e-7, lower)) / dBRange + 1.0; + upper = LINEAR_TO_DB(std::max(1.0e-7, upper)) / dBRange + 1.0; } bool needUpdate = pspeedenvelope->MouseEvent( diff --git a/src/effects/Amplify.cpp b/src/effects/Amplify.cpp index e6d53a01d..096364bfc 100644 --- a/src/effects/Amplify.cpp +++ b/src/effects/Amplify.cpp @@ -65,7 +65,7 @@ END_EVENT_TABLE() EffectAmplify::EffectAmplify() { mAmp = DEF_Amp; - mRatio = pow(10.0, mAmp / 20.0); + mRatio = DB_TO_LINEAR(mAmp); mRatioClip = 0.0; mCanClip = false; mPeak = 0.0; @@ -235,8 +235,8 @@ void EffectAmplify::PopulateOrExchange(ShuttleGui & S) S.StartMultiColumn(2, wxCENTER); { FloatingPointValidator vldNewPeak(precission, &mNewPeak, NUM_VAL_ONE_TRAILING_ZERO); - double minAmp = MIN_Amp + (20.0 * log10(mPeak)); - double maxAmp = MAX_Amp + (20.0 * log10(mPeak)); + double minAmp = MIN_Amp + LINEAR_TO_DB(mPeak); + double maxAmp = MAX_Amp + LINEAR_TO_DB(mPeak); // min and max need same precision as what we're validating (bug 963) minAmp = Internat::CompatibleToDouble(Internat::ToString(minAmp, precission)); @@ -268,17 +268,17 @@ void EffectAmplify::PopulateOrExchange(ShuttleGui & S) bool EffectAmplify::TransferDataToWindow() { // limit range of gain - double dBInit = 20.0*log10(mRatio); + double dBInit = LINEAR_TO_DB(mRatio); double dB = TrapDouble(dBInit, MIN_Amp, MAX_Amp); if (dB != dBInit) - mRatio = pow(10.0, dB / 20.0); + mRatio = DB_TO_LINEAR(dB); - mAmp = 20.0 * log10(mRatio); + mAmp = LINEAR_TO_DB(mRatio); mAmpT->GetValidator()->TransferToWindow(); mAmpS->SetValue((int) (mAmp * SCL_Amp + 0.5f)); - mNewPeak = 20.0 * log10(mRatio * mPeak); + mNewPeak = LINEAR_TO_DB(mRatio * mPeak); mNewPeakT->GetValidator()->TransferToWindow(); mClip->SetValue(mCanClip); @@ -295,7 +295,7 @@ bool EffectAmplify::TransferDataFromWindow() return false; } - mRatio = pow(10.0, TrapDouble(mAmp * SCL_Amp, MIN_Amp * SCL_Amp, MAX_Amp * SCL_Amp) / (20.0 * SCL_Amp)); + mRatio = DB_TO_LINEAR(TrapDouble(mAmp * SCL_Amp, MIN_Amp * SCL_Amp, MAX_Amp * SCL_Amp) / SCL_Amp); mCanClip = mClip->GetValue(); @@ -322,11 +322,11 @@ void EffectAmplify::OnAmpText(wxCommandEvent & WXUNUSED(evt)) return; } - mRatio = pow(10.0, TrapDouble(mAmp * SCL_Amp, MIN_Amp * SCL_Amp, MAX_Amp * SCL_Amp) / (20.0 * SCL_Amp)); + mRatio = DB_TO_LINEAR(TrapDouble(mAmp * SCL_Amp, MIN_Amp * SCL_Amp, MAX_Amp * SCL_Amp) / SCL_Amp); - mAmpS->SetValue((int) (20.0 * log10(mRatio) * SCL_Amp + 0.5)); + mAmpS->SetValue((int) (LINEAR_TO_DB(mRatio) * SCL_Amp + 0.5)); - mNewPeak = 20.0 * log10(mRatio * mPeak); + mNewPeak = LINEAR_TO_DB(mRatio * mPeak); mNewPeakT->GetValidator()->TransferToWindow(); CheckClip(); @@ -343,12 +343,12 @@ void EffectAmplify::OnPeakText(wxCommandEvent & WXUNUSED(evt)) if (mNewPeak == 0.0) mRatio = mRatioClip; else - mRatio = pow(10.0, mNewPeak / 20.0) / mPeak; + mRatio = DB_TO_LINEAR(mNewPeak) / mPeak; - double ampInit = 20.0 * log10(mRatio); + double ampInit = LINEAR_TO_DB(mRatio); mAmp = TrapDouble(ampInit, MIN_Amp, MAX_Amp); if (mAmp != ampInit) - mRatio = pow(10.0, mAmp / 20.0); + mRatio = DB_TO_LINEAR(mAmp); mAmpT->GetValidator()->TransferToWindow(); @@ -360,20 +360,20 @@ void EffectAmplify::OnPeakText(wxCommandEvent & WXUNUSED(evt)) void EffectAmplify::OnAmpSlider(wxCommandEvent & evt) { double dB = evt.GetInt() / SCL_Amp; - mRatio = pow(10.0, TrapDouble(dB, MIN_Amp, MAX_Amp) / 20.0); + mRatio = DB_TO_LINEAR(TrapDouble(dB, MIN_Amp, MAX_Amp)); double dB2 = (evt.GetInt() - 1) / SCL_Amp; - double ratio2 = pow(10.0, TrapDouble(dB2, MIN_Amp, MAX_Amp) / 20.0); + double ratio2 = DB_TO_LINEAR(TrapDouble(dB2, MIN_Amp, MAX_Amp)); if (!mClip->GetValue() && mRatio * mPeak > 1.0 && ratio2 * mPeak < 1.0) { mRatio = 1.0 / mPeak; } - mAmp = 20.0 * log10(mRatio); + mAmp = LINEAR_TO_DB(mRatio); mAmpT->GetValidator()->TransferToWindow(); - mNewPeak = 20.0 * log10(mRatio * mPeak); + mNewPeak = LINEAR_TO_DB(mRatio * mPeak); mNewPeakT->GetValidator()->TransferToWindow(); CheckClip(); diff --git a/src/effects/AutoDuck.cpp b/src/effects/AutoDuck.cpp index a582c3800..1887368a2 100644 --- a/src/effects/AutoDuck.cpp +++ b/src/effects/AutoDuck.cpp @@ -278,7 +278,7 @@ bool EffectAutoDuck::Process() sampleCount minSamplesPause = mControlTrack->TimeToLongSamples(maxPause); - double threshold = pow(10.0, mThresholdDb/20); + double threshold = DB_TO_LINEAR(mThresholdDb); // adjust the threshold so we can compare it to the rmsSum value threshold = threshold * threshold * kRMSWindowSize; @@ -553,7 +553,7 @@ bool EffectAutoDuck::ApplyDuckFade(int trackNumber, WaveTrack* t, if (gain < mDuckAmountDb) gain = mDuckAmountDb; - buf[i - pos] *= pow(10.0, gain / 20.0); + buf[i - pos] *= DB_TO_LINEAR(gain); } t->Set((samplePtr)buf, floatSample, pos, len); diff --git a/src/effects/BassTreble.cpp b/src/effects/BassTreble.cpp index f311a75d6..e524e7f90 100644 --- a/src/effects/BassTreble.cpp +++ b/src/effects/BassTreble.cpp @@ -155,7 +155,7 @@ sampleCount EffectBassTreble::ProcessBlock(float **inBlock, float **outBlock, sa } else { - float gain = (pow(10.0, dB_level / 20.0f)) / mMax; + float gain = DB_TO_LINEAR(dB_level) / mMax; for (sampleCount i = 0; i < blockLen; i++) { // Normalize to specified level diff --git a/src/effects/Compressor.cpp b/src/effects/Compressor.cpp index 0d8e8752e..4599d09a7 100644 --- a/src/effects/Compressor.cpp +++ b/src/effects/Compressor.cpp @@ -328,8 +328,8 @@ bool EffectCompressor::TransferDataFromWindow() bool EffectCompressor::NewTrackPass1() { - mThreshold = pow(10.0, mThresholdDB/20); // factor of 20 because it's power - mNoiseFloor = pow(10.0, mNoiseFloorDB/20); + mThreshold = DB_TO_LINEAR(mThresholdDB); + mNoiseFloor = DB_TO_LINEAR(mNoiseFloorDB); mNoiseCounter = 100; mAttackInverseFactor = exp(log(mThreshold) / (mCurRate * mAttackTime + 0.5)); diff --git a/src/effects/Contrast.cpp b/src/effects/Contrast.cpp index 3d9ffacc3..1615c6fd7 100644 --- a/src/effects/Contrast.cpp +++ b/src/effects/Contrast.cpp @@ -112,7 +112,7 @@ float ContrastDialog::GetDB() { if( rms < 1.0E-30 ) return -60.0; - return 20.0*log10(rms); + return LINEAR_TO_DB(rms); } else { diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index ac81f46ea..4201b4303 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -1182,13 +1182,13 @@ bool EffectEqualization::CalcFilter() } mFilterFuncR[mWindowSize/2] = val1; - mFilterFuncR[0] = (float)(pow(10., mFilterFuncR[0]/20.)); + mFilterFuncR[0] = DB_TO_LINEAR(mFilterFuncR[0]); for(i=1;imdBMin; } diff --git a/src/effects/NoiseReduction.cpp b/src/effects/NoiseReduction.cpp index d02985d0b..b03ae578c 100644 --- a/src/effects/NoiseReduction.cpp +++ b/src/effects/NoiseReduction.cpp @@ -765,10 +765,10 @@ EffectNoiseReduction::Worker::Worker const int nAttackBlocks = 1 + (int)(settings.mAttackTime * sampleRate / mStepSize); const int nReleaseBlocks = 1 + (int)(settings.mReleaseTime * sampleRate / mStepSize); // Applies to amplitudes, divide by 20: - mNoiseAttenFactor = pow(10.0, noiseGain / 20.0); + mNoiseAttenFactor = DB_TO_LINEAR(noiseGain); // Apply to gain factors which apply to amplitudes, divide by 20: - mOneBlockAttack = pow(10.0, (noiseGain / (20.0 * nAttackBlocks))); - mOneBlockRelease = pow(10.0, (noiseGain / (20.0 * nReleaseBlocks))); + mOneBlockAttack = DB_TO_LINEAR(noiseGain / nAttackBlocks); + mOneBlockRelease = DB_TO_LINEAR(noiseGain / nReleaseBlocks); // Applies to power, divide by 10: mOldSensitivityFactor = pow(10.0, settings.mOldSensitivity / 10.0); diff --git a/src/effects/NoiseRemoval.cpp b/src/effects/NoiseRemoval.cpp index 0ac3f4bc2..a1f39364c 100644 --- a/src/effects/NoiseRemoval.cpp +++ b/src/effects/NoiseRemoval.cpp @@ -275,10 +275,8 @@ void EffectNoiseRemoval::Initialize() mFreqSmoothingBins = (int)(mFreqSmoothingHz * mWindowSize / mSampleRate); mAttackDecayBlocks = 1 + (int)(mAttackDecayTime * mSampleRate / (mWindowSize / 2)); - // Applies to amplitudes, divide by 20: - mNoiseAttenFactor = pow(10.0, mNoiseGain/20.0); - // Applies to gain factors which apply to amplitudes, divide by 20: - mOneBlockAttackDecay = pow(10.0, (mNoiseGain / (20.0 * mAttackDecayBlocks))); + mNoiseAttenFactor = DB_TO_LINEAR(mNoiseGain); + mOneBlockAttackDecay = DB_TO_LINEAR(mNoiseGain / mAttackDecayBlocks); // Applies to power, divide by 10: mSensitivityFactor = pow(10.0, mSensitivity/10.0); mMinSignalBlocks = diff --git a/src/effects/Normalize.cpp b/src/effects/Normalize.cpp index 7cbf3a8e0..c0ad7f978 100644 --- a/src/effects/Normalize.cpp +++ b/src/effects/Normalize.cpp @@ -152,9 +152,8 @@ bool EffectNormalize::Process() float ratio; if( mGain ) - ratio = pow(10.0,TrapDouble(mLevel, // same value used for all tracks - MIN_Level, - MAX_Level)/20.0); + // same value used for all tracks + ratio = DB_TO_LINEAR(TrapDouble(mLevel, MIN_Level, MAX_Level)); else ratio = 1.0; diff --git a/src/effects/ScienFilter.cpp b/src/effects/ScienFilter.cpp index 838e8273e..7dee7f0e1 100644 --- a/src/effects/ScienFilter.cpp +++ b/src/effects/ScienFilter.cpp @@ -725,7 +725,7 @@ bool EffectScienFilter::CalcFilter() } if ((mOrder & 1) == 0) { - float fTemp = pow (10.0, -wxMax(0.001, mRipple) / 20.0); // at DC the response is down R dB (for even-order) + float fTemp = DB_TO_LINEAR(-wxMax(0.001, mRipple)); // at DC the response is down R dB (for even-order) mpBiquad[0].fNumerCoeffs [0] *= fTemp; mpBiquad[0].fNumerCoeffs [1] *= fTemp; mpBiquad[0].fNumerCoeffs [2] *= fTemp; @@ -761,7 +761,7 @@ bool EffectScienFilter::CalcFilter() case kChebyshevTypeII: // Chebyshev Type 2 float fSZeroX, fSZeroY; float fSPoleX, fSPoleY; - eps = pow (10.0, -wxMax(0.001, mStopbandRipple) / 20.0); + eps = DB_TO_LINEAR(-wxMax(0.001, mStopbandRipple)); a = log (1 / eps + sqrt(1 / square(eps) + 1)) / mOrder; // Assume even order @@ -1131,7 +1131,7 @@ void EffectScienFilterPanel::OnPaint(wxPaintEvent & WXUNUSED(evt)) x = mEnvRect.x + i; freq = pow(10.0, loLog + i * step); //Hz yF = mEffect->FilterMagnAtFreq (freq); - yF = 20.0 * log10(yF); + yF = LINEAR_TO_DB(yF); if (yF < mDbMin) { diff --git a/src/widgets/ASlider.cpp b/src/widgets/ASlider.cpp index 9a632f047..d803b3754 100644 --- a/src/widgets/ASlider.cpp +++ b/src/widgets/ASlider.cpp @@ -292,7 +292,7 @@ bool SliderDialog::TransferDataFromWindow() mTextCtrl->GetValue().ToDouble(&value); if (mStyle == DB_SLIDER) - value = pow(10.0, value / 20.0); + value = DB_TO_LINEAR(value); mSlider->Set(value); return true; @@ -1330,7 +1330,7 @@ float LWSlider::DragPositionToValue(int fromPos, bool shiftDown) float LWSlider::Get( bool convert ) { if (mStyle == DB_SLIDER) - return ( convert ? pow(10.0f, mCurrentValue / 20.0f) : mCurrentValue ); + return (convert ? DB_TO_LINEAR(mCurrentValue) : mCurrentValue); else return mCurrentValue; } @@ -1340,7 +1340,7 @@ void LWSlider::Set(float value) if (mIsDragging) return; if (mStyle == DB_SLIDER) - mCurrentValue = 20.0f*log10(value); + mCurrentValue = LINEAR_TO_DB(value); else mCurrentValue = value; diff --git a/src/widgets/Meter.cpp b/src/widgets/Meter.cpp index fabc0cba8..2f7edde48 100644 --- a/src/widgets/Meter.cpp +++ b/src/widgets/Meter.cpp @@ -864,7 +864,7 @@ static float ToDB(float v, float range) { double db; if (v > 0) - db = 20 * log10(fabs(v)); + db = LINEAR_TO_DB(fabs(v)); else db = -999; return ClipZeroToOne((db + range) / range); @@ -995,7 +995,7 @@ void Meter::OnMeterUpdate(wxTimerEvent & WXUNUSED(event)) } else { double decayAmount = mDecayRate * deltaT; - double decayFactor = pow(10.0, -decayAmount/20); + double decayFactor = DB_TO_LINEAR(-decayAmount); mBar[j].peak = floatMax(msg.peak[j], mBar[j].peak * decayFactor); }