Detectando conexão / desconexão de fone de ouvido no Linux

30

Estou tentando detectar um sinal quando um fone de ouvido está conectado ou desconectado do sistema. Qual é a melhor maneira de fazer isso?

Se houver uma placa especial com drivers, essa será a minha maneira preferida.

user775633
fonte
Não sei se entendi a última parte - você pretende fazer isso conectando um hardware adicional ao seu computador?
rozcietrzewiacz
@rozcietrzewiacz - Eu tenho um aplicativo java que precisa ser notificado se o fone de ouvido estiver conectado ou desconectado. Esse é o meu objetivo. Estou aberto a sugestões / recomendações com ou sem o uso de hardware adicional.
user775633
@Gilles - Não, hardware típico faz fornecer notificação ao software. Sei que isso é U&L, mas você provavelmente conhece a notificação clássica e irritante do Windows: "Você conectou um dispositivo à entrada de áudio!" i51.tinypic.com/2w2hogw.jpg . Felizmente, o Linux não faz isso, mas as informações devem estar disponíveis no hardware que você possui. A questão é como o sistema operacional disponibiliza essas informações.
Kevin Vermeer
@KevinVermeer Por acaso não estou familiarizado com esse aborrecimento específico do Windows, não. É bom saber que o hardware moderno fornece notificação, obrigado. O Linux normalmente forneceria as informações até /sysentão, e talvez notificações via dbus.
Gilles 'SO- stop be evil'
Isso não está em um sistema Windows. Este problema é para os Linux. Eu deveria ter sido mais explícito. Desculpe! De qualquer forma, parece que, por padrão, não há uma maneira fácil de interceptar essa notificação. É por isso que estou pensando em verificar se há algum cartão personalizado com um driver que intercepte e disponibilize esse sinal para aplicativos em execução no Linux.
precisa saber é o seguinte

Respostas:

17

No meu linux (Debian GNU / Linux 3.12.0 x86_64) isso é conhecido pelo sistema acpi, como acpi_listenmostra:

jack/microphone MICROPHONE plug
jack/headphone HEADPHONE plug
jack/microphone MICROPHONE unplug
jack/headphone HEADPHONE unplug

isso parece depender de uma opção selecionada na configuração do kernel CONFIG_SND_HDA_INPUT_JACK

Se este for o seu caso, você pode preencher /etc/acpi/events/com scripts para disparar o que quiser.

Verifique a página de manual do acpid http://linux.die.net/man/8/acpid

teísta
fonte
Isso funciona perfeitamente no meu sistema Ubuntu 15.10 com HDA Intel PCH, ALC892 Analog, conforme relatado por Alsa. CONFIG_SND_HDA_INPUT_JACK = y está definido.
kevinf
14

Esta informação está disponível /proc/asound/card0/codec#0e depende do hardware. Para o meu computador, está na seção que captura essas informações:

Fone de ouvido conectado:

[...]
Node 0x0d [Pin Complex] wcaps 0x400181: Stereo
  Control: name="Speaker Phantom Jack", index=0, device=0
  Pincap 0x00000014: OUT Detect
  Pin Default 0x90170110: [Fixed] Speaker at Int N/A
    Conn = Analog, Color = Unknown
    DefAssociation = 0x1, Sequence = 0x0
    Misc = NO_PRESENCE
  Pin-ctls: 0x00:
[...]

Fone de ouvido desconectado (consulte Pin-ctls):

[...]
Node 0x0d [Pin Complex] wcaps 0x400181: Stereo
  Control: name="Speaker Phantom Jack", index=0, device=0
  Pincap 0x00000014: OUT Detect
  Pin Default 0x90170110: [Fixed] Speaker at Int N/A
    Conn = Analog, Color = Unknown
    DefAssociation = 0x1, Sequence = 0x0
    Misc = NO_PRESENCE
  Pin-ctls: 0x40: OUT
[...]

Você pode usar o inotify para verificar se o arquivo foi modificado e grep as informações.

Veja também https://askubuntu.com/questions/133809/mute-sound-on-headphone-unplug .

Florian Bw
fonte
1
man inotifydiz que pseudo-fs como / proc não são monitoráveis ​​com o inotify. existe uma solução alternativa?
Bibek_G 12/02/16
@Bibek_G sim, use acpi_listen(veja a resposta do teísta).
Don escotilha
Eu tive que usar em audio1vez disso audio0para que isso funcionasse, mesmo que eu tenha apenas um notebook simples com uma única placa de som. então é /proc/asound/card1/codec#0para mim, pode ser outro número para você.
hoijui
3

Encontre o etiquetador udev da tomada no sistema, conecte um cliente (dbus-monitor) que monitore o barramento usando o DBus para obter mensagens sobre a conexão e desconexão da tomada.

Nikhil Mulley
fonte
2

Se o seu kernel possui entradas de jack configuradas root@brix:~# grep CONFIG_SND_HDA_INPUT_JACK /boot/config-$(uname -r)

Usando Evtestvocê pode listar todos os seus eventos de entrada.

