The basic idea is to support multiple/different output devices, e.g. send to AirPlay speakers.
See Output Stack on the wiki.
I actually planned to figure out and contribute this myself but then was too busy for it, so I'll just share my thoughts with you.
The idea is that each audio output implements a common interface โ let's call it AudioOutput
.
Every AudioOutput
is initialized with an audio source and has a few very basic functions to enable
, disable
, setVolume
, โฆ
Volumio would output sound to a raw PCM stream, which is then passed as the audio source to all the outputs.
An OutputController
enables or disables outputs and also calls setVolume
for each of them.
Some output examples:
- take the PCM stream and send it to local speakers via DAC
- use node_airtunes to send the audio to AirPlay speakers.
- convert to mp3 stream and make it accessible via HTTP
AirPlay is a great example because it shows two issues that I don't yet know how to solve:
Synchronizing
Especially remote speakers will have some delay before actually playing the audio, and you don't want your AirPlay speakers 5 meters away to hang 3 seconds behind the directly connected speakers.
AFAIK AirPlay buffers audio and plays it back delayed, while pause/resume is carried out as soon as it arrives at the AirPlay server. However, that issue could be solved by not using AirPlay's pause/resume feature and just silence the PCM stream when Volumio is paused. This will have the effect that music still plays for a few seconds after you hit pause, though.
Maybe enable
could have a callback that includes the delay and OutputController
can delay the source individually for each output to counter the latency?
Custom Options
Since you can select multiple AirPlay speakers, we need a way to pass this option to the end user.
Same goes for e.g. port options for the http server mentioned above.
Perhaps AudioOutput
could have settings
and a function that's called when they change?
I hope this made some sense ๐ฐ