Wykrywanie połączenia / rozłączenia słuchawek w systemie Linux

30

Próbuję wykryć sygnał, gdy słuchawki są podłączone lub odłączone od systemu. Jak najlepiej to zrobić?

Jeśli jest specjalna płyta ze sterownikami, to będzie mój preferowany sposób.

użytkownik775633
źródło
Nie jestem pewien, czy rozumiem ostatnią część - czy zamierzasz to zrobić, podłączając dodatkowy sprzęt do swojego komputera?
rozcietrzewiacz
@rozcietrzewiacz - Mam aplikację Java, która wymaga powiadomienia, jeśli słuchawki są podłączone lub odłączone. To jest mój cel. Jestem otwarty na wszelkie sugestie / rekomendacje z lub bez użycia dodatkowego sprzętu.
user775633,
@Gilles - Nie, typowy sprzęt komputerowy ma dostarczyć zgłoszenie do programu. Wiem, że to U&L, ale prawdopodobnie znasz klasyczne irytujące powiadomienie systemu Windows: „Podłączyłeś urządzenie do gniazda audio!” i51.tinypic.com/2w2hogw.jpg . Linux na szczęście tego nie robi, ale informacje powinny być dostępne z posiadanego sprzętu. Pytanie brzmi, w jaki sposób system operacyjny udostępnia te informacje.
Kevin Vermeer,
@KevinVermeer Nie zdarza mi się być zaznajomiony z tą konkretną irytacją Windows, nie. Dobrze wiedzieć, że nowoczesny sprzęt zapewnia powiadomienia, dziękuję. Linux zwykle przekaże wtedy informacje /sys, a być może powiadomienia przez dbus.
Gilles „SO- przestań być zły”
To nie jest w systemie Windows. Ten problem dotyczy systemu Linux. Powinienem był być bardziej wyraźny. Przepraszam! W każdym razie wygląda na to, że domyślnie nie ma łatwego sposobu na przechwycenie tego powiadomienia. Dlatego zastanawiam się nawet, czy są jakieś niestandardowe karty, które mają sterownik, który przechwytuje i udostępnia ten sygnał dla aplikacji działających na systemie Linux.
user775633,

Odpowiedzi:

17

W moim systemie Linux (Debian GNU / Linux 3.12.0 x86_64) jest to znane przez system acpi, więc wywoływanie acpi_listenpokazuje:

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

wydaje się, że zależy to od wybranej opcji w konfiguracji jądra CONFIG_SND_HDA_INPUT_JACK

W takim przypadku możesz wypełnić /etc/acpi/events/skrypty, aby uruchomić w dowolnym momencie.

Sprawdź stronę man acpid http://linux.die.net/man/8/acpid

teista
źródło
Działa to doskonale na moim systemie Ubuntu 15.10 z HDA Intel PCH, ALC892 Analog, jak donosi Alsa. CONFIG_SND_HDA_INPUT_JACK = y jest ustawione.
kevinf
14

Informacje te są dostępne /proc/asound/card0/codec#0i zależą od sprzętu. W przypadku mojego komputera jest to sekcja, która przechwytuje te informacje:

Podłączone słuchawki:

[...]
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:
[...]

Słuchawki odłączone (patrz 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
[...]

Możesz użyć inotify, aby sprawdzić, czy plik został zmodyfikowany i grep informacji.

Zobacz także https://askubuntu.com/questions/133809/mute-sound-on-headphone-unplug .

Florian Bw
źródło
1
man inotifymówi, że pseudo-fs, takie jak / proc, nie mogą być monitorowane za pomocą inotify. Czy jest w pobliżu praca?
Bibek_G
@Bibek_G tak, użyj acpi_listen(patrz odpowiedź teisty ).
Don Hatch
Musiałem użyć audio1zamiast audio0tego, aby to zadziałało, chociaż mam tylko prosty notebook z jedną kartą dźwiękową. więc to jest /proc/asound/card1/codec#0dla mnie, może to być dla ciebie jeszcze inny numer.
hoijui
3

Znajdź znacznik udev gniazda w systemie, podłącz klienta (dbus-monitor), który monitoruje magistralę za pomocą DBus pod kątem komunikatów o podłączeniu i rozłączeniu gniazda.

Nikhil Mulley
źródło
2

Jeśli twoje jądro ma skonfigurowane wejścia jack root@brix:~# grep CONFIG_SND_HDA_INPUT_JACK /boot/config-$(uname -r)

Za pomocą Evtestmożesz wyświetlić listę wszystkich zdarzeń wejściowych.

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
źródło
2

Narzędzie o nazwie hda-verb może włączać / wyłączać gniazdo słuchawkowe za pomocą pinów.

Na przykład,

Aby włączyć gniazdo słuchawkowe, użyj:

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

Aby wyłączyć gniazdo słuchawkowe, użyj:

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

Ponieważ chcesz po prostu sprawdzić jego status, być może możesz użyć mechanizmu odpytywania w programie Java, który może sprawdzić stan powyższych pinów za pomocą hda. W tym celu program Java powinien móc wywoływać czasownik hda. Alternatywnie możesz sprawdzić źródło czasownika hda, gdy jest ono dostępne, i zobaczyć, jak to zrobili.

Omar Khan
źródło
0

Mój laptop ma system audio HD HD firmy Conexant, ale regulacja głośności mikrofonu i gniazda słuchawkowego nigdy nie pojawia się w wielu dostępnych mikserach, nawet w alsamixerze. Głośniki mikrofonu i słuchawek można włączać i wyłączać tylko. Oto mały skrypt, aby to zrobić:

#!/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
źródło