thestk / rtaudio

A set of C++ classes that provide a common API for realtime audio input/output across Linux (native ALSA, JACK, PulseAudio and OSS), Macintosh OS X (CoreAudio and JACK), and Windows (DirectSound, ASIO, and WASAPI) operating systems.
Other
1.49k stars 318 forks source link

How to make playback follow active output device? #338

Closed nyanpasu64 closed 2 years ago

nyanpasu64 commented 2 years ago

IIRC currently when you open a WASAPI device in an RtAudio app (BambooTracker), and change Windows's default device (eg. by plugging in a new audio output or headphones), RtAudio (and BambooTracker) continues playing to the old device. Ideally, RtAudio on WASAPI would act like web browsers and music players: by default, it would always play to the current default device when you plug or unplug devices or change the default, unless you explicitly pass a device ID into openStream rather than "follow default device". When unplugging an explicitly chosen device, I'd either stop playback with an error, or fallback to the default device (and if no devices are left, you need to error anyway).

I'm not sure if RtAudio supports that now (one reason I'm no longer confident I want to use it in future projects). I didn't look in depth if it's possible, but AFAIK currently StreamParameters::deviceId has no "follow default device as it changes" mode, and all the code I've seen sets param.deviceId = getDefaultOutputDevice() or similar. I don't know if I can implement this in the application or not.

Possibly related: #194.

nyanpasu64 commented 2 years ago

Neither does locking and unlocking a mutex on every callback (ALSA), or adding an entire period of excess playback latency (ALSA relying on snd_pcm_writei blocking as backpressure), or double latency when playing through pipewire (ALSA backend talking to the pipewire-alsa library which buffers audio, talking to the pipewire daemon which buffers audio again). But RtAudio does all of them. Automatic device switching has no penalty in the happy path (default device not changed) and measurably improves user experience when the user asks RtAudio to use the default device, then unplugs headphones and wonders why the audio stops playing. To me, being useful for audio apps supersedes concerns over whether it makes RtAudio unsuited for real-time playback (which it already is, IMO).

On the topic of implementation, I've heard that WASAPI (unlike past Windows APIs) requires the app manually track the default device. That would complicate implementation. I'll look into what https://github.com/thestk/rtaudio/tree/newdeviceselection is doing at some point.

garyscavone commented 2 years ago

I am closing this. The supported APIs generally do not provide a mechanism to inform RtAudio when the default device is changed. And even if they did, I don't feel comfortable assuming that the user wants audio to be automatically rerouted to another device. Finally, it would require a lot of extra code to attempt to get it to work, which goes against the basic idea of what RtAudio is meant for.