inline void init_convolution()

in pedalboard/plugins/Convolution.h [94:201]


inline void init_convolution(py::module &m) {
  py::class_<JucePlugin<ConvolutionWithMix>, Plugin,
             std::shared_ptr<JucePlugin<ConvolutionWithMix>>>(
      m, "Convolution",
      "An audio convolution, suitable for things like speaker simulation or "
      "reverb modeling.\n\n"
      "The convolution impulse response can be specified either by filename or "
      "as a 32-bit floating point NumPy array. If a NumPy array is provided, "
      "the ``sample_rate`` argument must also be provided to indicate the "
      "sample rate of the impulse response.\n\n*Support for passing NumPy "
      "arrays as impulse responses introduced in v0.9.10.*")
      .def(py::init([](std::variant<std::string,
                                    py::array_t<float, py::array::c_style>>
                           impulseResponse,
                       float mix, std::optional<double> sampleRate) {
             auto plugin = std::make_unique<JucePlugin<ConvolutionWithMix>>();

             if (auto *impulseResponseFilename =
                     std::get_if<std::string>(&impulseResponse)) {
               py::gil_scoped_release release;
               // Load the IR file on construction, to handle errors
               auto inputFile = juce::File(*impulseResponseFilename);
               // Test opening the file before we pass it to
               // loadImpulseResponse, which reloads it in the background:
               {
                 juce::FileInputStream stream(inputFile);
                 if (!stream.openedOk()) {
                   throw std::runtime_error(
                       "Unable to load impulse response: " +
                       *impulseResponseFilename);
                 }
               }

               plugin->getDSP().getConvolution().loadImpulseResponse(
                   inputFile, juce::dsp::Convolution::Stereo::yes,
                   juce::dsp::Convolution::Trim::no, 0);
               plugin->getDSP().setImpulseResponseFilename(
                   *impulseResponseFilename);
             } else if (auto *inputArray =
                            std::get_if<py::array_t<float, py::array::c_style>>(
                                &impulseResponse)) {
               if (!sampleRate) {
                 throw std::runtime_error(
                     "sample_rate must be provided when passing a numpy array "
                     "as an impulse response.");
               }
               plugin->getDSP().getConvolution().loadImpulseResponse(
                   std::move(copyPyArrayIntoJuceBuffer(*inputArray)),
                   *sampleRate, juce::dsp::Convolution::Stereo::yes,
                   juce::dsp::Convolution::Trim::no,
                   juce::dsp::Convolution::Normalise::yes);

               plugin->getDSP().setImpulseResponse(
                   copyPyArrayIntoJuceBuffer(*inputArray));
               plugin->getDSP().setSampleRate(*sampleRate);
             }
             plugin->getDSP().setMix(mix);
             return plugin;
           }),
           py::arg("impulse_response_filename"), py::arg("mix") = 1.0,
           py::arg("sample_rate") = py::none())
      .def("__repr__",
           [](JucePlugin<ConvolutionWithMix> &plugin) {
             std::ostringstream ss;
             ss << "<pedalboard.Convolution";
             if (plugin.getDSP().getImpulseResponseFilename()) {
               ss << " impulse_response_filename="
                  << *plugin.getDSP().getImpulseResponseFilename();
             } else if (plugin.getDSP().getImpulseResponse()) {
               ss << " impulse_response=<"
                  << plugin.getDSP().getImpulseResponse()->getNumSamples()
                  << " samples of "
                  << plugin.getDSP().getImpulseResponse()->getNumChannels()
                  << "-channel audio at " << *plugin.getDSP().getSampleRate()
                  << " Hz>";
             }

             ss << " mix=" << plugin.getDSP().getMix();
             ss << " at " << &plugin;
             ss << ">";
             return ss.str();
           })
      .def_property_readonly(
          "impulse_response_filename",
          [](JucePlugin<ConvolutionWithMix> &plugin) {
            return plugin.getDSP().getImpulseResponseFilename();
          })
      .def_property_readonly(
          "impulse_response",
          [](JucePlugin<ConvolutionWithMix> &plugin)
              -> std::optional<py::array_t<float, py::array::c_style>> {
            if (plugin.getDSP().getImpulseResponse()) {
              return {copyJuceBufferIntoPyArray(
                  *plugin.getDSP().getImpulseResponse(),
                  ChannelLayout::NotInterleaved, 0, 2)};
            } else {
              return {};
            }
          })
      .def_property(
          "mix",
          [](JucePlugin<ConvolutionWithMix> &plugin) {
            return plugin.getDSP().getMix();
          },
          [](JucePlugin<ConvolutionWithMix> &plugin, double newMix) {
            return plugin.getDSP().setMix(newMix);
          });
}