Skip to content

Commit fe21c14

Browse files
authored
fix(partial-power): rounding function (#13)
Use flooring instead of rounding to transform frequencies to bins.
1 parent 03843a1 commit fe21c14

2 files changed

Lines changed: 14 additions & 9 deletions

File tree

src/features.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,20 @@ constexpr float bin_to_hz(float samplerate, std::integral auto bins, auto bin) n
8989
return 0.5F * samplerate * static_cast<float>(bin) / static_cast<float>(bins - 1);
9090
}
9191

92-
constexpr size_t hz_to_bin(float samplerate, std::integral auto bins, float frequency) noexcept {
92+
constexpr size_t hz_to_bin(
93+
float samplerate,
94+
std::integral auto bins,
95+
float frequency,
96+
float (*rounding_func)(float) = std::round
97+
) noexcept {
9398
if (samplerate == 0.0F || bins <= 1) {
9499
return 0;
95100
}
96101
// TODO: handle unexpected arguments
97102
assert(frequency >= 0.0F);
98103
assert(frequency <= 0.5F * samplerate);
99104
const auto bin = static_cast<float>(bins - 1) * frequency / (0.5F * samplerate);
100-
return static_cast<size_t>(std::round(bin));
105+
return static_cast<size_t>(rounding_func(bin));
101106
}
102107

103108
namespace views {
@@ -226,14 +231,14 @@ static constexpr auto power_spectrum_view(Spectrum spectrum) {
226231
float partial_power([[maybe_unused]] Env& env, Input input, float fmin, float fmax) {
227232
fmin = std::clamp(fmin, 0.0F, 0.5F * input.samplerate);
228233
fmax = std::clamp(fmax, fmin, 0.5F * input.samplerate);
229-
const auto power_spectrum = power_spectrum_view(input.spectrum);
230-
const auto power_spectrum_range = std::ranges::subrange(
234+
const auto ps = power_spectrum_view(input.spectrum);
235+
const auto ps_range = std::ranges::subrange(
231236
// NOLINTBEGIN(*narrowing-conversions)
232-
power_spectrum.begin() + hz_to_bin(input.samplerate, power_spectrum.size(), fmin),
233-
power_spectrum.begin() + hz_to_bin(input.samplerate, power_spectrum.size(), fmax)
237+
ps.begin() + hz_to_bin(input.samplerate, ps.size(), fmin, std::floor),
238+
ps.begin() + hz_to_bin(input.samplerate, ps.size(), fmax, std::floor)
234239
// NOLINTEND(*narrowing-conversions)
235240
);
236-
return sum<float>(power_spectrum_range) / sum<float>(power_spectrum);
241+
return sum<float>(ps_range) / sum<float>(ps);
237242
}
238243

239244
float spectral_peak_frequency([[maybe_unused]] Env& env, Input input) {

tests/test_features_partial-power.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,6 @@ input.samplerate = 10
6262
input.spectrum = [0, 1, 2, 3, 4, 0] # sum squares: 30
6363
# frequencies: 0, 1, 2, 3, 4, 5 Hz
6464
# ^
65-
params.fmin = 3.4 # round down to bin 3
66-
params.fmax = 3.6 # round up to bin 4
65+
params.fmin = 3.4 # floor to bin 3
66+
params.fmax = 4.6 # floor to bin 4
6767
result = 0.3 # 9/30

0 commit comments

Comments
 (0)