拔/插耳机时如何自动改变音量?


36

我想要的是以下内容:

  • 插入耳机时,我希望声音不会被静音并设置为特定的音量。
  • 拔下耳机时,我希望声音被静音(或设置为特定的音量)。

设置音量级别不是问题,但是在拔出/插入耳机时我需要某种方式执行此操作,因此我正在寻找一种方法来通知这些事件。

我很快发现/proc/asound/card0/codec#0可以指示是否插入了耳机,因此我尝试使用耳机进行监听inotifywait并根据修改后的通知更改音量。不幸的是inotifywait失败了,因为proc不是普通的文件系统。

还有其他方法(可能通过PulseAudio)吗?

音频设备:Intel HDA,音频编解码器:Conexant CX20585


总结一下到目前为止我已经尝试过的内容:

  • Ear Candy:我的系统上根本没有运行。似乎是一个废弃的项目?
  • 卡尔·比勒费尔特Karl Bielefeldt)发布的代码可能适用于某些硬件,而不适用于我的硬件。
  • StephenPaulger的想法由于缺少“发言人”频道而失败。
  • 受到aking1012的激励,我通过在内核代码中进行破解(在找到编解码器的杰克感知代码之后)使其工作了,但这是一个相当麻烦的解决方案。

因此,我仍在寻找一种简便的方法来执行此操作。


很好的问题,我也想这样做!
斯蒂芬·保罗

很好...但是我认为对alsa进行补丁对于插入/拔出所需的“即时”响应是必要的。否则它将起作用或似乎起作用,但是在负载或其他条件下,响应可能会滞后。认为您必须介于插入事件和输出切换之间。可能是可行的,但是不值得单独打补丁,除非alsa开发人员说它将致力于主干。
RobotHumans 2011年

一种方法是将模块加载到gdb中,等待“正常”声音事件停止,使用record选项,插入和拔出耳机,然后查看调试记录中发生了什么。
RobotHumans 2011年

您对多少延迟感到满意?
RobotHumans 2011年

Answers:



3

在Oneiric的UDS期间,进行了有关插孔检测的会话。有关详细信息,请参见蓝图。听起来这将完全满足我的需求:不同设备的音量级别不同-并非在每种硬件上都这样:

<htorque>我很好奇的一点:我很快就能为不同的设备设置不同的音量级别(例如,内部声音静音,耳机为75%)吗?

<coling>(在某些硬件上)将支持此功能。时标为“ soonish”:p
<coling>(我也希望在插入/拔出插孔时显示OSD(具有当前音量))

更新11.10

现在,这应该可以在Oneiric工作 -不幸的是,我的ThinkPad T510似乎是当前不支持的系统之一。

David Henningsson的另一跟进:

长话短说,这是一个理想的功能,我们正朝着这个方向发展,但步伐缓慢,因为该功能比乍看起来看上去要复杂得多。

好消息:在即将发布的Ubuntu Oneiric(11.10)中,这实际上是有效的。坏消息:它并不适合所有人。

这里更多。

更新为12.04

现在可以在Ubuntu 12.04(开发版)中使用我的ThinkPad T510(和许多其他型号)。


是否有任何跟踪当前支持哪种硬件的信息?
Mu Mind '10


2

我不知道您有多少编码经验,但是您提到了,inotifywait因此我将假设您至少对Shell脚本感到满意。基于本文的以下C程序应该能够检测到您的耳机已插入或拔出,​​然后您可以执行所需的任何操作。

#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;
}

该程序采用一个参数,该参数应该是耳机输入事件设备的路径。这是/dev/input/event7给我的,但是您可能必须尝试一些才能找到它在系统上的位置。您将需要该设备上的读取权限。程序将在退出前打印设备的名称以及第一个事件的类型,代码和值。


不幸的是,所有事件*均未与我的耳机连接。无论如何,+ 1 –也许对其他用户有帮助。
htorque 2011年

+1,工作对我来说,event.value的确是切换......但read操作只返回的价值的变化...也许你知道如何使它不堵?不管怎么说,还是要谢谢你!
凯文

O_NONBLOCK在打开设备时添加,并检查的返回值read。如果为负,则读取可能被阻止,或者发生了其他错误。如果将其合并到较大的程序中,则还有其他更复杂的方法无需轮询即可执行。
Karl Bielefeldt

1

检查dmesg和其他日志文件。可能插拔会触发某些特定消息。

然后,您可以使用守护程序来解析该日志文件并检测事件。我想您知道从现在开始该怎么做:)


1

如果你这样做

amixer sset 'Speaker' playback 0%

扬声器的音量将被静音,但耳机将继续工作。拔下耳机插头表示没有声音。几乎是您想要的...

但是 ...

如果更改音量控制,将再次设置“扬声器”的音量设置。这是因为pulseaudio会尝试聪明地设置音量(有关更多信息,请参见http://pulseaudio.org/wiki/PulseAudioStoleMyVolumes)。不过,我们可以阻止它弄乱卷。

打开/etc/pulse/default.pa

并找到线

load-module module-udev-detect

并将其更改为

load-module module-udev-detect ignore_dB=1

重新启动pulseaudio。

killall pulseaudio

现在,如果您将扬声器音量设为静音,则更改主音量将不会对其产生影响。因此耳机可以工作,但扬声器将保持静音。


将会是另一种方法,但是不幸的是,我没有扬声器音量通道,只有Master和PCM。
htorque 2011年

1

检查ACPID套接字是否有更改,可以在python或C或shell脚本的帮助下完成(用于控制耳机插件在节奏盒上播放和暂停的Python代码)。检查ACPID电压的变化,以检测耳机插件和耳机插头是否拔出。但是可以预期会有几秒钟的延迟。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.