root@brix:/etc/acpi# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:  Power Button
/dev/input/event1:  Power Button
/dev/input/event2:  Logitech Logitech BT Mini-Receiver
/dev/input/event3:  CM Storm QuickFire Rapid keyboard
/dev/input/event4:  CM Storm QuickFire Rapid keyboard
/dev/input/event5:  PixArt Microsoft USB Optical Mouse
/dev/input/event6:  Logitech Logitech BT Mini-Receiver
/dev/input/event7:  Video Bus
/dev/input/event8:  HDA Intel HDMI HDMI/DP,pcm=3
/dev/input/event9:  HDA Intel HDMI HDMI/DP,pcm=7
/dev/input/event10: HDA Intel HDMI HDMI/DP,pcm=8
/dev/input/event11: HDA Intel PCH Front Mic
/dev/input/event12: HDA Intel PCH Rear Mic
/dev/input/event13: HDA Intel PCH Line
/dev/input/event14: HDA Intel PCH Line Out
/dev/input/event15: HDA Intel PCH Front Headphone
Select the device event number [0-15]: 14
Input driver version is 1.0.1
Input device ID: bus 0x0 vendor 0x0 product 0x0 version 0x0
Input device name: "HDA Intel PCH Line Out"
Supported events:
  Event type 0 (EV_SYN)
  Event type 5 (EV_SW)
    Event code 6 (SW_LINEOUT_INSERT)
Properties:
Testing ... (interrupt to exit)
Event: time 1465927534.591787, type 5 (EV_SW), code 6 (SW_LINEOUT_INSERT), value 0
Event: time 1465927534.591787, -------------- EV_SYN ------------
Event: time 1465927536.618428, type 5 (EV_SW), code 6 (SW_LINEOUT_INSERT), value 1
Event: time 1465927536.618428, -------------- EV_SYN ------------
kevinf
fonte
2

Uma ferramenta chamada hda-verb pode ativar / desativar o fone de ouvido usando pinos.

Por exemplo,

Para ativar o fone de ouvido, use:

./hda-verb /dev/snd/hwC0D0 0x0f SET_PIN_WIDGET_CONTROL 0x40

Para desativar o fone de ouvido, use:

./hda-verb /dev/snd/hwC0D0 0x0f SET_PIN_WIDGET_CONTROL 0

Como você deseja apenas verificar seu status, talvez você possa usar algum mecanismo de pesquisa em seu programa java que pode verificar o status dos pinos acima usando hda. Para isso, seu programa java deve poder chamar hda-verb. Como alternativa, você pode verificar a fonte do hda-verbo disponível e ver como eles o fizeram.

Omar Khan
fonte
0

Meu laptop possui um sistema de áudio Conexant Intel HDA, mas os controles de volume do microfone e do fone de ouvido nunca aparecem nos diversos mixers disponíveis, mesmo no mesmo mixer. Os alto-falantes do microfone e dos fones de ouvido só podem ser ligados ou desligados. Aqui está um pequeno script para fazer exatamente isso:

#!/bin/bash
#
# Switching on or off your headphone speaker and mic jacks
# and at the same time switching off or on your laptop front speakers.
# requires hda-verb-0.3-6-mdv2011.0.x86_64
#
# Before putting it in place make sure to test your PIN_WIDGET_CONTROL's
# with su -c 'python2 hda-analyzer.py' available here :
# http://www.alsa-project.org/hda-analyzer.py
#
PIN_CONFIGS=/sys/class/sound/hwC0D0/init_pin_configs
if [ ! -f $PIN_CONFIGS ]; then
    echo "Your kernel is missing CONFIG_SND_HDA_HWDEP=y"
    exit 0
fi
if [ ! -f /usr/sbin/hda-verb ]; then
    echo "This script requires hda-verb-0.3-6-mdv2011.0.x86_64"
    exit 0
fi
PINS_PRESENT=`cat $PIN_CONFIGS | awk '{print $1}'`
if [ `basename $0` = "speakers-off.sh" ]; then
# Headset (Mic (Node 0x1b) + Headphone Drive (Node 0x19)) : ON
# Laptop Speaker (Node 0x1f) : OFF
[ `echo "$PINS_PRESENT" | grep 0x19` ] &&
   /usr/sbin/hda-verb /dev/snd/hwC0D0 0x19 SET_PIN_WIDGET_CONTROL 0x40
[ `echo "$PINS_PRESENT" | grep 0x1f` ] &&
   /usr/sbin/hda-verb /dev/snd/hwC0D0 0x1f SET_PIN_WIDGET_CONTROL 0
[ `echo "$PINS_PRESENT" | grep 0x1b` ] &&
   /usr/sbin/hda-verb /dev/snd/hwC0D0 0x1b SET_PIN_WIDGET_CONTROL 0x64
fi

if [ `basename $0` = "speakers-on.sh" ]; then
# Headset (Mic (Node 0x1b) + Headphone Drive (Node 0x19)) : OFF
# Laptop Speaker (Node 0x1f) : ON
[ `echo "$PINS_PRESENT" | grep 0x19` ] &&
   /usr/sbin/hda-verb /dev/snd/hwC0D0 0x19 SET_PIN_WIDGET_CONTROL 0
[ `echo "$PINS_PRESENT" | grep 0x1f` ] &&
   /usr/sbin/hda-verb /dev/snd/hwC0D0 0x1f SET_PIN_WIDGET_CONTROL 0x40
[ `echo "$PINS_PRESENT" | grep 0x1b` ] &&
   /usr/sbin/hda-verb /dev/snd/hwC0D0 0x1b SET_PIN_WIDGET_CONTROL 0x24
fi

exit 0
rmstock
fonte