1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-15 23:59:37 +02:00

Bug1009: Correct interaction of Zero Padding and Frequency Gain...

... also an excuse to pull out a function I will want to reuse in a later
project.  The real fix was simply to use fftLen not windowSize.
This commit is contained in:
Paul Licameli 2015-06-03 13:11:17 -04:00
parent 54e9e4950c
commit ba5738446c
2 changed files with 34 additions and 18 deletions

View File

@ -842,6 +842,25 @@ void RecreateWindow(
}
}
void WaveClip::ComputeSpectrogramGainFactors(int fftLen, int frequencyGain, std::vector<float> &gainFactors)
{
if (frequencyGain > 0) {
// Compute a frequency-dependent gain factor
// scaled such that 1000 Hz gets a gain of 0dB
// This is the reciprocal of the bin number of 1000 Hz:
const double factor = ((double)mRate / (double)fftLen) / 1000.0;
const int half = fftLen / 2;
gainFactors.reserve(half);
// Don't take logarithm of zero! Let bin 0 replicate the gain factor for bin 1.
gainFactors.push_back(frequencyGain*log10(factor));
for (sampleCount x = 1; x < half; x++) {
gainFactors.push_back(frequencyGain*log10(factor * x));
}
}
}
bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
float *freq, sampleCount *where,
int numPixels,
@ -852,7 +871,7 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
int maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
int range = gPrefs->Read(wxT("/Spectrum/Range"), 80L);
int gain = gPrefs->Read(wxT("/Spectrum/Gain"), 20L);
int frequencygain = gPrefs->Read(wxT("/Spectrum/FrequencyGain"), 0L);
int frequencyGain = gPrefs->Read(wxT("/Spectrum/FrequencyGain"), 0L);
int windowType;
int windowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
@ -897,7 +916,7 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
mSpecCache->windowTypeOld == windowType &&
mSpecCache->windowSizeOld == windowSize &&
mSpecCache->zeroPaddingFactorOld == zeroPaddingFactor &&
mSpecCache->frequencyGainOld == frequencygain &&
mSpecCache->frequencyGainOld == frequencyGain &&
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
mSpecCache->fftSkipPointsOld == fftSkipPoints &&
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
@ -986,18 +1005,10 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
mSpecCache->windowTypeOld = windowType;
mSpecCache->windowSizeOld = windowSize;
mSpecCache->zeroPaddingFactorOld = zeroPaddingFactor;
mSpecCache->frequencyGainOld = frequencygain;
mSpecCache->frequencyGainOld = frequencyGain;
float *gainfactor = NULL;
if(frequencygain > 0) {
// Compute a frequency-dependant gain factor
// scaled such that 1000 Hz gets a gain of 0dB
double factor = 0.001*(double)mRate/(double)windowSize;
gainfactor = new float[half];
for(sampleCount x = 0; x < half; x++) {
gainfactor[x] = frequencygain*log10(factor * x);
}
}
std::vector<float> gainFactors;
ComputeSpectrogramGainFactors(fftLen, frequencyGain, gainFactors);
for (sampleCount x = 0; x < mSpecCache->len; x++)
if (recalc[x]) {
@ -1080,16 +1091,14 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
mRate, &mSpecCache->freq[half * x],
autocorrelation, windowType);
#endif // EXPERIMENTAL_USE_REALFFTF
if(gainfactor) {
// Apply a frequency-dependant gain factor
if (!gainFactors.empty()) {
// Apply a frequency-dependent gain factor
for(i=0; i<half; i++)
mSpecCache->freq[half * x + i] += gainfactor[i];
mSpecCache->freq[half * x + i] += gainFactors[i];
}
}
}
if(gainfactor)
delete[] gainfactor;
delete[]buffer;
delete[]recalc;
delete oldCache;

View File

@ -29,6 +29,8 @@
#include <wx/list.h>
#include <wx/msgdlg.h>
#include <vector>
class Envelope;
class WaveCache;
class WaveTrackCache;
@ -187,6 +189,11 @@ public:
* calculations and Contrast */
bool GetWaveDisplay(WaveDisplay &display,
double t0, double pixelsPerSecond, bool &isLoadingOD);
void ComputeSpectrogramGainFactors(
int fftLen,
int frequencyGain, // db/decade
std::vector<float> &gainFactors
);
bool GetSpectrogram(WaveTrackCache &cache,
float *buffer, sampleCount *where,
int numPixels,