Skip to content

Increase expected size of output sample buffer, to correctly handle input termination. #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
15 changes: 14 additions & 1 deletion src/samplerate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -158,8 +161,15 @@ class Resampler {
if (channels != _channels || channels == 0)
throw std::domain_error("Invalid number of channels in input data.");

// 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<size_t>(std::ceil(inbuf.shape[0] * sr_ratio));
static_cast<size_t>(std::ceil(inbuf.shape[0] * sr_ratio))
+ END_OF_INPUT_EXTRA_OUTPUT_FRAMES;

// allocate output array
std::vector<size_t> out_shape{new_size};
Expand All @@ -185,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;
Expand Down