30#if !defined(PULP_WASM)
77 std::vector<float> mono,
double file_sr,
double session_sr,
79 const std::size_t frames = mono.size();
83 std::vector<float> ir;
84 if (std::abs(file_sr - session_sr) > 1e-3 && file_sr > 0.0) {
86 rs.
prepare(file_sr, session_sr, 1, frames);
90 std::vector<float> padded = std::move(mono);
91 padded.resize(frames + pad, 0.0f);
94 const std::size_t produced =
102 const double ratio = session_sr / file_sr;
103 const std::size_t gd_out =
static_cast<std::size_t
>(
105 if (gd_out > 0 && gd_out < ir.size())
106 ir.erase(ir.begin(), ir.begin() +
static_cast<std::ptrdiff_t
>(gd_out));
108 ir = std::move(mono);
110 if (ir.empty())
return std::nullopt;
115 const std::size_t max_session_frames =
116 static_cast<std::size_t
>(opts.
max_seconds * session_sr);
117 if (ir.size() > max_session_frames) ir.resize(max_session_frames);
126 if (!std::isfinite(v))
return std::nullopt;
127 energy +=
static_cast<double>(v) * v;
130 if (energy <= 0.0)
return std::nullopt;
131 const float g =
static_cast<float>(1.0 / std::sqrt(energy));
132 for (
float& v : ir) v *= g;
151 const float* samples, std::size_t frames, std::uint32_t channels,
152 double src_rate,
double target_sample_rate,
154 if (samples ==
nullptr || frames == 0 || channels == 0)
return std::nullopt;
155 const double session_sr = target_sample_rate > 0.0 ? target_sample_rate : 48000.0;
156 const double file_sr = src_rate > 0.0 ? src_rate : session_sr;
161 if (file_sr < kMinIrSampleRate || file_sr >
kMaxIrSampleRate)
return std::nullopt;
162 if (opts.reject_longer_than_seconds > 0.0
163 &&
static_cast<double>(frames) / file_sr > opts.reject_longer_than_seconds)
167 std::size_t n = frames;
168 if (opts.max_seconds > 0.0) {
169 const std::size_t max_src_frames =
170 static_cast<std::size_t
>(opts.max_seconds * file_sr);
171 if (n > max_src_frames) n = max_src_frames;
175 std::vector<float> mono(n, 0.0f);
176 for (std::uint32_t c = 0; c < channels; ++c) {
177 const float* plane = samples +
static_cast<std::size_t
>(c) * frames;
178 for (std::size_t i = 0; i < n; ++i) mono[i] += plane[i];
181 const float inv = 1.0f /
static_cast<float>(channels);
182 for (
float& v : mono)
v *= inv;
188#if !defined(PULP_WASM)
194 const std::string& path,
double target_sample_rate,
196 const double session_sr = target_sample_rate > 0.0 ? target_sample_rate : 48000.0;
202 if (opts.reject_longer_than_seconds > 0.0) {
204 if (info->num_frames == 0)
return std::nullopt;
205 const double claimed_sr =
static_cast<double>(info->sample_rate);
206 if (info->sample_rate > 0
209 const double info_sr = info->sample_rate > 0 ? claimed_sr : session_sr;
210 const double dur =
static_cast<double>(info->num_frames) / info_sr;
211 if (dur > opts.reject_longer_than_seconds)
return std::nullopt;
218 if (!data || data->channels.empty() || data->num_frames() == 0)
return std::nullopt;
219 const double file_sr =
220 data->sample_rate > 0 ?
static_cast<double>(data->sample_rate) : session_sr;
226 if (file_sr < kMinIrSampleRate || file_sr >
kMaxIrSampleRate)
return std::nullopt;
227 if (opts.reject_longer_than_seconds > 0.0
228 &&
static_cast<double>(data->num_frames()) / file_sr > opts.reject_longer_than_seconds)
232 std::size_t frames =
static_cast<std::size_t
>(data->num_frames());
233 if (opts.max_seconds > 0.0) {
234 const std::size_t max_file_frames =
235 static_cast<std::size_t
>(opts.max_seconds * file_sr);
236 if (frames > max_file_frames) frames = max_file_frames;
238 const std::uint32_t ch = data->num_channels();
241 std::vector<float>
mono(frames, 0.0f);
242 for (std::uint32_t c = 0;
c < ch; ++
c) {
243 const auto& src = data->channels[
c];
244 const std::size_t
m = std::min<std::size_t>(frames, src.size());
245 for (std::size_t i = 0;
i <
m; ++
i) mono[i] += src[i];
248 const float inv = 1.0f /
static_cast<float>(ch);
249 for (
float& v : mono)
v *= inv;
std::size_t process_block_mono(const SampleType *input, std::size_t in_count, SampleType *output, std::size_t out_capacity)
Mono convenience wrapper around process_block.
Definition resampler.hpp:324
void prepare(double input_rate, double output_rate, std::size_t channels, std::size_t max_block_size, ResamplerQuality quality={})
Configure the conversion.
Definition resampler.hpp:96
std::size_t taps_per_phase() const
Per-phase filter length.
Definition resampler.hpp:342
std::size_t max_output_for(std::size_t in_count) const
Worst-case output sample count for a given input count.
Definition resampler.hpp:335
Definition impulse_response.hpp:69
std::optional< std::vector< float > > finish_impulse_response(std::vector< float > mono, double file_sr, double session_sr, const ImpulseResponseLoadOptions &opts)
The post-decode half of the IR pipeline, shared by every entry point: resample the mono buffer from f...
Definition impulse_response.hpp:76
Definition analyzer_provider.hpp:12
constexpr double kMaxIrSampleRate
Definition impulse_response.hpp:54
std::optional< std::vector< float > > read_impulse_response(const std::string &path, double target_sample_rate, const ImpulseResponseLoadOptions &opts={})
Read an IR file → mono → resampled to target_sample_rate → (optionally) unit-energy normalized.
Definition impulse_response.hpp:193
constexpr double kMinIrSampleRate
Definition impulse_response.hpp:53
std::optional< std::vector< float > > read_impulse_response_pcm(const float *samples, std::size_t frames, std::uint32_t channels, double src_rate, double target_sample_rate, const ImpulseResponseLoadOptions &opts={})
Read already-decoded PCM → mono → resampled to target_sample_rate → (optionally) unit-energy normaliz...
Definition impulse_response.hpp:150
@ c
Definition pitch.hpp:20
@ i
Definition formant_filter_bank.hpp:20
ResamplerT< float > Resampler
Definition resampler.hpp:382
@ m
Definition input_events.hpp:40
@ v
Definition input_events.hpp:41
Polyphase-FIR resampler with a Kaiser-window low-pass prototype.
static DecodeLimits unbounded()
No ceilings at all: every field zero.
Definition format_registry.hpp:32
Definition impulse_response.hpp:56
double reject_longer_than_seconds
Refuse a file whose duration exceeds this many seconds before decoding (fat-finger guard).
Definition impulse_response.hpp:66
double max_seconds
Truncate the IR to at most this many seconds (measured at both the source and the target rate so a hu...
Definition impulse_response.hpp:60
bool normalize_unit_energy
Scale so the IR has unit energy (‖ir‖₂ = 1), keeping a dry/wet mix sane regardless of the file's reco...
Definition impulse_response.hpp:63