Como alterar automaticamente o nível do volume ao desconectar / conectar os fones de ouvido?

36

O que eu quero é o seguinte:

  • Quando conecto meus fones de ouvido, quero que o som fique sem som e definido para um nível de volume específico.
  • Quando desconecto os fones de ouvido, quero que o som fique mudo (ou definido para um nível de volume específico).

Definir os níveis de volume não é o problema, mas de alguma forma eu preciso fazer isso ao desconectar / conectar os fones de ouvido, então estou procurando uma maneira de ser notificado sobre esses eventos.

Eu rapidamente descobri /proc/asound/card0/codec#0que os fones de ouvido estão conectados ou não, então tentei monitorá-lo usando inotifywaite alterando o nível do volume com base nas notificações modificadas . Infelizmente inotifywaitfalhei porque proc não é um sistema de arquivos comum.

Existem outras maneiras de fazer isso (talvez via PulseAudio)?

Dispositivo de áudio: Intel HDA , codec de áudio: Conexant CX20585 .


Para resumir o que tentei até agora:

  • Ear Candy: não funcionou no meu sistema. Parece ser um projeto abandonado?
  • O código postado por Karl Bielefeldt pode funcionar em algum hardware, não no meu.
  • A ideia de StephenPaulger falha devido à falta de um canal 'Speaker'.
  • Motivado por aking1012, eu fiz o trabalho invadindo o código do kernel (depois de encontrar o código do sensor de tomada do codec), mas essa é uma solução bastante complicada.

Então, ainda estou procurando uma maneira fácil de fazer isso.

htorque
fonte
Excelente pergunta, eu quero fazer isso também!
Stephen Paulger 03/02
legal ... mas acho que um patch para o alsa será necessário para a resposta "instantânea" desejada ao conectar / desconectar. caso contrário, funcionaria ou pareceria funcionar, mas, sob carga ou outras condições, a resposta poderia demorar. acho que você precisa entrar entre o evento plug e a alternância de saída. provavelmente possível, mas muuuuito não vale uma correção individual, a menos que um desenvolvedor da alsa diga que estará comprometido com o tronco.
RobotHumans
uma abordagem seria carregar o módulo em gdb, aguardar a interrupção dos eventos de som "normais", usar a opção de gravação, conectar e desconectar os fones de ouvido e ver o que aconteceu na gravação de depuração.
RobotHumans
com quanto tempo você se sente confortável?
RobotHumans

Respostas:

3

Para definir o nível do volume no console, use o comando amixer. Por exemplo:

amixer sset Reprodução mestre 0%

Definirá seu nível para 0%

Não sei como mudar isso quando você conecta seus fones de ouvido ... mas talvez alguém possa ajudá-lo com isso

Luciano Facchinelli
fonte
3

Durante o UDS para Oneiric, houve uma sessão sobre detecção de jack. Veja o blueprint para detalhes. Parece que isso fará exatamente o que estou procurando: níveis de volume diferentes para dispositivos diferentes - mas não em todos os hardwares:

<htorque> algo que me interessa: poderei ter níveis de volume diferentes para dispositivos diferentes (por exemplo, som interno sem som, fones de ouvido 75%) em breve?

<coling> isso será suportado (em alguns h / w) sim. As escalas de tempo são "breves": p
<coling> (também esperaria que o OSD fosse mostrado (com o volume atual) quando as tomadas estiverem conectadas / desconectadas)

Atualização para 11.10

Isso agora deve estar funcionando em Oneiric - infelizmente, o meu ThinkPad T510 parece ser um dos sistemas atualmente não suportados.

Outro acompanhamento de David Henningsson:

Para encurtar a história, é um recurso desejável, e estamos caminhando nessa direção, mas lentamente, pois o recurso é mais complexo do que parece à primeira vista.

A boa notícia: no próximo Ubuntu Oneiric (11.10), isso está realmente funcionando. A má notícia: não está funcionando para todos.

Mais aqui .

Atualização para 12.04

Agora ele está trabalhando com o meu ThinkPad T510 (e muitos outros modelos) no Ubuntu 12.04 (versão de desenvolvimento).

htorque
fonte
Existe algo rastreando qual hardware é suportado atualmente ou algo nesse sentido?
Mu Mente
2

