pedalboard_native/__init__.pyi (785 lines of code) (raw):

"""This module provides classes and functions for generating and adding effects to audio. Most classes in this module are subclasses of ``Plugin``, each of which allows applying effects to an audio buffer or stream. For audio I/O classes (i.e.: reading and writing audio files), see ``pedalboard.io``.""" from __future__ import annotations import pedalboard_native import typing original_overload = typing.overload __OVERLOADED_DOCSTRINGS = {} def patch_overload(func): original_overload(func) if func.__doc__: __OVERLOADED_DOCSTRINGS[func.__qualname__] = func.__doc__ else: func.__doc__ = __OVERLOADED_DOCSTRINGS.get(func.__qualname__) if func.__doc__: # Work around the fact that pybind11-stubgen generates # duplicate docstrings sometimes, once for each overload: docstring = func.__doc__ if docstring[len(docstring) // 2 :].strip() == docstring[: -len(docstring) // 2].strip(): func.__doc__ = docstring[len(docstring) // 2 :].strip() return func typing.overload = patch_overload from typing_extensions import Literal from enum import Enum import threading import numpy _Shape = typing.Tuple[int, ...] __all__ = [ "AudioUnitPlugin", "Bitcrush", "Chorus", "Clipping", "Compressor", "Convolution", "Delay", "Distortion", "ExternalPlugin", "GSMFullRateCompressor", "Gain", "HighShelfFilter", "HighpassFilter", "IIRFilter", "Invert", "LadderFilter", "Limiter", "LowShelfFilter", "LowpassFilter", "MP3Compressor", "NoiseGate", "PeakFilter", "Phaser", "PitchShift", "Plugin", "PluginContainer", "Resample", "Reverb", "VST3Plugin", "io", "process", "utils", ] class Plugin: """ A generic audio processing plugin. Base class of all Pedalboard plugins. """ def __call__( self, input_array: numpy.ndarray, sample_rate: float, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: """ Run an audio buffer through this plugin. Alias for :py:meth:`process`. """ def process( self, input_array: numpy.ndarray, sample_rate: float, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: """ Run a 32-bit or 64-bit floating point audio buffer through this plugin. (If calling this multiple times with multiple plugins, consider creating a :class:`pedalboard.Pedalboard` object instead.) The returned array may contain up to (but not more than) the same number of samples as were provided. If fewer samples were returned than expected, the plugin has likely buffered audio inside itself. To receive the remaining audio, pass another audio buffer into ``process`` with ``reset`` set to ``True``. If the provided buffer uses a 64-bit datatype, it will be converted to 32-bit for processing. The provided ``buffer_size`` argument will be used to control the size of each chunk of audio provided to the plugin. Higher buffer sizes may speed up processing at the expense of memory usage. The ``reset`` flag determines if all of the plugins should be reset before processing begins, clearing any state from previous calls to ``process``. If calling ``process`` multiple times while processing the same audio file or buffer, set ``reset`` to ``False``. The layout of the provided ``input_array`` will be automatically detected, assuming that the smaller dimension corresponds with the number of channels. If the number of samples and the number of channels are the same, each :py:class:`Plugin` object will use the last-detected channel layout until :py:meth:`reset` is explicitly called (as of v0.9.9). .. note:: The :py:meth:`process` method can also be used via :py:meth:`__call__`; i.e.: just calling this object like a function (``my_plugin(...)``) will automatically invoke :py:meth:`process` with the same arguments. """ def reset(self) -> None: """ Clear any internal state stored by this plugin (e.g.: reverb tails, delay lines, LFO state, etc). The values of plugin parameters will remain unchanged. """ @property def is_effect(self) -> bool: """ True iff this plugin is an audio effect and accepts audio as input. *Introduced in v0.7.4.* """ @property def is_instrument(self) -> bool: """ True iff this plugin is not an audio effect and accepts only MIDI input, not audio. *Introduced in v0.7.4.* """ pass class Bitcrush(Plugin): """ A plugin that reduces the signal to a given bit depth, giving the audio a lo-fi, digitized sound. Floating-point bit depths are supported. Bitcrushing changes the amount of "vertical" resolution used for an audio signal (i.e.: how many unique values could be used to represent each sample). For an effect that changes the "horizontal" resolution (i.e.: how many samples are available per second), see :class:`pedalboard.Resample`. """ def __init__(self, bit_depth: float = 8) -> None: ... def __repr__(self) -> str: ... @property def bit_depth(self) -> float: """ The bit depth to quantize the signal to. Must be between 0 and 32 bits. May be an integer, decimal, or floating-point value. Each audio sample will be quantized onto ``2 ** bit_depth`` values. """ @bit_depth.setter def bit_depth(self, arg1: float) -> None: """ The bit depth to quantize the signal to. Must be between 0 and 32 bits. May be an integer, decimal, or floating-point value. Each audio sample will be quantized onto ``2 ** bit_depth`` values. """ pass class Chorus(Plugin): """ A basic chorus effect. This audio effect can be controlled via the speed and depth of the LFO controlling the frequency response, a mix control, a feedback control, and the centre delay of the modulation. Note: To get classic chorus sounds try to use a centre delay time around 7-8 ms with a low feeback volume and a low depth. This effect can also be used as a flanger with a lower centre delay time and a lot of feedback, and as a vibrato effect if the mix value is 1. """ def __init__( self, rate_hz: float = 1.0, depth: float = 0.25, centre_delay_ms: float = 7.0, feedback: float = 0.0, mix: float = 0.5, ) -> None: ... def __repr__(self) -> str: ... @property def centre_delay_ms(self) -> float: """ """ @centre_delay_ms.setter def centre_delay_ms(self, arg1: float) -> None: pass @property def depth(self) -> float: """ """ @depth.setter def depth(self, arg1: float) -> None: pass @property def feedback(self) -> float: """ """ @feedback.setter def feedback(self, arg1: float) -> None: pass @property def mix(self) -> float: """ """ @mix.setter def mix(self, arg1: float) -> None: pass @property def rate_hz(self) -> float: """ The speed of the chorus effect's low-frequency oscillator (LFO), in Hertz. This value must be between 0 Hz and 100 Hz. """ @rate_hz.setter def rate_hz(self, arg1: float) -> None: """ The speed of the chorus effect's low-frequency oscillator (LFO), in Hertz. This value must be between 0 Hz and 100 Hz. """ pass class Clipping(Plugin): """ A distortion plugin that adds hard distortion to the signal by clipping the signal at the provided threshold (in decibels). """ def __init__(self, threshold_db: float = -6.0) -> None: ... def __repr__(self) -> str: ... @property def threshold_db(self) -> float: """ """ @threshold_db.setter def threshold_db(self, arg1: float) -> None: pass pass class Compressor(Plugin): """ A dynamic range compressor, used to reduce the volume of loud sounds and "compress" the loudness of the signal. For a lossy compression algorithm that introduces noise or artifacts, see ``pedalboard.MP3Compressor`` or ``pedalboard.GSMCompressor``. """ def __init__( self, threshold_db: float = 0, ratio: float = 1, attack_ms: float = 1.0, release_ms: float = 100, ) -> None: ... def __repr__(self) -> str: ... @property def attack_ms(self) -> float: """ """ @attack_ms.setter def attack_ms(self, arg1: float) -> None: pass @property def ratio(self) -> float: """ """ @ratio.setter def ratio(self, arg1: float) -> None: pass @property def release_ms(self) -> float: """ """ @release_ms.setter def release_ms(self, arg1: float) -> None: pass @property def threshold_db(self) -> float: """ """ @threshold_db.setter def threshold_db(self, arg1: float) -> None: pass pass class Convolution(Plugin): """ An audio convolution, suitable for things like speaker simulation or reverb modeling. 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. *Support for passing NumPy arrays as impulse responses introduced in v0.9.10.* """ def __init__( self, impulse_response_filename: typing.Union[ str, numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]] ], mix: float = 1.0, sample_rate: typing.Optional[float] = None, ) -> None: ... def __repr__(self) -> str: ... @property def impulse_response( self, ) -> typing.Optional[numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]]: """ """ @property def impulse_response_filename(self) -> typing.Optional[str]: """ """ @property def mix(self) -> float: """ """ @mix.setter def mix(self, arg1: float) -> None: pass pass class Delay(Plugin): """ A digital delay plugin with controllable delay time, feedback percentage, and dry/wet mix. """ def __init__( self, delay_seconds: float = 0.5, feedback: float = 0.0, mix: float = 0.5 ) -> None: ... def __repr__(self) -> str: ... @property def delay_seconds(self) -> float: """ """ @delay_seconds.setter def delay_seconds(self, arg1: float) -> None: pass @property def feedback(self) -> float: """ """ @feedback.setter def feedback(self, arg1: float) -> None: pass @property def mix(self) -> float: """ """ @mix.setter def mix(self, arg1: float) -> None: pass pass class Distortion(Plugin): """ A distortion effect, which applies a non-linear (``tanh``, or hyperbolic tangent) waveshaping function to apply harmonically pleasing distortion to a signal. This plugin produces a signal that is roughly equivalent to running: ``def distortion(x): return tanh(x * db_to_gain(drive_db))`` """ def __init__(self, drive_db: float = 25) -> None: ... def __repr__(self) -> str: ... @property def drive_db(self) -> float: """ """ @drive_db.setter def drive_db(self, arg1: float) -> None: pass pass class ExternalPlugin(Plugin): """ A wrapper around a third-party effect plugin. Don't use this directly; use one of :class:`pedalboard.VST3Plugin` or :class:`pedalboard.AudioUnitPlugin` instead. """ @typing.overload def __call__( self, input_array: numpy.ndarray, sample_rate: float, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: """ Run an audio or MIDI buffer through this plugin, returning audio. Alias for :py:meth:`process`. Run an audio or MIDI buffer through this plugin, returning audio. Alias for :py:meth:`process`. """ @typing.overload def __call__( self, midi_messages: object, duration: float, sample_rate: float, num_channels: int = 2, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: ... @typing.overload def process( self, midi_messages: object, duration: float, sample_rate: float, num_channels: int = 2, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: """ Pass a buffer of audio (as a 32- or 64-bit NumPy array) *or* a list of MIDI messages to this plugin, returning audio. (If calling this multiple times with multiple effect plugins, consider creating a :class:`pedalboard.Pedalboard` object instead.) When provided audio as input, the returned array may contain up to (but not more than) the same number of samples as were provided. If fewer samples were returned than expected, the plugin has likely buffered audio inside itself. To receive the remaining audio, pass another audio buffer into ``process`` with ``reset`` set to ``True``. If the provided buffer uses a 64-bit datatype, it will be converted to 32-bit for processing. If provided MIDI messages as input, the provided ``midi_messages`` must be a Python ``List`` containing one of the following types: - Objects with a ``bytes()`` method and ``time`` property (such as :doc:`mido:messages` from :doc:`mido:index`, not included with Pedalboard) - Tuples that look like: ``(midi_bytes: bytes, timestamp_in_seconds: float)`` - Tuples that look like: ``(midi_bytes: List[int], timestamp_in_seconds: float)`` The returned array will contain ``duration`` seconds worth of audio at the provided ``sample_rate``. Each MIDI message will be sent to the plugin at its timestamp, where a timestamp of ``0`` indicates the start of the buffer, and a timestamp equal to ``duration`` indicates the end of the buffer. (Any MIDI messages whose timestamps are greater than ``duration`` will be ignored.) The provided ``buffer_size`` argument will be used to control the size of each chunk of audio returned by the plugin at once. Higher buffer sizes may speed up processing, but may cause increased memory usage. The ``reset`` flag determines if this plugin should be reset before processing begins, clearing any state from previous calls to ``process``. If calling ``process`` multiple times while processing the same audio or MIDI stream, set ``reset`` to ``False``. .. note:: The :py:meth:`process` method can also be used via :py:meth:`__call__`; i.e.: just calling this object like a function (``my_plugin(...)``) will automatically invoke :py:meth:`process` with the same arguments. Examples -------- Running audio through an external effect plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_effect with AudioFile("input-audio.wav") as f: output_audio = plugin(f.read(), f.samplerate) Rendering MIDI via an external instrument plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile from mido import Message # not part of Pedalboard, but convenient! plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_instrument sample_rate = 44100 num_channels = 2 with AudioFile("output-audio.wav", "w", sample_rate, num_channels) as f: f.write(plugin( [Message("note_on", note=60), Message("note_off", note=60, time=4)], sample_rate=sample_rate, duration=5, num_channels=num_channels )) *Support for instrument plugins introduced in v0.7.4.* Pass a buffer of audio (as a 32- or 64-bit NumPy array) *or* a list of MIDI messages to this plugin, returning audio. (If calling this multiple times with multiple effect plugins, consider creating a :class:`pedalboard.Pedalboard` object instead.) When provided audio as input, the returned array may contain up to (but not more than) the same number of samples as were provided. If fewer samples were returned than expected, the plugin has likely buffered audio inside itself. To receive the remaining audio, pass another audio buffer into ``process`` with ``reset`` set to ``True``. If the provided buffer uses a 64-bit datatype, it will be converted to 32-bit for processing. If provided MIDI messages as input, the provided ``midi_messages`` must be a Python ``List`` containing one of the following types: - Objects with a ``bytes()`` method and ``time`` property (such as :doc:`mido:messages` from :doc:`mido:index`, not included with Pedalboard) - Tuples that look like: ``(midi_bytes: bytes, timestamp_in_seconds: float)`` - Tuples that look like: ``(midi_bytes: List[int], timestamp_in_seconds: float)`` The returned array will contain ``duration`` seconds worth of audio at the provided ``sample_rate``. Each MIDI message will be sent to the plugin at its timestamp, where a timestamp of ``0`` indicates the start of the buffer, and a timestamp equal to ``duration`` indicates the end of the buffer. (Any MIDI messages whose timestamps are greater than ``duration`` will be ignored.) The provided ``buffer_size`` argument will be used to control the size of each chunk of audio returned by the plugin at once. Higher buffer sizes may speed up processing, but may cause increased memory usage. The ``reset`` flag determines if this plugin should be reset before processing begins, clearing any state from previous calls to ``process``. If calling ``process`` multiple times while processing the same audio or MIDI stream, set ``reset`` to ``False``. .. note:: The :py:meth:`process` method can also be used via :py:meth:`__call__`; i.e.: just calling this object like a function (``my_plugin(...)``) will automatically invoke :py:meth:`process` with the same arguments. Examples -------- Running audio through an external effect plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_effect with AudioFile("input-audio.wav") as f: output_audio = plugin(f.read(), f.samplerate) Rendering MIDI via an external instrument plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile from mido import Message # not part of Pedalboard, but convenient! plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_instrument sample_rate = 44100 num_channels = 2 with AudioFile("output-audio.wav", "w", sample_rate, num_channels) as f: f.write(plugin( [Message("note_on", note=60), Message("note_off", note=60, time=4)], sample_rate=sample_rate, duration=5, num_channels=num_channels )) *Support for instrument plugins introduced in v0.7.4.* """ @typing.overload def process( self, input_array: numpy.ndarray, sample_rate: float, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: ... pass class Gain(Plugin): """ A gain plugin that increases or decreases the volume of a signal by amplifying or attenuating it by the provided value (in decibels). No distortion or other effects are applied. Think of this as a volume control. """ def __init__(self, gain_db: float = 1.0) -> None: ... def __repr__(self) -> str: ... @property def gain_db(self) -> float: """ """ @gain_db.setter def gain_db(self, arg1: float) -> None: pass pass class IIRFilter(Plugin): """ An abstract class that implements various kinds of infinite impulse response (IIR) filter designs. This should not be used directly; use :class:`HighShelfFilter`, :class:`LowShelfFilter`, or :class:`PeakFilter` directly instead. """ pass class HighpassFilter(Plugin): """ Apply a first-order high-pass filter with a roll-off of 6dB/octave. The cutoff frequency will be attenuated by -3dB (i.e.: :math:`\\frac{1}{\\sqrt{2}}` as loud, expressed as a gain factor) and lower frequencies will be attenuated by a further 6dB per octave.) """ def __init__(self, cutoff_frequency_hz: float = 50) -> None: ... def __repr__(self) -> str: ... @property def cutoff_frequency_hz(self) -> float: """ """ @cutoff_frequency_hz.setter def cutoff_frequency_hz(self, arg1: float) -> None: pass pass class HighShelfFilter(IIRFilter, Plugin): """ A high shelf filter plugin with variable Q and gain, as would be used in an equalizer. Frequencies above the cutoff frequency will be boosted (or cut) by the provided gain (in decibels). """ def __init__( self, cutoff_frequency_hz: float = 440, gain_db: float = 0.0, q: float = 0.7071067690849304 ) -> None: ... def __repr__(self) -> str: ... @property def cutoff_frequency_hz(self) -> float: """ """ @cutoff_frequency_hz.setter def cutoff_frequency_hz(self, arg1: float) -> None: pass @property def gain_db(self) -> float: """ """ @gain_db.setter def gain_db(self, arg1: float) -> None: pass @property def q(self) -> float: """ """ @q.setter def q(self, arg1: float) -> None: pass pass class Invert(Plugin): """ Flip the polarity of the signal. This effect is not audible on its own and takes no parameters. This effect is mathematically identical to ``def invert(x): return -x``. Inverting a signal may be useful to cancel out signals in many cases; for instance, ``Invert`` can be used with the ``Mix`` plugin to remove the original signal from an effects chain that contains multiple signals. """ def __repr__(self) -> str: ... pass class LadderFilter(Plugin): """ A multi-mode audio filter based on the classic Moog synthesizer ladder filter, invented by Dr. Bob Moog in 1968. Depending on the filter's mode, frequencies above, below, or on both sides of the cutoff frequency will be attenuated. Higher values for the ``resonance`` parameter may cause peaks in the frequency response around the cutoff frequency. """ class Mode(Enum): """ The type of filter architecture to use. """ LPF12 = 0 # fmt: skip """ A low-pass filter with 12 dB of attenuation per octave above the cutoff frequency. """ HPF12 = 1 # fmt: skip """ A high-pass filter with 12 dB of attenuation per octave below the cutoff frequency. """ BPF12 = 2 # fmt: skip """ A band-pass filter with 12 dB of attenuation per octave on both sides of the cutoff frequency. """ LPF24 = 3 # fmt: skip """ A low-pass filter with 24 dB of attenuation per octave above the cutoff frequency. """ HPF24 = 4 # fmt: skip """ A high-pass filter with 24 dB of attenuation per octave below the cutoff frequency. """ BPF24 = 5 # fmt: skip """ A band-pass filter with 24 dB of attenuation per octave on both sides of the cutoff frequency. """ def __init__( self, mode: LadderFilter.Mode = Mode.LPF12, cutoff_hz: float = 200, resonance: float = 0, drive: float = 1.0, ) -> None: ... def __repr__(self) -> str: ... @property def cutoff_hz(self) -> float: """ """ @cutoff_hz.setter def cutoff_hz(self, arg1: float) -> None: pass @property def drive(self) -> float: """ """ @drive.setter def drive(self, arg1: float) -> None: pass @property def mode(self) -> LadderFilter.Mode: """ """ @mode.setter def mode(self, arg1: LadderFilter.Mode) -> None: pass @property def resonance(self) -> float: """ """ @resonance.setter def resonance(self, arg1: float) -> None: pass BPF12: pedalboard_native.LadderFilter.Mode # value = <Mode.BPF12: 2> BPF24: pedalboard_native.LadderFilter.Mode # value = <Mode.BPF24: 5> HPF12: pedalboard_native.LadderFilter.Mode # value = <Mode.HPF12: 1> HPF24: pedalboard_native.LadderFilter.Mode # value = <Mode.HPF24: 4> LPF12: pedalboard_native.LadderFilter.Mode # value = <Mode.LPF12: 0> LPF24: pedalboard_native.LadderFilter.Mode # value = <Mode.LPF24: 3> pass class Limiter(Plugin): """ A simple limiter with standard threshold and release time controls, featuring two compressors and a hard clipper at 0 dB. """ def __init__(self, threshold_db: float = -10.0, release_ms: float = 100.0) -> None: ... def __repr__(self) -> str: ... @property def release_ms(self) -> float: """ """ @release_ms.setter def release_ms(self, arg1: float) -> None: pass @property def threshold_db(self) -> float: """ """ @threshold_db.setter def threshold_db(self, arg1: float) -> None: pass pass class LowShelfFilter(IIRFilter, Plugin): """ A low shelf filter with variable Q and gain, as would be used in an equalizer. Frequencies below the cutoff frequency will be boosted (or cut) by the provided gain value. """ def __init__( self, cutoff_frequency_hz: float = 440, gain_db: float = 0.0, q: float = 0.7071067690849304 ) -> None: ... def __repr__(self) -> str: ... @property def cutoff_frequency_hz(self) -> float: """ """ @cutoff_frequency_hz.setter def cutoff_frequency_hz(self, arg1: float) -> None: pass @property def gain_db(self) -> float: """ """ @gain_db.setter def gain_db(self, arg1: float) -> None: pass @property def q(self) -> float: """ """ @q.setter def q(self, arg1: float) -> None: pass pass class LowpassFilter(Plugin): """ Apply a first-order low-pass filter with a roll-off of 6dB/octave. The cutoff frequency will be attenuated by -3dB (i.e.: 0.707x as loud). """ def __init__(self, cutoff_frequency_hz: float = 50) -> None: ... def __repr__(self) -> str: ... @property def cutoff_frequency_hz(self) -> float: """ """ @cutoff_frequency_hz.setter def cutoff_frequency_hz(self, arg1: float) -> None: pass pass class MP3Compressor(Plugin): """ An MP3 compressor plugin that runs the LAME MP3 encoder in real-time to add compression artifacts to the audio stream. Currently only supports variable bit-rate mode (VBR) and accepts a floating-point VBR quality value (between 0.0 and 10.0; lower is better). Note that the MP3 format only supports 8kHz, 11025Hz, 12kHz, 16kHz, 22050Hz, 24kHz, 32kHz, 44.1kHz, and 48kHz audio; if an unsupported sample rate is provided, an exception will be thrown at processing time. """ def __init__(self, vbr_quality: float = 2.0) -> None: ... def __repr__(self) -> str: ... @property def vbr_quality(self) -> float: """ """ @vbr_quality.setter def vbr_quality(self, arg1: float) -> None: pass pass class NoiseGate(Plugin): """ A simple noise gate with standard threshold, ratio, attack time and release time controls. Can be used as an expander if the ratio is low. """ def __init__( self, threshold_db: float = -100.0, ratio: float = 10, attack_ms: float = 1.0, release_ms: float = 100.0, ) -> None: ... def __repr__(self) -> str: ... @property def attack_ms(self) -> float: """ """ @attack_ms.setter def attack_ms(self, arg1: float) -> None: pass @property def ratio(self) -> float: """ """ @ratio.setter def ratio(self, arg1: float) -> None: pass @property def release_ms(self) -> float: """ """ @release_ms.setter def release_ms(self, arg1: float) -> None: pass @property def threshold_db(self) -> float: """ """ @threshold_db.setter def threshold_db(self, arg1: float) -> None: pass pass class PeakFilter(IIRFilter, Plugin): """ A peak (or notch) filter with variable Q and gain, as would be used in an equalizer. Frequencies around the cutoff frequency will be boosted (or cut) by the provided gain value. """ def __init__( self, cutoff_frequency_hz: float = 440, gain_db: float = 0.0, q: float = 0.7071067690849304 ) -> None: ... def __repr__(self) -> str: ... @property def cutoff_frequency_hz(self) -> float: """ """ @cutoff_frequency_hz.setter def cutoff_frequency_hz(self, arg1: float) -> None: pass @property def gain_db(self) -> float: """ """ @gain_db.setter def gain_db(self, arg1: float) -> None: pass @property def q(self) -> float: """ """ @q.setter def q(self, arg1: float) -> None: pass pass class Phaser(Plugin): """ A 6 stage phaser that modulates first order all-pass filters to create sweeping notches in the magnitude frequency response. This audio effect can be controlled with standard phaser parameters: the speed and depth of the LFO controlling the frequency response, a mix control, a feedback control, and the centre frequency of the modulation. """ def __init__( self, rate_hz: float = 1.0, depth: float = 0.5, centre_frequency_hz: float = 1300.0, feedback: float = 0.0, mix: float = 0.5, ) -> None: ... def __repr__(self) -> str: ... @property def centre_frequency_hz(self) -> float: """ """ @centre_frequency_hz.setter def centre_frequency_hz(self, arg1: float) -> None: pass @property def depth(self) -> float: """ """ @depth.setter def depth(self, arg1: float) -> None: pass @property def feedback(self) -> float: """ """ @feedback.setter def feedback(self, arg1: float) -> None: pass @property def mix(self) -> float: """ """ @mix.setter def mix(self, arg1: float) -> None: pass @property def rate_hz(self) -> float: """ """ @rate_hz.setter def rate_hz(self, arg1: float) -> None: pass pass class PitchShift(Plugin): """ A pitch shifting effect that can change the pitch of audio without affecting its duration. This effect uses `Chris Cannam's wonderful *Rubber Band* library <https://breakfastquay.com/rubberband/>`_ audio stretching library. """ def __init__(self, semitones: float = 0.0) -> None: ... def __repr__(self) -> str: ... @property def semitones(self) -> float: """ """ @semitones.setter def semitones(self, arg1: float) -> None: pass pass class AudioUnitPlugin(ExternalPlugin): """ A wrapper around third-party, audio effect or instrument plugins in `Apple's Audio Unit <https://en.wikipedia.org/wiki/Audio_Units>`_ format. Audio Unit plugins are only supported on macOS. This class will be unavailable on non-macOS platforms. Plugin files must be installed in the appropriate system-wide path for them to be loadable (usually ``/Library/Audio/Plug-Ins/Components/`` or ``~/Library/Audio/Plug-Ins/Components/``). For a plugin wrapper that works on Windows and Linux as well, see :class:`pedalboard.VST3Plugin`.) .. warning:: Some Audio Unit plugins may throw errors, hang, generate incorrect output, or outright crash if called from background threads. If you find that a Audio Unit plugin is not working as expected, try calling it from the main thread instead and `open a GitHub Issue to track the incompatibility <https://github.com/spotify/pedalboard/issues/new>`_. *Support for instrument plugins introduced in v0.7.4.* *Support for running Audio Unit plugins on background threads introduced in v0.8.8.* *Support for loading AUv3 plugins (* ``.appex`` *bundles) introduced in v0.9.5.* """ @typing.overload def __call__( self, input_array: numpy.ndarray, sample_rate: float, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: """ Run an audio or MIDI buffer through this plugin, returning audio. Alias for :py:meth:`process`. Run an audio or MIDI buffer through this plugin, returning audio. Alias for :py:meth:`process`. """ @typing.overload def __call__( self, midi_messages: object, duration: float, sample_rate: float, num_channels: int = 2, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: ... def __init__( self, path_to_plugin_file: str, parameter_values: object = None, plugin_name: typing.Optional[str] = None, initialization_timeout: float = 10.0, ) -> None: ... def __repr__(self) -> str: ... def _get_parameter(self, arg0: str) -> _AudioProcessorParameter: ... @staticmethod def get_plugin_names_for_file(filename: str) -> typing.List[str]: """ Return a list of plugin names contained within a given Audio Unit bundle (i.e.: a ``.component`` or ``.appex`` file). If the provided file cannot be scanned, an ``ImportError`` will be raised. Note that most Audio Units have a single plugin inside, but this method can be useful to determine if multiple plugins are present in one bundle, and if so, what their names are. """ @typing.overload def process( self, input_array: numpy.ndarray, sample_rate: float, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: """ Pass a buffer of audio (as a 32- or 64-bit NumPy array) *or* a list of MIDI messages to this plugin, returning audio. (If calling this multiple times with multiple effect plugins, consider creating a :class:`pedalboard.Pedalboard` object instead.) When provided audio as input, the returned array may contain up to (but not more than) the same number of samples as were provided. If fewer samples were returned than expected, the plugin has likely buffered audio inside itself. To receive the remaining audio, pass another audio buffer into ``process`` with ``reset`` set to ``True``. If the provided buffer uses a 64-bit datatype, it will be converted to 32-bit for processing. If provided MIDI messages as input, the provided ``midi_messages`` must be a Python ``List`` containing one of the following types: - Objects with a ``bytes()`` method and ``time`` property (such as :doc:`mido:messages` from :doc:`mido:index`, not included with Pedalboard) - Tuples that look like: ``(midi_bytes: bytes, timestamp_in_seconds: float)`` - Tuples that look like: ``(midi_bytes: List[int], timestamp_in_seconds: float)`` The returned array will contain ``duration`` seconds worth of audio at the provided ``sample_rate``. Each MIDI message will be sent to the plugin at its timestamp, where a timestamp of ``0`` indicates the start of the buffer, and a timestamp equal to ``duration`` indicates the end of the buffer. (Any MIDI messages whose timestamps are greater than ``duration`` will be ignored.) The provided ``buffer_size`` argument will be used to control the size of each chunk of audio returned by the plugin at once. Higher buffer sizes may speed up processing, but may cause increased memory usage. The ``reset`` flag determines if this plugin should be reset before processing begins, clearing any state from previous calls to ``process``. If calling ``process`` multiple times while processing the same audio or MIDI stream, set ``reset`` to ``False``. .. note:: The :py:meth:`process` method can also be used via :py:meth:`__call__`; i.e.: just calling this object like a function (``my_plugin(...)``) will automatically invoke :py:meth:`process` with the same arguments. Examples -------- Running audio through an external effect plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_effect with AudioFile("input-audio.wav") as f: output_audio = plugin(f.read(), f.samplerate) Rendering MIDI via an external instrument plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile from mido import Message # not part of Pedalboard, but convenient! plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_instrument sample_rate = 44100 num_channels = 2 with AudioFile("output-audio.wav", "w", sample_rate, num_channels) as f: f.write(plugin( [Message("note_on", note=60), Message("note_off", note=60, time=4)], sample_rate=sample_rate, duration=5, num_channels=num_channels )) *Support for instrument plugins introduced in v0.7.4.* Pass a buffer of audio (as a 32- or 64-bit NumPy array) *or* a list of MIDI messages to this plugin, returning audio. (If calling this multiple times with multiple effect plugins, consider creating a :class:`pedalboard.Pedalboard` object instead.) When provided audio as input, the returned array may contain up to (but not more than) the same number of samples as were provided. If fewer samples were returned than expected, the plugin has likely buffered audio inside itself. To receive the remaining audio, pass another audio buffer into ``process`` with ``reset`` set to ``True``. If the provided buffer uses a 64-bit datatype, it will be converted to 32-bit for processing. If provided MIDI messages as input, the provided ``midi_messages`` must be a Python ``List`` containing one of the following types: - Objects with a ``bytes()`` method and ``time`` property (such as :doc:`mido:messages` from :doc:`mido:index`, not included with Pedalboard) - Tuples that look like: ``(midi_bytes: bytes, timestamp_in_seconds: float)`` - Tuples that look like: ``(midi_bytes: List[int], timestamp_in_seconds: float)`` The returned array will contain ``duration`` seconds worth of audio at the provided ``sample_rate``. Each MIDI message will be sent to the plugin at its timestamp, where a timestamp of ``0`` indicates the start of the buffer, and a timestamp equal to ``duration`` indicates the end of the buffer. (Any MIDI messages whose timestamps are greater than ``duration`` will be ignored.) The provided ``buffer_size`` argument will be used to control the size of each chunk of audio returned by the plugin at once. Higher buffer sizes may speed up processing, but may cause increased memory usage. The ``reset`` flag determines if this plugin should be reset before processing begins, clearing any state from previous calls to ``process``. If calling ``process`` multiple times while processing the same audio or MIDI stream, set ``reset`` to ``False``. .. note:: The :py:meth:`process` method can also be used via :py:meth:`__call__`; i.e.: just calling this object like a function (``my_plugin(...)``) will automatically invoke :py:meth:`process` with the same arguments. Examples -------- Running audio through an external effect plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_effect with AudioFile("input-audio.wav") as f: output_audio = plugin(f.read(), f.samplerate) Rendering MIDI via an external instrument plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile from mido import Message # not part of Pedalboard, but convenient! plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_instrument sample_rate = 44100 num_channels = 2 with AudioFile("output-audio.wav", "w", sample_rate, num_channels) as f: f.write(plugin( [Message("note_on", note=60), Message("note_off", note=60, time=4)], sample_rate=sample_rate, duration=5, num_channels=num_channels )) *Support for instrument plugins introduced in v0.7.4.* """ @typing.overload def process( self, midi_messages: object, duration: float, sample_rate: float, num_channels: int = 2, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: ... def show_editor(self, close_event: typing.Optional[threading.Event] = None) -> None: """ Show the UI of this plugin as a native window. This method may only be called on the main thread, and will block the main thread until any of the following things happens: - the window is closed by clicking the close button - the window is closed by pressing the appropriate (OS-specific) keyboard shortcut - a KeyboardInterrupt (Ctrl-C) is sent to the program - the :py:meth:`threading.Event.set` method is called (by another thread) on a provided :py:class:`threading.Event` object An example of how to programmatically close an editor window:: import pedalboard from threading import Event, Thread plugin = pedalboard.load_plugin("../path-to-my-plugin-file") close_window_event = Event() def other_thread(): # do something to determine when to close the window if should_close_window: close_window_event.set() thread = Thread(target=other_thread) thread.start() # This will block until the other thread calls .set(): plugin.show_editor(close_window_event) """ @property def _parameters(self) -> typing.List[_AudioProcessorParameter]: """ """ @property def _reload_type(self) -> ExternalPluginReloadType: """ The behavior that this plugin exhibits when .reset() is called. This is an internal attribute which gets set on plugin instantiation and should only be accessed for debugging and testing. """ @_reload_type.setter def _reload_type(self, arg0: ExternalPluginReloadType) -> None: """ The behavior that this plugin exhibits when .reset() is called. This is an internal attribute which gets set on plugin instantiation and should only be accessed for debugging and testing. """ @property def category(self) -> str: """ A category that this plugin falls into, such as "Dynamics", "Reverbs", etc. *Introduced in v0.9.4.* """ @property def descriptive_name(self) -> str: """ A more descriptive name for this plugin. This may be the same as the 'name' field, but some plugins may provide an alternative name. *Introduced in v0.9.4.* """ @property def has_shared_container(self) -> bool: """ True iff this plugin is part of a multi-plugin container. *Introduced in v0.9.4.* """ @property def identifier(self) -> str: """ A string that can be saved and used to uniquely identify this plugin (and version) again. *Introduced in v0.9.4.* """ @property def is_instrument(self) -> bool: """ True iff this plugin identifies itself as an instrument (generator, synthesizer, etc) plugin. *Introduced in v0.9.4.* """ @property def manufacturer_name(self) -> str: """ The name of the manufacturer of this plugin, as reported by the plugin itself. *Introduced in v0.9.4.* """ @property def name(self) -> str: """ The name of this plugin. """ @property def raw_state(self) -> bytes: """ A :py:class:`bytes` object representing the plugin's internal state. For the Audio Unit format, this is usually a binary property list that can be decoded or encoded with the built-in :py:mod:`plistlib` package. .. warning:: This property can be set to change the plugin's internal state, but providing invalid data may cause the plugin to crash, taking the entire Python process down with it. """ @raw_state.setter def raw_state(self, arg1: bytes) -> None: """ A :py:class:`bytes` object representing the plugin's internal state. For the Audio Unit format, this is usually a binary property list that can be decoded or encoded with the built-in :py:mod:`plistlib` package. .. warning:: This property can be set to change the plugin's internal state, but providing invalid data may cause the plugin to crash, taking the entire Python process down with it. """ @property def reported_latency_samples(self) -> int: """ The number of samples of latency (delay) that this plugin reports to introduce into the audio signal due to internal buffering and processing. Pedalboard automatically compensates for this latency during processing, so this property is present for informational purposes. Note that not all plugins correctly report the latency that they introduce, so this value may be inaccurate (especially if the plugin reports 0). *Introduced in v0.9.12.* """ @property def version(self) -> str: """ The version string for this plugin, as reported by the plugin itself. *Introduced in v0.9.4.* """ pass class PluginContainer(Plugin): """ A generic audio processing plugin that contains zero or more other plugins. Not intended for direct use. """ def __contains__(self, plugin: Plugin) -> bool: ... def __delitem__(self, index: int) -> None: """ Delete a plugin by its index. Index may be negative. If the index is out of range, an IndexError will be thrown. """ def __getitem__(self, index: int) -> Plugin: """ Get a plugin by its index. Index may be negative. If the index is out of range, an IndexError will be thrown. """ def __init__(self, plugins: typing.List[Plugin]) -> None: ... def __iter__(self) -> typing.Iterator[Plugin]: ... def __len__(self) -> int: """ Get the number of plugins in this container. """ def __setitem__(self, index: int, plugin: Plugin) -> None: """ Replace a plugin at the specified index. Index may be negative. If the index is out of range, an IndexError will be thrown. """ def append(self, plugin: Plugin) -> None: """ Append a plugin to the end of this container. """ def insert(self, index: int, plugin: Plugin) -> None: """ Insert a plugin at the specified index. """ def remove(self, plugin: Plugin) -> None: """ Remove a plugin by its value. """ pass class Resample(Plugin): """ A plugin that downsamples the input audio to the given sample rate, then upsamples it back to the original sample rate. Various quality settings will produce audible distortion and aliasing effects. """ class Quality(Enum): """ Indicates which specific resampling algorithm to use. Resampling algorithms each provide a different tradeoff between speed and quality. Pedalboard provides two different types of resampling algorithms: - `Aliasing` algorithms, which cause high frequencies to appear as lower frequencies. - Non-aliasing algorithms, which filter out high frequencies when downsampling and avoid introducing extra high-frequency content when upsampling. (These algorithms were introduced in Pedalboard v0.9.15.) Aliasing algorithms include :py:class:`ZeroOrderHold`, :py:class:`Linear`, :py:class:`CatmullRom`, :py:class:`Lagrange`, and :py:class:`WindowedSinc`. Non-aliasing algorithms include :py:class:`WindowedSinc256`, :py:class:`WindowedSinc128`, :py:class:`WindowedSinc64`, :py:class:`WindowedSinc32`, :py:class:`WindowedSinc16`, and :py:class:`WindowedSinc8`. Choosing an algorithm to use depends on the signal being resampled, the relationship between the source and target sample rates, and the application of the resampled signal. - If downsampling by an integer factor (i.e.: from 44.1kHz to 22050Hz, or 48kHz to 24kHz), and if the source signal has no high-frequency content above half of the target sample rate the :py:class:`ZeroOrderHold` algorithm will be the fastest by far and will produce no artifacts. - In all other cases, any of the numbered :py:class:`WindowedSinc` algorithms (i.e.: :py:class:`WindowedSinc256`, :py:class:`WindowedSinc64`) will produce a clean signal with no artifacts. Higher numbers will produce a cleaner signal with less roll-off of high frequency content near the Nyquist frequency of the new sample rate. However, depending on your application, the artifacts introduced by each resampling method may be acceptable. Test each method to determine which is the best tradeoff between speed and accuracy for your use case. To provide a good balance between speed and accuracy, :py:class:`WindowedSinc32` is the default from Pedalboard v0.9.15 onwards. (Previously, :py:class:`WindowedSinc` was the default.) """ ZeroOrderHold = 0 # fmt: skip """ The lowest quality and fastest resampling method, with lots of audible artifacts. Zero-order hold resampling chooses the next value to use based on the last value, without any interpolation. Think of it like nearest-neighbor resampling. .. warning:: This algorithm produces aliasing artifacts. """ Linear = 1 # fmt: skip """ A resampling method slightly less noisy than the simplest method. Linear resampling takes the average of the two nearest values to the desired sample, which is reasonably good for downsampling. .. warning:: This algorithm produces aliasing artifacts. """ CatmullRom = 2 # fmt: skip """ A moderately good-sounding resampling method which is fast to run. Slightly slower than Linear resampling, but slightly higher quality. .. warning:: This algorithm produces aliasing artifacts. """ Lagrange = 3 # fmt: skip """ A moderately good-sounding resampling method which is slow to run. Slower than CatmullRom resampling, but slightly higher quality. .. warning:: This algorithm produces aliasing artifacts. """ WindowedSinc = 4 # fmt: skip """ A very high quality (and the slowest) resampling method, with no audible artifacts when upsampling. This resampler applies a windowed sinc filter design with 100 zero-crossings of the sinc function to approximate an ideal brick-wall low-pass filter. .. warning:: This algorithm produces aliasing artifacts when downsampling, but not when upsampling. .. note:: This method was the default in versions of Pedalboard prior to v0.9.15. """ WindowedSinc256 = 5 # fmt: skip """ The highest possible quality resampling algorithm, with no audible artifacts when upsampling or downsampling. This resampler applies a windowed sinc filter with 256 zero-crossings to approximate an ideal brick-wall low-pass filter. This filter does not produce aliasing artifacts when upsampling or downsampling. Compare this in speed and quality to Resampy's ``kaiser_best`` method. """ WindowedSinc128 = 6 # fmt: skip """ A very high quality resampling algorithm, with no audible artifacts when upsampling or downsampling. This resampler applies a windowed sinc filter with 128 zero-crossings to approximate an ideal brick-wall low-pass filter. This filter does not produce aliasing artifacts when upsampling or downsampling. This method is roughly as fast as Resampy's ``kaiser_fast`` method, while producing results roughly equal in quality to Resampy's ``kaiser_best`` method. """ WindowedSinc64 = 7 # fmt: skip """ A very high quality resampling algorithm, with few audible artifacts when upsampling or downsampling. This resampler applies a windowed sinc filter with 64 zero-crossings to approximate an ideal brick-wall low-pass filter. This filter does not produce aliasing artifacts when upsampling or downsampling. This method is (on average) faster than Resampy's ``kaiser_fast`` method, and roughly equal in quality. """ WindowedSinc32 = 8 # fmt: skip """ A reasonably high quality resampling algorithm, with few audible artifacts when upsampling or downsampling. This resampler applies a windowed sinc filter with 32 zero-crossings to approximate an ideal brick-wall low-pass filter. This filter produces very few aliasing artifacts when upsampling or downsampling. This method is always faster than Resampy's ``kaiser_fast`` method, while being reasonable in quality. .. note:: This method is the default in Pedalboard v0.9.15 and later. """ WindowedSinc16 = 9 # fmt: skip """ A medium quality resampling algorithm, with few audible artifacts when upsampling or downsampling. This resampler applies a windowed sinc filter with 16 zero-crossings to approximate an ideal brick-wall low-pass filter. This filter produces some aliasing artifacts when upsampling or downsampling. This method is faster than Resampy's ``kaiser_fast`` method, while being acceptable in quality. """ WindowedSinc8 = 10 # fmt: skip """ A low quality resampling algorithm, with few audible artifacts when upsampling or downsampling. This resampler applies a windowed sinc filter with 16 zero-crossings to approximate an ideal brick-wall low-pass filter. This filter produces noticeable aliasing artifacts when upsampling or downsampling. This method can be more than 10x faster than Resampy's ``kaiser_fast`` method, and is useful for applications that are tolerant of some resampling artifacts. """ def __init__( self, target_sample_rate: float = 8000.0, quality: Quality = Quality.WindowedSinc32 ) -> None: ... def __repr__(self) -> str: ... @property def quality(self) -> Resample.Quality: """ The resampling algorithm used to resample the audio. """ @quality.setter def quality(self, arg1: Resample.Quality) -> None: """ The resampling algorithm used to resample the audio. """ @property def target_sample_rate(self) -> float: """ The sample rate to resample the input audio to. This value may be a floating-point number, in which case a floating-point sampling rate will be used. Note that the output of this plugin will still be at the original sample rate; this is merely the sample rate used for quality reduction. """ @target_sample_rate.setter def target_sample_rate(self, arg1: float) -> None: """ The sample rate to resample the input audio to. This value may be a floating-point number, in which case a floating-point sampling rate will be used. Note that the output of this plugin will still be at the original sample rate; this is merely the sample rate used for quality reduction. """ CatmullRom: pedalboard_native.Resample.Quality # value = <Quality.CatmullRom: 2> Lagrange: pedalboard_native.Resample.Quality # value = <Quality.Lagrange: 3> Linear: pedalboard_native.Resample.Quality # value = <Quality.Linear: 1> WindowedSinc: pedalboard_native.Resample.Quality # value = <Quality.WindowedSinc: 4> WindowedSinc128: pedalboard_native.Resample.Quality # value = <Quality.WindowedSinc128: 6> WindowedSinc16: pedalboard_native.Resample.Quality # value = <Quality.WindowedSinc16: 9> WindowedSinc256: pedalboard_native.Resample.Quality # value = <Quality.WindowedSinc256: 5> WindowedSinc32: pedalboard_native.Resample.Quality # value = <Quality.WindowedSinc32: 8> WindowedSinc64: pedalboard_native.Resample.Quality # value = <Quality.WindowedSinc64: 7> WindowedSinc8: pedalboard_native.Resample.Quality # value = <Quality.WindowedSinc8: 10> ZeroOrderHold: pedalboard_native.Resample.Quality # value = <Quality.ZeroOrderHold: 0> pass class Reverb(Plugin): """ A simple reverb effect. Uses a simple stereo reverb algorithm, based on the technique and tunings used in `FreeVerb <https://ccrma.stanford.edu/~jos/pasp/Freeverb.html>_`. """ def __init__( self, room_size: float = 0.5, damping: float = 0.5, wet_level: float = 0.33, dry_level: float = 0.4, width: float = 1.0, freeze_mode: float = 0.0, ) -> None: ... def __repr__(self) -> str: ... @property def damping(self) -> float: """ """ @damping.setter def damping(self, arg1: float) -> None: pass @property def dry_level(self) -> float: """ """ @dry_level.setter def dry_level(self, arg1: float) -> None: pass @property def freeze_mode(self) -> float: """ """ @freeze_mode.setter def freeze_mode(self, arg1: float) -> None: pass @property def room_size(self) -> float: """ """ @room_size.setter def room_size(self, arg1: float) -> None: pass @property def wet_level(self) -> float: """ """ @wet_level.setter def wet_level(self, arg1: float) -> None: pass @property def width(self) -> float: """ """ @width.setter def width(self, arg1: float) -> None: pass pass class VST3Plugin(ExternalPlugin): """ A wrapper around third-party, audio effect or instrument plugins in `Steinberg GmbH's VST3® <https://en.wikipedia.org/wiki/Virtual_Studio_Technology>`_ format. VST3® plugins are supported on macOS, Windows, and Linux. However, VST3® plugin files are not cross-compatible with different operating systems; a platform-specific build of each plugin is required to load that plugin on a given platform. (For example: a Windows VST3 plugin bundle will not load on Linux or macOS.) .. warning:: Some VST3® plugins may throw errors, hang, generate incorrect output, or outright crash if called from background threads. If you find that a VST3® plugin is not working as expected, try calling it from the main thread instead and `open a GitHub Issue to track the incompatibility <https://github.com/spotify/pedalboard/issues/new>`_. *Support for instrument plugins introduced in v0.7.4.* *Support for running VST3® plugins on background threads introduced in v0.8.8.* """ @typing.overload def __call__( self, input_array: numpy.ndarray, sample_rate: float, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: """ Run an audio or MIDI buffer through this plugin, returning audio. Alias for :py:meth:`process`. Run an audio or MIDI buffer through this plugin, returning audio. Alias for :py:meth:`process`. """ @typing.overload def __call__( self, midi_messages: object, duration: float, sample_rate: float, num_channels: int = 2, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: ... def __init__( self, path_to_plugin_file: str, parameter_values: object = None, plugin_name: typing.Optional[str] = None, initialization_timeout: float = 10.0, ) -> None: ... def __repr__(self) -> str: ... def _get_parameter(self, arg0: str) -> _AudioProcessorParameter: ... @staticmethod def get_plugin_names_for_file(arg0: str) -> typing.List[str]: """ Return a list of plugin names contained within a given VST3 plugin (i.e.: a ".vst3"). If the provided file cannot be scanned, an ImportError will be raised. """ def load_preset(self, preset_file_path: str) -> None: """ Load a VST3 preset file in .vstpreset format. """ @typing.overload def process( self, input_array: numpy.ndarray, sample_rate: float, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: """ Pass a buffer of audio (as a 32- or 64-bit NumPy array) *or* a list of MIDI messages to this plugin, returning audio. (If calling this multiple times with multiple effect plugins, consider creating a :class:`pedalboard.Pedalboard` object instead.) When provided audio as input, the returned array may contain up to (but not more than) the same number of samples as were provided. If fewer samples were returned than expected, the plugin has likely buffered audio inside itself. To receive the remaining audio, pass another audio buffer into ``process`` with ``reset`` set to ``True``. If the provided buffer uses a 64-bit datatype, it will be converted to 32-bit for processing. If provided MIDI messages as input, the provided ``midi_messages`` must be a Python ``List`` containing one of the following types: - Objects with a ``bytes()`` method and ``time`` property (such as :doc:`mido:messages` from :doc:`mido:index`, not included with Pedalboard) - Tuples that look like: ``(midi_bytes: bytes, timestamp_in_seconds: float)`` - Tuples that look like: ``(midi_bytes: List[int], timestamp_in_seconds: float)`` The returned array will contain ``duration`` seconds worth of audio at the provided ``sample_rate``. Each MIDI message will be sent to the plugin at its timestamp, where a timestamp of ``0`` indicates the start of the buffer, and a timestamp equal to ``duration`` indicates the end of the buffer. (Any MIDI messages whose timestamps are greater than ``duration`` will be ignored.) The provided ``buffer_size`` argument will be used to control the size of each chunk of audio returned by the plugin at once. Higher buffer sizes may speed up processing, but may cause increased memory usage. The ``reset`` flag determines if this plugin should be reset before processing begins, clearing any state from previous calls to ``process``. If calling ``process`` multiple times while processing the same audio or MIDI stream, set ``reset`` to ``False``. .. note:: The :py:meth:`process` method can also be used via :py:meth:`__call__`; i.e.: just calling this object like a function (``my_plugin(...)``) will automatically invoke :py:meth:`process` with the same arguments. Examples -------- Running audio through an external effect plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_effect with AudioFile("input-audio.wav") as f: output_audio = plugin(f.read(), f.samplerate) Rendering MIDI via an external instrument plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile from mido import Message # not part of Pedalboard, but convenient! plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_instrument sample_rate = 44100 num_channels = 2 with AudioFile("output-audio.wav", "w", sample_rate, num_channels) as f: f.write(plugin( [Message("note_on", note=60), Message("note_off", note=60, time=4)], sample_rate=sample_rate, duration=5, num_channels=num_channels )) *Support for instrument plugins introduced in v0.7.4.* Pass a buffer of audio (as a 32- or 64-bit NumPy array) *or* a list of MIDI messages to this plugin, returning audio. (If calling this multiple times with multiple effect plugins, consider creating a :class:`pedalboard.Pedalboard` object instead.) When provided audio as input, the returned array may contain up to (but not more than) the same number of samples as were provided. If fewer samples were returned than expected, the plugin has likely buffered audio inside itself. To receive the remaining audio, pass another audio buffer into ``process`` with ``reset`` set to ``True``. If the provided buffer uses a 64-bit datatype, it will be converted to 32-bit for processing. If provided MIDI messages as input, the provided ``midi_messages`` must be a Python ``List`` containing one of the following types: - Objects with a ``bytes()`` method and ``time`` property (such as :doc:`mido:messages` from :doc:`mido:index`, not included with Pedalboard) - Tuples that look like: ``(midi_bytes: bytes, timestamp_in_seconds: float)`` - Tuples that look like: ``(midi_bytes: List[int], timestamp_in_seconds: float)`` The returned array will contain ``duration`` seconds worth of audio at the provided ``sample_rate``. Each MIDI message will be sent to the plugin at its timestamp, where a timestamp of ``0`` indicates the start of the buffer, and a timestamp equal to ``duration`` indicates the end of the buffer. (Any MIDI messages whose timestamps are greater than ``duration`` will be ignored.) The provided ``buffer_size`` argument will be used to control the size of each chunk of audio returned by the plugin at once. Higher buffer sizes may speed up processing, but may cause increased memory usage. The ``reset`` flag determines if this plugin should be reset before processing begins, clearing any state from previous calls to ``process``. If calling ``process`` multiple times while processing the same audio or MIDI stream, set ``reset`` to ``False``. .. note:: The :py:meth:`process` method can also be used via :py:meth:`__call__`; i.e.: just calling this object like a function (``my_plugin(...)``) will automatically invoke :py:meth:`process` with the same arguments. Examples -------- Running audio through an external effect plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_effect with AudioFile("input-audio.wav") as f: output_audio = plugin(f.read(), f.samplerate) Rendering MIDI via an external instrument plugin:: from pedalboard import load_plugin from pedalboard.io import AudioFile from mido import Message # not part of Pedalboard, but convenient! plugin = load_plugin("../path-to-my-plugin-file") assert plugin.is_instrument sample_rate = 44100 num_channels = 2 with AudioFile("output-audio.wav", "w", sample_rate, num_channels) as f: f.write(plugin( [Message("note_on", note=60), Message("note_off", note=60, time=4)], sample_rate=sample_rate, duration=5, num_channels=num_channels )) *Support for instrument plugins introduced in v0.7.4.* """ @typing.overload def process( self, midi_messages: object, duration: float, sample_rate: float, num_channels: int = 2, buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: ... def show_editor(self, close_event: typing.Optional[threading.Event] = None) -> None: """ Show the UI of this plugin as a native window. This method may only be called on the main thread, and will block the main thread until any of the following things happens: - the window is closed by clicking the close button - the window is closed by pressing the appropriate (OS-specific) keyboard shortcut - a KeyboardInterrupt (Ctrl-C) is sent to the program - the :py:meth:`threading.Event.set` method is called (by another thread) on a provided :py:class:`threading.Event` object An example of how to programmatically close an editor window:: import pedalboard from threading import Event, Thread plugin = pedalboard.load_plugin("../path-to-my-plugin-file") close_window_event = Event() def other_thread(): # do something to determine when to close the window if should_close_window: close_window_event.set() thread = Thread(target=other_thread) thread.start() # This will block until the other thread calls .set(): plugin.show_editor(close_window_event) """ @property def _parameters(self) -> typing.List[_AudioProcessorParameter]: """ """ @property def _reload_type(self) -> ExternalPluginReloadType: """ The behavior that this plugin exhibits when .reset() is called. This is an internal attribute which gets set on plugin instantiation and should only be accessed for debugging and testing. """ @_reload_type.setter def _reload_type(self, arg0: ExternalPluginReloadType) -> None: """ The behavior that this plugin exhibits when .reset() is called. This is an internal attribute which gets set on plugin instantiation and should only be accessed for debugging and testing. """ @property def category(self) -> str: """ A category that this plugin falls into, such as "Dynamics", "Reverbs", etc. *Introduced in v0.9.4.* """ @property def descriptive_name(self) -> str: """ A more descriptive name for this plugin. This may be the same as the 'name' field, but some plugins may provide an alternative name. *Introduced in v0.9.4.* """ @property def has_shared_container(self) -> bool: """ True iff this plugin is part of a multi-plugin container. *Introduced in v0.9.4.* """ @property def identifier(self) -> str: """ A string that can be saved and used to uniquely identify this plugin (and version) again. *Introduced in v0.9.4.* """ @property def is_instrument(self) -> bool: """ True iff this plugin identifies itself as an instrument (generator, synthesizer, etc) plugin. *Introduced in v0.9.4.* """ @property def manufacturer_name(self) -> str: """ The name of the manufacturer of this plugin, as reported by the plugin itself. *Introduced in v0.9.4.* """ @property def name(self) -> str: """ The name of this plugin. """ @property def preset_data(self) -> bytes: """ Get or set the current plugin state as bytes in .vstpreset format. .. warning:: This property can be set to change the plugin's internal state, but providing invalid data may cause the plugin to crash, taking the entire Python process down with it. """ @preset_data.setter def preset_data(self, arg1: bytes) -> None: """ Get or set the current plugin state as bytes in .vstpreset format. .. warning:: This property can be set to change the plugin's internal state, but providing invalid data may cause the plugin to crash, taking the entire Python process down with it. """ @property def raw_state(self) -> bytes: """ A :py:class:`bytes` object representing the plugin's internal state. For the VST3 format, this is usually an XML-encoded string prefixed with an 8-byte header and suffixed with a single null byte. .. warning:: This property can be set to change the plugin's internal state, but providing invalid data may cause the plugin to crash, taking the entire Python process down with it. """ @raw_state.setter def raw_state(self, arg1: bytes) -> None: """ A :py:class:`bytes` object representing the plugin's internal state. For the VST3 format, this is usually an XML-encoded string prefixed with an 8-byte header and suffixed with a single null byte. .. warning:: This property can be set to change the plugin's internal state, but providing invalid data may cause the plugin to crash, taking the entire Python process down with it. """ @property def reported_latency_samples(self) -> int: """ The number of samples of latency (delay) that this plugin reports to introduce into the audio signal due to internal buffering and processing. Pedalboard automatically compensates for this latency during processing, so this property is present for informational purposes. Note that not all plugins correctly report the latency that they introduce, so this value may be inaccurate (especially if the plugin reports 0). *Introduced in v0.9.12.* """ @property def version(self) -> str: """ The version string for this plugin, as reported by the plugin itself. *Introduced in v0.9.4.* """ pass class _AudioProcessorParameter: """ An abstract base class for parameter objects that can be added to an AudioProcessor. """ def __repr__(self) -> str: ... def get_name(self, maximum_string_length: int) -> str: """ Returns the name to display for this parameter, which is made to fit within the given string length """ def get_raw_value_for_text(self, string_value: str) -> float: """ Returns the raw value of the supplied text. Plugins may handle errors however they see fit, but will likely not raise exceptions. """ def get_text_for_raw_value(self, raw_value: float, maximum_string_length: int = 512) -> str: """ Returns a textual version of the supplied normalised parameter value. """ @property def default_raw_value(self) -> float: """ The default internal value of this parameter. Convention is that this parameter should be between 0 and 1.0. This may or may not correspond with the value shown to the user. """ @property def index(self) -> int: """ The index of this parameter in its plugin's parameter list. """ @property def is_automatable(self) -> bool: """ Returns true if this parameter can be automated (i.e.: scheduled to change over time, in real-time, in a DAW). """ @property def is_boolean(self) -> bool: """ Returns whether the parameter represents a boolean switch, typically with "On" and "Off" states. """ @property def is_discrete(self) -> bool: """ Returns whether the parameter uses discrete values, based on the result of getNumSteps, or allows the host to select values continuously. """ @property def is_meta_parameter(self) -> bool: """ A meta-parameter is a parameter that changes other parameters. """ @property def is_orientation_inverted(self) -> bool: """ If true, this parameter operates in the reverse direction. (Not all plugin formats will actually use this information). """ @property def label(self) -> str: """ Some parameters may be able to return a label string for their units. For example "Hz" or "%". """ @property def name(self) -> str: """ Returns the name to display for this parameter at its longest. """ @property def num_steps(self) -> int: """ Returns the number of steps that this parameter's range should be quantised into. See also: is_discrete, is_boolean. """ @property def raw_value(self) -> float: """ The internal value of this parameter. Convention is that this parameter should be between 0 and 1.0. This may or may not correspond with the value shown to the user. """ @raw_value.setter def raw_value(self, arg1: float) -> None: """ The internal value of this parameter. Convention is that this parameter should be between 0 and 1.0. This may or may not correspond with the value shown to the user. """ @property def string_value(self) -> str: """ Returns the current value of the parameter as a string. """ pass def process( input_array: numpy.ndarray, sample_rate: float, plugins: typing.List[Plugin], buffer_size: int = 8192, reset: bool = True, ) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float32]]: """ Run a 32-bit or 64-bit floating point audio buffer through a list of Pedalboard plugins. If the provided buffer uses a 64-bit datatype, it will be converted to 32-bit for processing. The provided ``buffer_size`` argument will be used to control the size of each chunk of audio provided into the plugins. Higher buffer sizes may speed up processing at the expense of memory usage. The ``reset`` flag determines if all of the plugins should be reset before processing begins, clearing any state from previous calls to ``process``. If calling ``process`` multiple times while processing the same audio file or buffer, set ``reset`` to ``False``. :meta private: """ class GSMFullRateCompressor(Plugin): """ An audio degradation/compression plugin that applies the GSM "Full Rate" compression algorithm to emulate the sound of a 2G cellular phone connection. This plugin internally resamples the input audio to a fixed sample rate of 8kHz (required by the GSM Full Rate codec), although the quality of the resampling algorithm can be specified. """ def __init__(self, quality: Resample.Quality = Resample.Quality.WindowedSinc8) -> None: ... def __repr__(self) -> str: ... @property def quality(self) -> Resample.Quality: """ """ @quality.setter def quality(self, arg1: Resample.Quality) -> None: pass pass