Skip to content

Fix MIDI overload resolution for ArrayLike support (#450)#471

Open
gijzelaerr wants to merge 5 commits intospotify:masterfrom
gijzelaerr:feature/arraylike-support-450
Open

Fix MIDI overload resolution for ArrayLike support (#450)#471
gijzelaerr wants to merge 5 commits intospotify:masterfrom
gijzelaerr:feature/arraylike-support-450

Conversation

@gijzelaerr
Copy link
Member

Summary

  • Fixes the macOS/Windows test failures introduced by Allow passing any ArrayLike object instead of just numpy.ndarray. #450 (psobot's ArrayLike support PR)
  • The root cause: Allow passing any ArrayLike object instead of just numpy.ndarray. #450 changed ExternalPlugin binding lambdas from const py::array to py::object, which broke pybind11's overload resolution between the audio process/__call__ and MIDI renderMIDIMessages overloads
  • When instrument plugins were called with MIDI messages (e.g. plugin(notes, 5.0, sr, reset=False)), the py::object audio overload matched first, causing ensureArrayLike() to fail on non-array MIDI message lists with: TypeError: Pedalboard only supports 32-bit and 64-bit floating point audio for processing.
  • The fix restores const py::array as the parameter type in the ExternalPlugin binding lambdas (AbstractExternalPlugin, VST3Plugin, AudioUnitPlugin) so pybind11 correctly rejects non-array inputs and falls through to the MIDI overload
  • The base Plugin class and standalone process() function retain py::object since they have no MIDI overloads to conflict with
  • pybind11 still auto-converts array-like objects (torch tensors, JAX arrays, etc.) to py::array via the buffer protocol and __array__ interface during argument dispatch

Based on @psobot's work in #450.

Test plan

  • Linux tests should continue to pass (no instrument plugins, so no MIDI dispatch)
  • macOS tests with instrument plugins (Magical8BitPlug2) should now pass — MIDI messages correctly route to renderMIDIMessages instead of the audio process path
  • Windows tests with instrument plugins should similarly pass
  • ArrayLike support (torch tensors, etc.) still works for audio processing via the base Plugin class and standalone process() function

🤖 Generated with Claude Code

psobot and others added 5 commits January 13, 2026 22:29
PR spotify#450 changed ExternalPlugin binding lambdas to accept py::object
instead of const py::array for the audio input parameter. This broke
pybind11's overload resolution for instrument plugins: since py::object
matches any Python type, calls with MIDI messages (e.g.
plugin(notes, 5.0, sr, reset=False)) would match the audio overload
before the MIDI overload, causing ensureArrayLike() to fail on
non-array-like MIDI message lists with:
  TypeError: Pedalboard only supports 32-bit and 64-bit floating point
  audio for processing.

The fix restores const py::array as the parameter type in the
ExternalPlugin binding lambdas (for AbstractExternalPlugin, VST3Plugin,
and AudioUnitPlugin) so pybind11 correctly rejects non-array inputs and
falls through to the MIDI overload. The base Plugin class and standalone
process() function retain py::object since they have no MIDI overloads.
pybind11 will still auto-convert array-like objects (torch tensors, etc.)
to py::array via the buffer protocol and __array__ interface.

Based on psobot's work in spotify#450.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants