Control: reassign -1 libportaudio2 19.7.0-1
Control: retitle -1 libportaudio2: should discard error messages from alsa-lib
by setting a dummy error handler
Control: affects -1 xournalpp
On 2025-12-29 15:00:52 +0000, Barak A. Pearlmutter wrote:
> For further clarification I discussed this issue with claude.ai and here's
> what seems to be going on. It's not related to libsndfile, it's actually
> PortAudio's fault.
I agree that this is PortAudio's fault (though I think that
alsa-lib's default for errors is a poor choice). See below
what should be done to fix the issue in PortAudio (not tested).
So, reassigning the bug to libportaudio2.
[...]
> Xournalpp links against PortAudio, which enumerates all ALSA PCM devices at
> initialization via snd_device_name_hint() or similar discovery APIs. ALSA's
> default configuration files (e.g., /usr/share/alsa/alsa.conf) define
> references to numerous hardware PCM devices (surround configurations, HDMI,
> modem, phoneline, etc.) regardless of whether the hardware exists. When
> PortAudio probes these devices, ALSA attempts to open each one, generating
> error messages to stderr for every non-existent device.
The error messages come from alsa-lib. According to src/error.c
in alsa-lib:
/**
* \brief The default log handler function.
[...]
* If a local error function has been installed for the current thread by
* \ref snd_lib_log_set_local, it is called. Otherwise, prints the error
* message including location to \c stderr.
*/
static void snd_lib_vlog_default(int prio, int interface, const char *file, int
line, const char *function, int errcode, const char *fmt, va_list arg)
[...]
I think that sending messages to stderr by default is a poor choice.
So the software using alsa-lib (here, the PortAudio library) should
define either its own log handler function or its own error handler
function, since the default error handler function is what triggers
the log by calling snd_lib_vlog.
/**
* \brief Sets the error handler.
[...]
* This function sets a new error handler, or (if \c handler is \c NULL)
* the default one which prints the error messages to \c stderr.
*/
int snd_lib_error_set_handler(snd_lib_error_handler_t handler)
{
snd_lib_error = handler == NULL ? snd_lib_error_default : handler;
return 0;
}
In the PortAudio source, I can see in src/hostapi/alsa/pa_linux_alsa.c:
PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
hostApiIndex )
{
[...]
/*ENSURE_( snd_lib_error_set_handler(AlsaErrorHandler),
paUnanticipatedHostError );*/
[...]
}
and
static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
{
[...]
/*snd_lib_error_set_handler(NULL);*/
[...]
}
So it seems that the intent was to set an error handler, but this has
been commented out, together with
/** Uncommented because AlsaErrorHandler is unused for anything good yet. If
AlsaErrorHandler is
to be used, do not forget to register this callback in PaAlsa_Initialize,
and unregister in Terminate.
*/
/*static void AlsaErrorHandler(const char *file, int line, const char
*function, int err, const char *fmt, ...)
{
}*/
This explanation is actually wrong: AlsaErrorHandler should be
used to discard the error messages (sent to stderr by default)
since PortAudio does not seem to want to handle them.
--
Vincent Lefèvre <[email protected]> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Pascaline project (LIP, ENS-Lyon)