Skip to content
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
38 changes: 38 additions & 0 deletions pedalboard/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,44 @@ processFloat32(const py::array_t<float, py::array::c_style> inputArray,
juce::AudioBuffer<float> ioBuffer =
copyPyArrayIntoJuceBuffer(inputArray, {inputChannelLayout});

// ======= DETECTION FOR INT16-CONVERTED FLOAT DATA =======
bool allIntegers = true;
bool looksLikeInt16 = true;

for (int c = 0; c < ioBuffer.getNumChannels(); c++) {
float *channelData = ioBuffer.getWritePointer(c);
for (int i = 0; i < ioBuffer.getNumSamples(); i++) {
float value = channelData[i];

// Check if the value is very close to an integer
if (std::abs(value - std::round(value)) > 1e-6) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to use if (f == std::trunc(f)) here instead, as the use case that we're trying to detect is when a user passes in an int16 (or, rarely, an int32 array containing 24-bit integer data) and PyBind11 automatically casts it to float. In such cases, the values should be exactly integers, as float can represent all 24-bit integers exactly.

allIntegers = false;
}

// Check if the value is within int16 range
if (value < -32768.0 || value > 32767.0) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need another check here to ensure that at least some values are outside of [-1, 1], or else this will trigger on all-silent inputs.

looksLikeInt16 = false;
}

// If both conditions are already violated, break early
if (!allIntegers && !looksLikeInt16) {
break;
}
}
if (!allIntegers && !looksLikeInt16) {
break;
}
}

// If all values are integers or look like int16, raise an error
if (allIntegers) {
throw std::runtime_error("Error: Input contains only integer values. Ensure proper floating-point conversion.");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need Error: as a prefix here; the user will already see this prefixed with RuntimeError: when it gets raised.

Suggested change
throw std::runtime_error("Error: Input contains only integer values. Ensure proper floating-point conversion.");
throw std::runtime_error("Provided input contains only integer values. Pedalboard uses floating-point audio on the range [-1, 1]. Ensure that your audio is in floating point format.");

}
if (looksLikeInt16) {
throw std::runtime_error("Error: Input appears to be improperly converted from 16-bit integer audio. Use proper scaling.");
}

// ======= Continue normal processing =======
if (ioBuffer.getNumChannels() == 0) {
unsigned int numChannels = 0;
unsigned int numSamples = ioBuffer.getNumSamples();
Expand Down
Loading