#include "detect.hpp" #include 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* 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(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(mag); peaks[count].reduction = red; count++; } } } } return count; }