From 272a4a6762cd518f17e88ff9e97019ac363a44ab Mon Sep 17 00:00:00 2001 From: Arlo Faria Date: Tue, 11 Jun 2024 13:12:55 -0700 Subject: [PATCH 1/2] Increase expected size of output sample buffer. --- src/samplerate.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/samplerate.cpp b/src/samplerate.cpp index 42bb4d3..b9522fc 100644 --- a/src/samplerate.cpp +++ b/src/samplerate.cpp @@ -158,8 +158,14 @@ class Resampler { if (channels != _channels || channels == 0) throw std::domain_error("Invalid number of channels in input data."); + // Add a "fudge factor" of 10,000. This is because the actual number of + // output samples generated on the last call when input is terminated can + // be more than the expected number of output samples during mid-stream + // steady-state processing. (Also, when the stream is started, the number + // of output samples generated will generally be zero or otherwise less + // than the number of samples in mid-stream processing.) const auto new_size = - static_cast(std::ceil(inbuf.shape[0] * sr_ratio)); + static_cast(std::ceil(inbuf.shape[0] * sr_ratio)) + 10000; // allocate output array std::vector out_shape{new_size}; From 62d5c162aaa0083dac38cc7b3c2dae9d9dd5c87e Mon Sep 17 00:00:00 2001 From: Arlo Faria Date: Tue, 11 Jun 2024 13:56:33 -0700 Subject: [PATCH 2/2] Use a macro definition and throw/raise a runtime error/exception. --- src/samplerate.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/samplerate.cpp b/src/samplerate.cpp index b9522fc..0869225 100644 --- a/src/samplerate.cpp +++ b/src/samplerate.cpp @@ -40,6 +40,9 @@ #define VERSION_INFO "nightly" #endif +// This value was empirically and somewhat arbitrarily chosen; increase it for further safety. +#define END_OF_INPUT_EXTRA_OUTPUT_FRAMES 10000 + namespace py = pybind11; using namespace pybind11::literals; @@ -158,14 +161,15 @@ class Resampler { if (channels != _channels || channels == 0) throw std::domain_error("Invalid number of channels in input data."); - // Add a "fudge factor" of 10,000. This is because the actual number of + // Add a "fudge factor" to the size. This is because the actual number of // output samples generated on the last call when input is terminated can // be more than the expected number of output samples during mid-stream // steady-state processing. (Also, when the stream is started, the number // of output samples generated will generally be zero or otherwise less // than the number of samples in mid-stream processing.) const auto new_size = - static_cast(std::ceil(inbuf.shape[0] * sr_ratio)) + 10000; + static_cast(std::ceil(inbuf.shape[0] * sr_ratio)) + + END_OF_INPUT_EXTRA_OUTPUT_FRAMES; // allocate output array std::vector out_shape{new_size}; @@ -191,6 +195,9 @@ class Resampler { if ((size_t)src_data.output_frames_gen < new_size) { out_shape[0] = src_data.output_frames_gen; output.resize(out_shape); + } else if ((size_t)src_data.output_frames_gen >= new_size) { + // This means our fudge factor is too small. + throw std::runtime_error("Generated more output samples than expected!"); } return output;