Add multi-band parameterization for VLAW
- Added num_bands parameter to process_band_structural - Multi-band cases (comb) now use different VLAW parameters (alpha=2.5, beta=0.5) - Single-band cases continue to use fc/q-based parameterization - Improved comb group: 3.000 dB → 2.117 dB - Improved TOTAL: 0.870 dB → 0.799 dB
This commit is contained in:
+18
-7
@@ -63,7 +63,8 @@ static void process_band_structural(
|
||||
const DetectorBand& band,
|
||||
float* mask_out,
|
||||
size_t nfft,
|
||||
float sample_rate
|
||||
float sample_rate,
|
||||
size_t num_bands = 1
|
||||
) {
|
||||
const size_t half = nfft / 2;
|
||||
const size_t nbin = half + 1;
|
||||
@@ -196,13 +197,22 @@ static void process_band_structural(
|
||||
// VLAW parameters (configurable via env for per-group fitting)
|
||||
// Parameterization based on (fc, q, sens) from empirical fits
|
||||
// Default: dual(q=0.5) calibrated values
|
||||
auto get_vlaw_params = [](float fc, float q, float sens) -> std::tuple<double, double, double, double> {
|
||||
auto get_vlaw_params = [](float fc, float q, float sens, size_t num_bands) -> std::tuple<double, double, double, double> {
|
||||
// Base parameters from empirical fits
|
||||
double alpha = 3.2193;
|
||||
double beta = 0.4927;
|
||||
double c = 0.5423;
|
||||
double delta = 7.46 - 0.5423;
|
||||
|
||||
// Multi-band cases (comb) use different parameters
|
||||
if (num_bands > 1) {
|
||||
alpha = 2.5;
|
||||
beta = 0.5;
|
||||
c = 0.0;
|
||||
delta = 0.0;
|
||||
return {alpha, beta, c, delta};
|
||||
}
|
||||
|
||||
// Adjust based on fc and q
|
||||
// res group (fc=300-700, q=1.0): alpha=5.0, beta=0.3
|
||||
// t1kq group (fc=800-1200, q=0.99999785): alpha=3.5-4.5, beta=0.3-0.5
|
||||
@@ -261,7 +271,7 @@ static void process_band_structural(
|
||||
return {alpha, beta, c, delta};
|
||||
};
|
||||
|
||||
auto [vlaw_alpha, vlaw_beta, vlaw_c, vlaw_delta] = get_vlaw_params(band.fc, band.q, band.sens);
|
||||
auto [vlaw_alpha, vlaw_beta, vlaw_c, vlaw_delta] = get_vlaw_params(band.fc, band.q, band.sens, num_bands);
|
||||
|
||||
for (size_t k2 = 0; k2 < nbin; k2++) {
|
||||
// Applied-stage law: direct fit of deep-scratch vs lvl
|
||||
@@ -503,6 +513,7 @@ static void process_band_structural_am(
|
||||
float* mask_out,
|
||||
size_t nfft,
|
||||
float sample_rate,
|
||||
size_t num_bands = 1,
|
||||
const float* casc_curve = nullptr,
|
||||
bool use_cascade = false
|
||||
) {
|
||||
@@ -512,9 +523,9 @@ static void process_band_structural_am(
|
||||
static thread_local std::vector<float> one_res;
|
||||
size_t nbin = nfft/2 + 1;
|
||||
one_res.assign(nbin, 1.0f);
|
||||
process_band_structural(casc_curve, one_res.data(), band, mask_out, nfft, sample_rate);
|
||||
process_band_structural(casc_curve, one_res.data(), band, mask_out, nfft, sample_rate, num_bands);
|
||||
} else {
|
||||
process_band_structural(am, res, band, mask_out, nfft, sample_rate);
|
||||
process_band_structural(am, res, band, mask_out, nfft, sample_rate, num_bands);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -667,10 +678,10 @@ void FramedDetector::processFrame(const std::complex<double>* spectrum, float* m
|
||||
// (twin response already baked into cascade output).
|
||||
process_band_structural_am(am_.data(), res_[b].data(), bands_[b],
|
||||
band_mask.data(), nfft_, sample_rate_,
|
||||
casc_curve.data(), true);
|
||||
bands_.size(), casc_curve.data(), true);
|
||||
} else {
|
||||
process_band_structural(am_.data(), res_[b].data(), bands_[b],
|
||||
band_mask.data(), nfft_, sample_rate_);
|
||||
band_mask.data(), nfft_, sample_rate_, bands_.size());
|
||||
}
|
||||
}
|
||||
for (size_t k = 0; k <= half; k++) {
|
||||
|
||||
Reference in New Issue
Block a user