mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 08:09:32 +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,
|
bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
|
||||||
float *freq, sampleCount *where,
|
float *freq, sampleCount *where,
|
||||||
int numPixels,
|
int numPixels,
|
||||||
@ -852,7 +871,7 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
|
|||||||
int maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
|
int maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
|
||||||
int range = gPrefs->Read(wxT("/Spectrum/Range"), 80L);
|
int range = gPrefs->Read(wxT("/Spectrum/Range"), 80L);
|
||||||
int gain = gPrefs->Read(wxT("/Spectrum/Gain"), 20L);
|
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 windowType;
|
||||||
int windowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
|
int windowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
|
||||||
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
||||||
@ -897,7 +916,7 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
|
|||||||
mSpecCache->windowTypeOld == windowType &&
|
mSpecCache->windowTypeOld == windowType &&
|
||||||
mSpecCache->windowSizeOld == windowSize &&
|
mSpecCache->windowSizeOld == windowSize &&
|
||||||
mSpecCache->zeroPaddingFactorOld == zeroPaddingFactor &&
|
mSpecCache->zeroPaddingFactorOld == zeroPaddingFactor &&
|
||||||
mSpecCache->frequencyGainOld == frequencygain &&
|
mSpecCache->frequencyGainOld == frequencyGain &&
|
||||||
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
||||||
mSpecCache->fftSkipPointsOld == fftSkipPoints &&
|
mSpecCache->fftSkipPointsOld == fftSkipPoints &&
|
||||||
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
|
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
|
||||||
@ -986,18 +1005,10 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
|
|||||||
mSpecCache->windowTypeOld = windowType;
|
mSpecCache->windowTypeOld = windowType;
|
||||||
mSpecCache->windowSizeOld = windowSize;
|
mSpecCache->windowSizeOld = windowSize;
|
||||||
mSpecCache->zeroPaddingFactorOld = zeroPaddingFactor;
|
mSpecCache->zeroPaddingFactorOld = zeroPaddingFactor;
|
||||||
mSpecCache->frequencyGainOld = frequencygain;
|
mSpecCache->frequencyGainOld = frequencyGain;
|
||||||
|
|
||||||
float *gainfactor = NULL;
|
std::vector<float> gainFactors;
|
||||||
if(frequencygain > 0) {
|
ComputeSpectrogramGainFactors(fftLen, frequencyGain, gainFactors);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (sampleCount x = 0; x < mSpecCache->len; x++)
|
for (sampleCount x = 0; x < mSpecCache->len; x++)
|
||||||
if (recalc[x]) {
|
if (recalc[x]) {
|
||||||
@ -1080,16 +1091,14 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
|
|||||||
mRate, &mSpecCache->freq[half * x],
|
mRate, &mSpecCache->freq[half * x],
|
||||||
autocorrelation, windowType);
|
autocorrelation, windowType);
|
||||||
#endif // EXPERIMENTAL_USE_REALFFTF
|
#endif // EXPERIMENTAL_USE_REALFFTF
|
||||||
if(gainfactor) {
|
if (!gainFactors.empty()) {
|
||||||
// Apply a frequency-dependant gain factor
|
// Apply a frequency-dependent gain factor
|
||||||
for(i=0; i<half; i++)
|
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[]buffer;
|
||||||
delete[]recalc;
|
delete[]recalc;
|
||||||
delete oldCache;
|
delete oldCache;
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include <wx/list.h>
|
#include <wx/list.h>
|
||||||
#include <wx/msgdlg.h>
|
#include <wx/msgdlg.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Envelope;
|
class Envelope;
|
||||||
class WaveCache;
|
class WaveCache;
|
||||||
class WaveTrackCache;
|
class WaveTrackCache;
|
||||||
@ -187,6 +189,11 @@ public:
|
|||||||
* calculations and Contrast */
|
* calculations and Contrast */
|
||||||
bool GetWaveDisplay(WaveDisplay &display,
|
bool GetWaveDisplay(WaveDisplay &display,
|
||||||
double t0, double pixelsPerSecond, bool &isLoadingOD);
|
double t0, double pixelsPerSecond, bool &isLoadingOD);
|
||||||
|
void ComputeSpectrogramGainFactors(
|
||||||
|
int fftLen,
|
||||||
|
int frequencyGain, // db/decade
|
||||||
|
std::vector<float> &gainFactors
|
||||||
|
);
|
||||||
bool GetSpectrogram(WaveTrackCache &cache,
|
bool GetSpectrogram(WaveTrackCache &cache,
|
||||||
float *buffer, sampleCount *where,
|
float *buffer, sampleCount *where,
|
||||||
int numPixels,
|
int numPixels,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user