|
40 | 40 | #define VERSION_INFO "nightly" |
41 | 41 | #endif |
42 | 42 |
|
| 43 | +// This value was empirically and somewhat arbitrarily chosen; increase it for further safety. |
| 44 | +#define END_OF_INPUT_EXTRA_OUTPUT_FRAMES 10000 |
| 45 | + |
43 | 46 | namespace py = pybind11; |
44 | 47 | using namespace pybind11::literals; |
45 | 48 |
|
@@ -158,8 +161,15 @@ class Resampler { |
158 | 161 | if (channels != _channels || channels == 0) |
159 | 162 | throw std::domain_error("Invalid number of channels in input data."); |
160 | 163 |
|
| 164 | + // Add a "fudge factor" to the size. This is because the actual number of |
| 165 | + // output samples generated on the last call when input is terminated can |
| 166 | + // be more than the expected number of output samples during mid-stream |
| 167 | + // steady-state processing. (Also, when the stream is started, the number |
| 168 | + // of output samples generated will generally be zero or otherwise less |
| 169 | + // than the number of samples in mid-stream processing.) |
161 | 170 | const auto new_size = |
162 | | - static_cast<size_t>(std::ceil(inbuf.shape[0] * sr_ratio)); |
| 171 | + static_cast<size_t>(std::ceil(inbuf.shape[0] * sr_ratio)) |
| 172 | + + END_OF_INPUT_EXTRA_OUTPUT_FRAMES; |
163 | 173 |
|
164 | 174 | // allocate output array |
165 | 175 | std::vector<size_t> out_shape{new_size}; |
@@ -188,6 +198,9 @@ class Resampler { |
188 | 198 | if ((size_t)src_data.output_frames_gen < new_size) { |
189 | 199 | out_shape[0] = src_data.output_frames_gen; |
190 | 200 | output.resize(out_shape); |
| 201 | + } else if ((size_t)src_data.output_frames_gen >= new_size) { |
| 202 | + // This means our fudge factor is too small. |
| 203 | + throw std::runtime_error("Generated more output samples than expected!"); |
191 | 204 | } |
192 | 205 |
|
193 | 206 | return output; |
|
0 commit comments