A controller for CamillaDSP that automatically changes the configuration when the audio source's sample rate or format changes. It works by listening for changes on an audio device and then applying a new configuration to CamillaDSP.
It can provide new configurations in two ways: by loading a specific config file for the new format, or by adapting a general-purpose config.
This version of the controller works with CamillaDSP v4.0 and later.
The following python packages are required:
pycamilladsppyyaml
- Linux (ALSA listener): The controller relies on
pyalsawhen monitoring ALSA devices. - macOS (CoreAudio listener): The controller uses
cffito compile a small helper module and requires the Xcode command line tools for that build step.
The controller gets the CamillaDSP configurations from config providers. One or more providers can be enabled at the same time. The controller will try them in order, and the first one that can provide a config for the new audio format will be used.
The "Specific" provider loads a completely new configuration file when the audio format changes.
It's enabled with the -s or --specific command line parameter.
This parameter takes a path to a configuration file,
which can contain placeholders for the audio format parameters.
The available placeholders are:
{samplerate}{sampleformat}{channels}
Given the path /path/to/configs/conf_{samplerate}_{channels}.yml.
When the audio device changes to a 44100 Hz, 2-channel stream, the controller
will look for a file named /path/to/configs/conf_44100_2.yml.
The "Adapt" provider modifies a single base configuration file
to match the new audio format.
It's enabled with the -a or --adapt parameter,
which should point to the base configuration file.
This provider works in two ways depending on whether the configuration file uses a resampler:
- With a resampler: It sets the
capture_samplerateparameter to match the new sample rate. If the new sample rate is the same as the mainsamplerate, the resampler is disabled (if it's a synchronous resampler). - Without a resampler: It changes the main
samplerateparameter to the new sample rate.
It can also adapt the sample format if the capture device in the config
has a format parameter.
The controller can monitor changes on audio devices to automatically trigger a configuration change.
On Linux, the controller can monitor an ALSA device for sample rate and format changes. This is useful for capturing audio from a loopback device where other applications can play audio with varying sample rates.
The pyalsa package is required to use this feature.
Start the controller to monitor the ALSA device hw:Loopback,0:
python controller.py -p 1234 -s "/home/user/camilladsp/configs/config_{samplerate}.yml" -r 44100 -d hw:Loopback,0When a new stream starts playing to the loopback device, the controller will detect the sample rate and load the corresponding config.
Example configs:
config_44100.yml
devices:
samplerate: 44100
chunksize: 1024
enable_rate_adjust: true
capture:
type: Alsa
channels: 2
device: "hw:Loopback,0"
format: S32_LE
playback:
type: Alsa
channels: 2
device: "hw:MyDac"config_48000.yml
devices:
samplerate: 48000
chunksize: 1024
enable_rate_adjust: true
capture:
type: Alsa
channels: 2
device: "hw:Loopback,0"
format: S32_LE
playback:
type: Alsa
channels: 2
device: "hw:MyDac"On macOS, the controller can monitor the sample rate of a CoreAudio device.
This feature requires the cffi package. When first run, a small C module
will be compiled. This requires that the XCode command line tools are installed.
Start the controller to monitor the device "BlackHole 2ch":
python controller.py -p 1234 -s "/path/to/config_{samplerate}.yml" -a "/path/to/config_with_resampler.yml" -d "BlackHole 2ch"Here both the "Specific" and "Adapt" config providers are enabled.
The "Specific" one is tried first.
It will load a a config for the new sample rate if a file for it exists.
If not, the "Adapt" provider will be used,
which will modify the config_with_resampler.yml file.
Example configs:
config_44100.yml
devices:
samplerate: 44100
chunksize: 1024
capture:
type: CoreAudio
channels: 2
device: "BlackHole 2ch"
playback:
type: CoreAudio
channels: 2
device: "MyDAC"config_96000.yml
devices:
samplerate: 96000
chunksize: 1024
capture:
type: CoreAudio
channels: 2
device: "BlackHole 2ch"
playback:
type: CoreAudio
channels: 2
device: "MyDAC"config_with_resampler.yml
devices:
samplerate: 96000
capture_samplerate: 44100
chunksize: 1024
resampler:
type: Synchronous
capture:
type: CoreAudio
channels: 2
device: "BlackHole 2ch"
playback:
type: CoreAudio
channels: 2
device: "MyDAC"When a 44.1kHz stream is played, capture_samplerate is set to 44100.
When a 96kHz stream is played, capture_samplerate is set to 96000,
and the resampler is removed since it's not needed.
There is currently no device listener for Windows. This is because the available loopback devices do not provide any public API for reading the sample rate of the playback side.
A further limitation on Windows is that when the sample rate does change, the WASAPI audio API does not notify the client (in this case CamillaDSP) what the new sample rate is. It only reports that it changed. As a consequence of this, CamillaDSP is unable to provide the new sample rate in the "stop reason" message that it sends to the controller. This means the controller doesn't know the new rate, and is unable to provide a new config. This is a limitation in the underlying Windows API and not something that can be fixed in CamillaDSP.
The controller can still be used on Windows. However, currently the only benefit of doing so is that it can try to restart processing if it fails with a capture or playback error. If the sample rate changes, CamillaDSP will stop with an error and be unable to continue