Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,20 @@ constexpr float bin_to_hz(float samplerate, std::integral auto bins, auto bin) n
return 0.5F * samplerate * static_cast<float>(bin) / static_cast<float>(bins - 1);
}

constexpr size_t hz_to_bin(float samplerate, std::integral auto bins, float frequency) noexcept {
constexpr size_t hz_to_bin(
float samplerate,
std::integral auto bins,
float frequency,
float (*rounding_func)(float) = std::round
) noexcept {
if (samplerate == 0.0F || bins <= 1) {
return 0;
}
// TODO: handle unexpected arguments
assert(frequency >= 0.0F);
assert(frequency <= 0.5F * samplerate);
const auto bin = static_cast<float>(bins - 1) * frequency / (0.5F * samplerate);
return static_cast<size_t>(std::round(bin));
return static_cast<size_t>(rounding_func(bin));
}

namespace views {
Expand Down Expand Up @@ -226,14 +231,14 @@ static constexpr auto power_spectrum_view(Spectrum spectrum) {
float partial_power([[maybe_unused]] Env& env, Input input, float fmin, float fmax) {
fmin = std::clamp(fmin, 0.0F, 0.5F * input.samplerate);
fmax = std::clamp(fmax, fmin, 0.5F * input.samplerate);
const auto power_spectrum = power_spectrum_view(input.spectrum);
const auto power_spectrum_range = std::ranges::subrange(
const auto ps = power_spectrum_view(input.spectrum);
const auto ps_range = std::ranges::subrange(
// NOLINTBEGIN(*narrowing-conversions)
power_spectrum.begin() + hz_to_bin(input.samplerate, power_spectrum.size(), fmin),
power_spectrum.begin() + hz_to_bin(input.samplerate, power_spectrum.size(), fmax)
ps.begin() + hz_to_bin(input.samplerate, ps.size(), fmin, std::floor),
ps.begin() + hz_to_bin(input.samplerate, ps.size(), fmax, std::floor)
// NOLINTEND(*narrowing-conversions)
);
return sum<float>(power_spectrum_range) / sum<float>(power_spectrum);
return sum<float>(ps_range) / sum<float>(ps);
}

float spectral_peak_frequency([[maybe_unused]] Env& env, Input input) {
Expand Down
4 changes: 2 additions & 2 deletions tests/test_features_partial-power.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,6 @@ input.samplerate = 10
input.spectrum = [0, 1, 2, 3, 4, 0] # sum squares: 30
# frequencies: 0, 1, 2, 3, 4, 5 Hz
# ^
params.fmin = 3.4 # round down to bin 3
params.fmax = 3.6 # round up to bin 4
params.fmin = 3.4 # floor to bin 3
params.fmax = 4.6 # floor to bin 4
result = 0.3 # 9/30
Loading