O Ear Candy possui algumas funcionalidades para lidar com a inserção / remoção de fones de ouvido.

zacharyliu
fonte
1
Parece que isso é apenas para fones de ouvido USB ... está correto?
Mu Mente
2

Não sei quanta experiência de codificação você tem, mas você mencionou, inotifywaitportanto, assumirei que você se sinta ao menos confortável com scripts de shell. O programa C a seguir, com base neste artigo , deve detectar os fones de ouvido conectados ou desconectados, após o qual você pode executar as ações que desejar.

#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>

int main(int argc, char* argv[])
{
    int fd = -1;
    char name[256]= "Unknown";
    struct input_event event;

    if ((fd = open(argv[1], O_RDONLY)) < 0) {
        perror("evdev open");
        exit(1);
    }

    if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) {
        perror("evdev ioctl");
    }

    printf("The device on %s says its name is %s\n",
            argv[1], name);

    read(fd, &event, sizeof(struct input_event));
    printf("Event type is %d\n", event.type);
    printf("Event code is %d\n", event.code);
    printf("Event value is %d\n", event.value);

    close(fd);
    return 0;
}

O programa usa um argumento, que deve ser o caminho para o dispositivo de evento de entrada para seus fones de ouvido. Isso é /dev/input/event7para mim, mas você pode precisar tentar alguns para descobrir qual é o seu sistema. Você precisará de permissões de leitura nesse dispositivo. O programa imprimirá o nome do dispositivo e o tipo, código e valor do primeiro evento antes de sair.

Karl Bielefeldt
fonte
Infelizmente, nenhum dos eventos * acabou por estar conectado ao meu fone de ouvido. De qualquer forma, +1 - talvez seja útil para outros usuários.
Htorque
O +1, funciona para mim, event.valueé realmente alternado ... mas a readoperação só retorna quando o valor muda ... talvez você saiba como fazê-lo não bloquear? obrigado mesmo assim!
28513 Kevin Kevin
Você adiciona O_NONBLOCKquando abre o dispositivo e verifica o valor de retorno do read. Se for negativo, a leitura teria bloqueado ou ocorreu algum outro erro. Existem outras maneiras mais complicadas de fazer isso sem pesquisar, se você estiver incorporando isso a um programa maior.
Karl Bielefeldt
1

Verifique o dmesg e outros arquivos de log. Provavelmente, conectar / desconectar aciona algumas mensagens específicas.

Em seguida, você pode usar um daemon para analisar esse arquivo de log e detectar os eventos. Eu acho que você sabe o que fazer a partir deste ponto :)

Pedro Loureiro
fonte
1

Se você fizer

amixer sset 'Speaker' playback 0%

o volume do alto-falante ficará mudo, mas os fones de ouvido continuarão funcionando. Desconectar os fones de ouvido significa que não há som. Que é quase o que você quer ...

No entanto ...

Se você alterar o controle de volume, a configuração de volume do 'Alto-falante' será configurada novamente. Isso ocorre porque o pulseaudio tenta ser inteligente ao definir volumes (consulte http://pulseaudio.org/wiki/PulseAudioStoleMyVolumes para obter mais informações). No entanto, podemos impedir que mexa nos volumes.

Abra /etc/pulse/default.pa

e encontre a linha

load-module module-udev-detect

e mude para

load-module module-udev-detect ignore_dB=1

Reinicie o pulseaudio.

killall pulseaudio

Agora, se você silenciar o volume do alto-falante, a alteração do volume principal não o afetará. Portanto, os fones de ouvido funcionarão, mas o alto-falante permanecerá silencioso.

StephenPaulger
fonte
Seria uma abordagem diferente, mas infelizmente não tenho um canal de volume de alto-falante, apenas Master e PCM.
htorque 8/02/11
1

Verifique se há alterações no soquete ACPID, isso pode ser feito com a ajuda de python ou C ou shell script ( código Python para controlar a reprodução do plug-in do fone de ouvido e pausar no rhythmbox). Verifique as alterações na tensão do ACPID para detectar o plug-in e o plug-in do fone de ouvido. Um atraso de segundos pode ser esperado.

t3pleni9
fonte