projectM-visualizer / frontend-sdl2

Standalone application based on SDL2 that turns your desktop audio into awesome visuals. Available on most platforms supported by both libprojectM and libSDL2.
GNU General Public License v3.0
57 stars 32 forks source link

WASAPI implementation #37

Closed kblaschke closed 2 years ago

kblaschke commented 2 years ago

Implemented the WASAPI-based audio capture functionality required to support loopback capturing, which SDL2 doesn't provide. The previous SDL frontend only supported capture from the default device and failed when it changed, e.g. if a headset was unplugged. The new implementation supports manual device selection (initial by the user using the command line or config parameters) and also in the app using ctrl-i. In addition to that, hotplug events are now processed and the capturing is adapted accordingly, e.g. restarting the current device or switching to the next/default on if unplugged.

A few other fixes regarding formatting and logging are also included in separate commits.

As WASAPI is COM-based, please review the code for any possible resource leaks (e.g. not properly calling Release() or CoTaskMemFree() in some branches) I might have overlooked. I didn't include atlbase.h to use CComPtr<> on purpose, as this would require the optional ATL/MFC components to be installed in Visual Studio, which not everyone might have done.

kblaschke commented 2 years ago

Did you have a chance to see if PortAudio can do this but in a cross-platform fashion?

From what I can tell, PortAudio supports loopback capturing with WASAPI. But it doesn't support PulseAudio on Linux, only ALSA, which means the "monitor" devices, which are the equivalent to loopback mode with WASAPI, won't be accessible. ALSA itself doesn't provide a loopback mode or device by default, only if the user manually creates one using a config file, which isn't exactly easy. So we could use PortAudio for Windows and macOS, but then would require a custom PulseAudio implementation (or using the SDL2 audio driver) on Linux, which wouldn't provide much of an advantage IMO.

There's light on the horizon though, as Portaudio has an open PR for a dedicated PulseAudio backend. If that's merged, it might be worth a try to switch to PortAudio instead (and doing the same with the Qt frontend, possibly even sharing the code). https://github.com/PortAudio/portaudio/pull/336