Expand description
§rundsp makes fundsp even more fun
The fundsp crate is a fantastic way to do audio processing in Rust, but actually recording
and playing live audio with it requires a certain amount of boilerplate to plug it into an audio
I/O backend like cpal.
I want to live in a world where playing a sound could be as simple as this:
use rundsp::fundsp::hacker::*;
rundsp::output(sine_hz(110.0)).run();§Input and output
And I want it to be just as easy to scale up to simultaneous stereo input and output:
// Let's make it sound like we're in a giant cave
let reverb = reverb2_stereo(20.0, 3.0, 1.0, 0.2, highshelf_hz(1000.0, 1.0, db_amp(-1.0)));
let chorus = chorus(0, 0.0, 0.03, 0.2) | chorus(1, 0.0, 0.03, 0.2);
let effects = chorus >> ((0.8 * reverb) & (0.2 * multipass()));
// Feed the input directly into the output effects
rundsp::mic().output(effects).run();To contextualize part of what rundsp is doing on your behalf, contrast this with the
equivalent
example from the
fundsp documentation, which requires 150 lines of boilerplate code, using cpal
directly to play these 3 lines of effects.
I built rundsp so that I could live in that world today. Maybe you can too!
§What does it do?
-
Stereo, mono, and nullary inputs and outputs: The
rundspinterface accepts input audio nodes with 0, 1, or 2 input channels and output audio nodes with 0, 1, or 2 output channels, automatically up- or down-mixing the available channels in the selected audio configuration, and checking at compile-time that the input and output nodes (if both are present) can be plugged into one another with no dangling channels. -
Automatic configuration with good defaults: It then configures audio backend streams using
cpal(see configuration for how to customize this) for the input and output nodes, plugging the output channels of the input into the input channels of the output to form one cohesive pipeline from input to output. If you choose to use only one half of the pipeline, the other half will never be constructed. -
Error recovery and state-preserving manual restarts: In the event of an error while constructing or running an audio stream, a user-specified retry handler is invoked to determine whether to restart the stream. If you are building an audio application on a platform that can provide notifications of device hotplug events, you can also manually restart one or both ends of the audio pipeline upon notification. Either way, all restarts of either or both ends will re-run the device and configuration selection process and restart the processing pipeline without losing any state.
-
Asynchronous audio control interface: The
Runningaudio pipeline isSend(unlikecpal::Stream), which means it can be used in threads and multi-threaded asynchronous tasks. It exposes an asynchronous (Tokio required) interface to play, pause, restart, and stop the audio, either collectively or one end (input or output) at a time. TheRunningaudio can also be split into aRunning<Waited>andWaitingfuture, which allows commands to be sent to the audio streams concurrently while another task waits for it to complete (either after being stopped or when encountering an error that wasn’t retried).
§Configuration
With rundsp, the defaults are often exactly what you want (they’re lifted from cpal’s
configuration defaults), but when they’re not, you can configure precisely what you want about
your audio playback:
- the audio host of the ones supported by the platform,
- the device for each end of the I/O pipeline,
- the configuration for each end of the I/O pipeline (including parameters like sample format, sample rate, buffer size, etc.),
- whether to start paused and require pressing play manually,
- what to do when the stream encounters an error, including your own arbitrary asynchronous retry policy
§Who is this not for?
This library is intended for use in the Tokio asynchronous runtime, and has not been tested in any other asynchronous runtime. If you need to use another runtime, or if you need a blocking interface, this library does not provide either of those options.
Inputs and outputs are limited by design to stereo inputs and outputs, since beyond stereo sound, there is no general way to correctly map between an arbitrary number of node inputs/outputs and physical device channels. Rather than increasing the interface complexity of the library, we choose to support only mono and stereo devices.
Fundamentally, rundsp is an opinionated and abstracted wrapper around cpal, specialized
for use with fundsp audio nodes. It is not generalized over other audio I/O backends, and it
seems tricky (though not necessarily impossible!) to achieve this generalization while keeping
the simple configuration interface.
Re-exports§
Modules§
- error
- Errors that can happen when running audio.
- run
- Details for the configuration of an audio
Run, not usually required to be imported. - wait
- Futures related to waiting for audio streams to finish.
Structs§
- Retry
- After an error, should we restart the stream, and if so, when?
- Run
- The configuration for an audio pipeline.
- Running
- A running audio pipeline.
Enums§
Traits§
- From
Stereo - Channel counts of 0, 1, and 2 can be produced by down-mixing from stereo audio.
- Stereo
Input - An
AudioNodewhich can be used as a stereo input. - Stereo
Output - An
AudioNodewhich can be used as a stereo output. - ToStereo
- Channel counts of 0, 1, and 2 can be consumed by up-mixing to stereo audio.
Functions§
- config
- Create a new
Runusing the given closure to select an audioSupportedStreamConfig. - device
- Create a new
Runusing the given closure to select an audioDevice. - host
- Create a new
Runusing a given audioHost. - input
- Create a new
Runusing the given audio node as the input end. - mic
- Create a new
Runthat feeds the microphone’s input directly to the output of the pipeline. - mono_
mic - Create a new
Runthat feeds the microphone’s input directly to the output of the pipeline, as mono audio. - mono_
speaker - Create a new
Runthat feeds the output of the pipeline directly to the speaker (or headphones), as mono audio. - on_
error - Create a new
Runwhich will use the given closure to determine how to retry in the event of an error while building or running a stream. SeeRetryingfor more information. - on_
input - Create a new
Runwhich will call the given closure every time an input buffer is received. - on_
output - Create a new
Runwhich will call the given closure every time an output buffer is produced. - output
- Create a new
Runusing the given audio node as the output end. - speaker
- Create a new
Runthat feeds the output of the pipeline directly to the speaker (or headphones). - start_
paused - Create a new
Runwhich will start paused, so that it has to be manually played before audio will happen. - stereo_
mic - Create a new
Runthat feeds the microphone’s input directly to the output of the pipeline, as stereo audio. - stereo_
speaker - Create a new
Runthat feeds the output of the pipeline directly to the speaker (or headphones), as stereo audio.