dsp/: C++ skeleton with working FFT/WOLA STFT
- Cooley-Tukey radix-2 FFT (forward + inverse with /N normalization) - WOLA STFT/ISTFT with Hann window (nfft=2048, hop=512) - WAV16 read + WAV24 write (fixed aliasing bug in read) - Fixed in-place processing bug (separate input/output buffers) - Biquad filter (peak/shelf/reject) - Peak detector skeleton - MS encode/decode (M8 stereo) - Harness: WAV16 → STFT → WAV24 passthrough verified non-zero output Verified: burst500.wav passthrough produces output RMS=0.0678
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
#include "detect.hpp"
|
||||
#include <cmath>
|
||||
|
||||
Detector::Detector() : sharpness_(10), selectivity_(10), depth_(0.864) {
|
||||
}
|
||||
|
||||
void Detector::setParams(float sharpness, float selectivity, float depth) {
|
||||
sharpness_ = sharpness;
|
||||
selectivity_ = selectivity;
|
||||
depth_ = depth;
|
||||
}
|
||||
|
||||
float Detector::computeReduction(float magnitude, float freq) {
|
||||
float level_db = 20 * std::log10(std::max(magnitude, 1e-12f));
|
||||
float base_red = std::min(std::max(level_db + 10, 0.0f), 60.0f);
|
||||
float amount = base_red * depth_;
|
||||
return std::min(amount, 60.0f);
|
||||
}
|
||||
|
||||
size_t Detector::detectPeaks(const std::complex<double>* spectrum, size_t n,
|
||||
float sample_rate, Peak* peaks, size_t max_peaks) {
|
||||
float spacing_bins = std::max(2.0f, selectivity_ * 0.5f);
|
||||
|
||||
size_t count = 0;
|
||||
for (size_t k = 1; k < n - 1; k++) {
|
||||
double mag = std::abs(spectrum[k]);
|
||||
double mag_prev = std::abs(spectrum[k - 1]);
|
||||
double mag_next = std::abs(spectrum[k + 1]);
|
||||
|
||||
if (mag > mag_prev && mag > mag_next) {
|
||||
float freq = k * sample_rate / (2 * n);
|
||||
float red = computeReduction(static_cast<float>(mag), freq);
|
||||
|
||||
if (red > 3.0f) {
|
||||
bool is_peak = true;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (std::abs(peaks[i].freq - freq) < spacing_bins * sample_rate / (2 * n)) {
|
||||
is_peak = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_peak && count < max_peaks) {
|
||||
peaks[count].bin = k;
|
||||
peaks[count].freq = freq;
|
||||
peaks[count].magnitude = static_cast<float>(mag);
|
||||
peaks[count].reduction = red;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user