Fix synchrosqueezing: correct complex division sign and add noise threshold
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
+10
-3
@@ -473,13 +473,19 @@ static void GenerateSpectrogramTexture(StftResult* stft, Image* image, Texture2D
|
||||
// Accumulation buffer for reassigned energy
|
||||
float* accumBuffer = (float*)calloc(width * height, sizeof(float));
|
||||
|
||||
// Noise threshold: only reassign bins with significant energy
|
||||
// This prevents noise from being reassigned to random frequencies
|
||||
float noiseThreshold = maxAmplitude * 0.01f; // 1% of max amplitude
|
||||
|
||||
for (int seg = 0; seg < width; seg++) {
|
||||
for (int bin = 0; bin < height; bin++) {
|
||||
FrequencyData* V_f = &stft->segments[seg].spectrum[bin];
|
||||
FrequencyData* V_fd = &stft->segments[seg].derivativeSpectrum[bin];
|
||||
|
||||
float amplitude = V_f->amplitude;
|
||||
if (amplitude < 0.0001f) continue;
|
||||
|
||||
// Skip noise bins
|
||||
if (amplitude < noiseThreshold) continue;
|
||||
|
||||
// Compute instantaneous frequency using synchrosqueezing formula:
|
||||
// ω̂ = bin_freq + Re[V_fd / (i * V_f)]
|
||||
@@ -496,8 +502,9 @@ static void GenerateSpectrogramTexture(StftResult* stft, Image* image, Texture2D
|
||||
float trueFreq = V_f->frequency; // Default to bin frequency
|
||||
|
||||
if (denom > 1e-10f) {
|
||||
// Re[V_fd / (i * V_f)] = (V_fd_real * V_f_imag + V_fd_imag * V_f_real) / denom
|
||||
float correction = (V_fd_real * V_f_imag + V_fd_imag * V_f_real) / denom;
|
||||
// Re[V_fd / (i * V_f)] = (-V_fd_real * V_f_imag + V_fd_imag * V_f_real) / denom
|
||||
// Note the MINUS sign on the first term
|
||||
float correction = (-V_fd_real * V_f_imag + V_fd_imag * V_f_real) / denom;
|
||||
trueFreq = V_f->frequency + correction;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user