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:
parent
54e9e4950c
commit
ba5738446c
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user