diff --git a/pedalboard/ExternalPlugin.h b/pedalboard/ExternalPlugin.h index 14a52d8f..5344bb70 100644 --- a/pedalboard/ExternalPlugin.h +++ b/pedalboard/ExternalPlugin.h @@ -649,7 +649,7 @@ template class ExternalPlugin : public Plugin { // To compensate for any latency added by the plugin, // only tell Pedalboard to use the last _n_ samples. long usableSamplesProduced = - samplesProvided - pluginInstance->getLatencySamples(); + std::max(0L, samplesProvided - pluginInstance->getLatencySamples()); return static_cast( std::min(usableSamplesProduced, (long)outputBlock.getNumSamples())); } diff --git a/pedalboard/process.h b/pedalboard/process.h index c34e9aa2..329aab9b 100644 --- a/pedalboard/process.h +++ b/pedalboard/process.h @@ -317,6 +317,11 @@ process(const py::array_t inputArray, juce::dsp::ProcessContextReplacing context(ioBlock); int outputSamples = plugin->process(context); + if (outputSamples < 0) { + throw std::runtime_error( + "A plugin returned a negative number of output samples! " + "This is an internal Pedalboard error and should be reported."); + } pluginSamplesReceived += outputSamples; int missingSamples = blockSize - outputSamples; diff --git a/tests/test_external_plugins.py b/tests/test_external_plugins.py index 6503d31a..3a5448e6 100644 --- a/tests/test_external_plugins.py +++ b/tests/test_external_plugins.py @@ -630,7 +630,7 @@ def test_parameter_name_normalization(_input: str, expected: str): @pytest.mark.skipif(not plugin_named("CHOWTapeModel"), reason="Missing CHOWTapeModel plugin.") -@pytest.mark.parametrize("buffer_size", [128, 8192, 65536]) +@pytest.mark.parametrize("buffer_size", [16, 128, 8192, 65536]) @pytest.mark.parametrize("oversampling", [1, 2, 4, 8, 16]) def test_external_plugin_latency_compensation(buffer_size: int, oversampling: int): """