jue 09 julio 2015
Por Javier Cantero
En Debian .
etiq.: pulseaudio xfce bugs
Al final del artículo Instalando PulseAudio en Debian
Jessie comentaba que me quedaban unos cuantos molestos
detalles por solucionar con PulseAudio:
Al pulsar el botón multimedia de "Mute" para hacer un unmute , el
sonido permanece en silencio porque sólo se ha reactivado el canal
"Master" del mixer de sonido, mientras que el resto de canales (en mi
caso "Headphone" y "Front") permanecen silenciados (que
correspondería con el bug #654633 del BTS).
Los botones multimedia de subir/bajar volumen sólo funcionan para la
tarjeta de sonido ALSA configurada. Específicamente no funcionan para
ningún otro sink de sonido PulseAudio aunque esté activo (como mi
headset bluetooth).
A estos dos bugs del pasado artículo tengo que añadir este otro:
Los sonidos que acompañan las ventanas emergentes de pausa de
Workrave producen dos molestas notificaciones de cambio de volumen
(tiene pinta de ser el mismo que el bug #754155 ).
Estos "flecos" tienen que ver con la integración de PulseAudio con
Xfce , o mejor dicho con la ausencia de integración de
PulseAudio con Xfce.
Xfce tiene 2 componentes relacionados con el sistema de sonido:
xfce4-mixer : la típica aplicación de control de volúmenes
—mixer— de los distintos dispositivos de entrada y salida de sonido.
Es una aplicación independiente aunque también puede funcionar como
un plugin de panel de Xfce.
xfce4-volumed : un demonio que permite controlar el volumen de una
tarjeta (la seleccionada en la configuración) mediante las teclas
multimedia de volumen. También se encarga de mostrar visualmente
los cambios de volumen mediante notificaciones.
La cuestión es que ambas aplicaciones interaccionan con el subsistema de
sonido a través de GStreamer (0.10) en vez de usar ALSA o PulseAudio
directamente, y es GStreamer el que se encarga de usar el backend
apropiado. En Debian esto se traduce en que tanto xfce4-mixer
como xfce4-volumed tienen una dependencia del paquete
gstreamer0.10-alsa
o alternativamente del paquete virtual
gstreamer0.10-audiosink
(que provee entre otros el
paquete gstreamer0.10-pulseaudio
). Así que dependiendo de si usamos
ALSA o PulseAudio debemos tener instalado el paquete del backend de
GStreamer que corresponda.
Por desgracia, me temo que los desarrolladores de Xfce se preocupan
esencialmente de la integración con ALSA, y por eso la dependencia con
gstreamer0.10-alsa
es más prioritaria que el resto. Esto hace que casi
siempre acabe instalandose gstreamer0.10-alsa
(sobre todo si
previamente se tenía una instalación con ALSA como es mi caso), lo que a
su vez provoca que apt
o aptitude
no encuentren necesario instalar
gstreamer0.10-pulseaudio
. En la práctica es fácil encontrarse en la
situación de no tener instalado este backend a pesar de tener
instalado PulseAudio, y esa como veremos luego es una de las razones de
la existencia de estos bugs.
Otra de razones es que simplemente las aplicaciones no están pensadas
con la arquitectura de PulseAudio en mente. Están hechas para un tiempo
en el que el sistema de sonido consistía en un único dispositivo
hardware estático al que mandar el audio, y como mucho del que
recibirlo. Escenarios como conectar un headset Bluetooth y que el
audio tenga automáticamente que migrar a este nuevo dispositivo no se
concebían entonces, pero actualmente se asume que el sistema tiene que
soportarlos (es lo que pasa por ejemplo en el bug #677014 ).
Esto lleva a casos como el del propio mantenedor de xfce4-volumed
diciendo que su aplicación no es compatible con
PulseAudio . El problema que tiene este desarrollador no es
adaptar su aplicación a una nueva API, es que tendría que rediseñarla de
arriba a abajo basándose en el nuevo modelo dinámico de PulseAudio. Y la
impresión que me da es que no está muy por la labor.
A esto hay que añadir que el mismo autor considera a día de hoy
xfce4-volumed como sin mantenimiento :
XVD is no longer maintained It relies on libkeybinder and gst-0.10,
both of which are superseded, and it needs to integrate a longstand
PulseAudio support patch. I will, eventually, rewrite xvd with
libxfce4utils instead of libkeybinder and gst1.0 instead of gst-0.10.
If you want to contribute to Xfce by fixing an old but useful piece
of code, get in touch with me!
lo que queda corroborado por el hecho de que la última versión que hay
—la 0.1.13— en el repositorio git oficial es de marzo de 2011.
El parche de soporte de PulseAudio al que se refiere debe ser
xfce4-volumed-pulse . El autor del mismo
explica :
The developer of xfce4-volumed said that xfce4-volumed isn't
compatible with pulseaudio, but that's not really accurate. The first
problem is a default settings issue (preselection of the correct gst
card/channel), and the second culprit is gstreamer pulse plugin is
one culprit (basically, the bindings suck, let's say it).
[...]
A few months ago, I "forked" xfce4-volumed and ported it locally to
pulseaudio. It works fine here (it takes the default pulse card, you
can't change it with xfconf-query anymore, but with pactl or the
pulseaudio mixer), but it didn't have many testing and I haven't had
time to include it in Xubuntu anyway.
La pega es que si se quiere usar xfce4-volumed-pulse hay que compilarlo
e instalarlo a mano. No está empaquetado en Debian y tampoco he
visto ningúna petición o intento de empaquetarlo.
De todas formas xfce4-volumed-pulse es una solución justo para salir del
paso. Como dice su desarrollador, xfce4-volumed tiene que reescribirse
aunque sólo sea porque hay que migrar la aplicación de GStreamer 0.10 a
GStreamer 1.x (ya expliqué hace poco que GStreamer 0.10 está llamado a
desaparecer y Debian no lo va a incluir más a partir de
Stretch ). Y además hay otros cambios pendientes en
la infraestructura de bibliotecas de soporte de Xfce que exigen una
nueva reimplementación. Puede ser el momento apropiado para empezar
desde cero y arreglar todo de una vez.
La situación de xfce4-mixer es muy parecida: puede considerarse en
estado "sin mantenimiento". La última versión estable es la 4.10 de
octubre de 2012 y hay una primera versión de desarrollo 4.11
de abril de 2014, pero desde entonces el repositorio git no
se ha tocado salvo para actualizar traducciones. Y encima cuando abren
un bug pidiendo soporte de PulseAudio en xfce4-mixer , la
respuesta del mantenedor es cerrarlo WONTFIX diciendo:
I'm not telling you that it's a good situation. I'm telling you that
xfce4-mixer is going to get a final 4.12 release and then that it's
unmaintained. This bug won't be fixed.
Y como alternativa propone usar xfce4-pulseaudio-plugin , que
algunas distros incluyen pero Debian todavía no . El
diálogo es de marzo de este año, así que es posible que no haya habido
tiempo todavía de empaquetarlo.
Así que nos encontramos en una situación en la que las dos aplicaciones
oficiales de Xfce no soportan PulseAudio, y no parece que lo vayan a
tener ya (no al menos hasta que se haga una reescritura completa de las
mismas). Y las alternativas no están maduras o todavía no han llegado a
downstream . Así que es el momento de las soluciones temporales, los
hacks guarros y la cinta adhesiva.
Pásame la cinta adhesiva, Otilio
El bug de launchpad "Pulse Audio don't get unmuted when XF86AudioMute
is used" es un compendio de este tipo soluciones/hacks para
el bug del Unmute. La mayoría de ellas se basan en suplantar la
funcionalidad de xfce4-volumed haciendo que el window manager de Xfce
ejecute cierto comando o script cuando se pulsa XF86AudioMute (la
tecla que envía el servidor X cuando se pulsa "Mute" en un teclado con
teclas multimedia). Lo que varía es el comando base utilizado para
controlar la función Mute de PulseAudio.
Por ejemplo, se puede usar el comando pactl
para decirle directamente
a PulseAudio que queremos aplicar un Mute o Unmute a un sink . O mejor
todavía, podemos usar "toggle" para cambiar entre Mute y Unmute, que es
lo que realmente suele hacer el botón multimedia:
pactl set-sink-mute <sink> toggle
El nombre del sink se puede obtener de la lista de pactl list short
sinks
.
Basta con añadir este comando a un nuevo atajo de teclado definido en la
la opción de configuración "Teclado" de Xfce:
Nota: es buena práctica reiniciar la sesión para asegurarse que Xfce
ha leído la nueva configuración.
De la misma manera se podría pensar en solucionar el segundo bug
haciendo atajos para que las teclas XF86AudioRaiseVolume y
XF86AudioLowerVolume invoquen el incremento/decremento de volumen en
el sink :
pactl set-sink-volume <sink> +2%
pactl set-sink-volume <sink> "-2%"
El problema de este método es que sólo sirve para un único sink . Si
hay varios sinks , como mi caso con ALSA y BlueZ (el headset ),
necesitaríamos una forma de expresar "el sink que esté ahora activo".
Pero esa forma no existe. Hay un nombre especial (@DEFAULT_SINK@
) pero
es para otra cosa distinta: indica el sink por defecto (aquel
seleccionado por el usuario para hacer fallback ). Pero no tenemos
uno equivalente para indicar el sink activo (lo cual es una pena
porque sería realmente útil para el segundo bug).
Ya que un comando no era suficiente, lo siguiente fue escribir scripts
completos que se lanzan al pulsar XF86AudioMute . Por ejemplo hay uno
que parsea la salida de pactl list short sinks
para saber cuál está
activo (RUNNING) y aplicarle el pactl set-sink-mute <sink> toggle
.
Otro usa un método mucho menos refinado: recorre toda la lista actual de
sinks y aplica el toggle a todos y cada uno de ellos. Algunos
necesitan guardar cierto estado, y lo hacen leyendo y escribiendo el
estado en ficheros entre ejecuciones (¡encima en el directorio
.pulse
!).
No puedo ni empezar a describir lo problemático que es todo esto. Son
soluciones superfrágiles, que si bien funcionan para una ñapa rápida, en
cuanto algo se desbarate al que no conozca cómo funcionan le va a dar
unos dolores de cabeza indescriptibles y de muy difícil diagnóstico y
arreglo (más que nada porque no es algo estándar de lo que pueda buscar
una solución o abrir un bug).
En vez de pactl
otra gente está usando el comando amixer
para hacer
el Mute/Unmute de PulseAudio. Esto funciona porque, aunque amixer es
para manipular el mixer de ALSA, ellos en realidad lo están aplicando
(probablemente sin saberlo) sobre una tarjeta de sonido ALSA virtual
especial llamada "pulse", y que en realidad sirve para representar al
demonio de PulseAudio. Así que cuando ejecutan:
amixer -D pulse set Master mute
amixer -D pulse set Master unmute
amixer -D pulse set Master toggle
En realidad están diciéndole al mixer de PulseAudio y no al de ALSA que
haga el Mute o Unmute (o el "toggle", que sería el apropiado para
asociar a la tecla XF86AudioMute ).
Este engaño no es más que una forma de proporcionar compatibilidad a
viejos programas (normalmente propietarios que no se pueden recompilar
para PulseAudio) que sólo sabían usar tarjetas ALSA a través de
alsa-libs . En el caso de Debian, la magia reside en el paquete
libasound2-plugins
, ya que es ahí donde se añade el plugin que crea
esta tarjeta de sonido virtual "pulse" que redirige por detrás el audio
a PulseAudio.
En la página The Perfect Setup de PulseAudio, en la sección
"Third Party Applications" (y también en el hilo del bug) se explica
cómo configurar alsa-libs (libasound2) para que la tarjeta de sonido
"pulse" sea el dispositivo por defecto, modificando el
/etc/asound.conf
(afecta a todo el sistema) o el ~/.asoundr
(afecta
sólo al usuario). Resulta que en Debian Jessie y Stretch no hace
falta , ya que ya traen esta configuración de serie si se instala el
paquete pulseaudio
y su dependencia libasound2-plugins
. Por si
alguien tiene curiosidad, está en:
/usr/share/alsa/alsa.conf.d/50-pulseaudio.conf
y en
/usr/share/alsa/pulse-alsa.conf
.
Lo podemos comprobar con amixer
:
$ amixer info
Card default 'pulse'/'PulseAudio'
Mixer name : 'PulseAudio'
Components : ''
Controls : 4
Simple ctrls : 2
Si lo tenéis así, el -D pulse
de los comandos de arriba en realidad
sobra, y el comando de Mute/Unmute se reduce a un simple:
Un momento, y entonces ¿por qué falla xfce4-volumed? ¿No es este el
equivalente a lo que hace internamente el demonio? Pues parece ser que
no . En realidad xfce4-volumed no usa el dispositivo ALSA por
defecto sino la propiedad "active-card" de la configuración de
xfce4-mixer que se guarda en el Editor de Configuraciones general de
Xfce:
En mi caso vale HDAIntelPCHAlsamixer
y se refiere específicamente
al mixer de la tarjeta ALSA física, no al del dispositivo ALSA por
defecto, ya que GStreamer conoce esta tarjeta (a través de su backend
gstreamer0.10-alsa
, que la está usando) y por eso se salta la charada
que ha montado PulseAudio para ir a modificar directamente el mixer del
dispositivo ALSA.
Y es aquí donde llegamos a este comentario en un bug
abierto contra PulseAudio precisamente por este asunto del Unmute:
Ok, then I guess xfce4-volumed is accessing alsa directly, instead of
doing the muting through pulseaudio.
Explanation for the inconsistency between muting and unmuting:
xfce4-volumed sets the Master switch to muted. PulseAudio notices that
something happened in the alsa mixer, and sees that one of the switches
is muted, so PulseAudio concludes that the device is muted and sets the
internal device state to mute. While setting the internal state,
pulseaudio also mutes the rest of the switches marked as "switch =
mute", including PCM. When xfce4-volumed unmutes the Master switch,
PulseAudio again notices that something happened, but since the PCM
switch is still muted, PulseAudio concludes that the device is still
muted and does nothing.
xfce4-volumed should be changed to talk to pulseaudio instead of
accessing the alsa mixer directly.
Esto está en consonancia con lo que ya sabemos (que funciona si usamos
el mixer de PulseAudio) y también explica por qué está pasando (por
culpa de PulseAudio, ¡que raro! :-P
). Sólo tenemos que conseguir que
xfce4-volumed use el mixer adecuado para que los problema se arreglen
sin necesidad de andar con atajos de teclado, scripts y demás.
Pues la solución es tan sencilla como instalar el backend de GStreamer
para PulseAudio gstreamer0.10-pulseaudio
. Una vez instalado,
nuevamente nos aseguramos que Xfce detecte los cambios reiniciando la
sesión , y en el desplegable de selección de Mixers de xfce4-mixer
elegimos como dispositivo el que corresponde a "PulseAudio Mixer" en vez
del "ALSA Mixer".
¡Y funciona! Bueno, funciona el Mute/Unmute correctamente, pero sólo
para el dispositivo ALSA. También he conseguido que se arregle el tercer
bug (ya no tengo notificaciones de cambios de sonido fantasmas). Puedo
cambiar el Mixer al que corresponde a mi headset si lo enciendo antes
de iniciar la sesión (entonces las teclas de Mute y de volumen
funcionan, pero sólo para el headset ), pero no es práctico tener que
reiniciar la sesión cada vez que quiero cambiar de dispositivo
PulseAudio. Como ya he comentado, esto sólo se soluciona con una
aproximación más dinámica a la detección de dispositivos y eso es algo
de lo que carecen actualmente tanto xfce4-mixer como xfce4-volumed.
:wq