![检测何时仅播放静音](https://linux22.com/image/115649/%E6%A3%80%E6%B5%8B%E4%BD%95%E6%97%B6%E4%BB%85%E6%92%AD%E6%94%BE%E9%9D%99%E9%9F%B3.png)
我的电脑已连接到音频放大器,我可以通过网络打开或关闭该音频放大器。我想将其设置为在 10 分钟没有播放任何音频后自动关闭。
我在这里发现了一些类似的问题,建议查看/proc/asound/card*/pcm*/sub*/status
是否有指示正在输出音频的单词RUNNING
,但是许多程序似乎让音频运行,即使它们没有发出任何噪音,只是输出静音。我注意到一些 Python 程序会这样做,就像 Firefox 在运行apulse
.
这意味着/proc/asound/
当扬声器没有发出音频时我无法检测到,因为它是永久的RUNNING
。
是否有另一种方法可以检测正在播放的唯一音频信号何时是静音?是否有某种方法可以记录或以其他方式拦截 ALSA 输出,即使hw
设备是正在使用的设备?
答案1
sox
这是仅使用 alsa(alsa 环回模块)并检测静音的概念验证演示。环回模块为您提供了一个输出设备,您可以在其中播放声音,然后从中录制回来。因此,例如,您可以直接mplayer
使用环回进行声音输出,然后运行sox
从环回录音,检测静音,然后输出到原始硬件输出设备。
加载模块
sudo modprobe snd-aloop
(它在我的可用内核模块列表中)。aplay -l
现在将列出一张带有 2 个设备的新卡。设备 0 用于播放,设备 1 用于录制。有 8 个独立的“子设备”通道,最容易使用数字 0,因为通常可以将其省略。 (我aplay
在包中找到alsa-utils
)。
$ aplay -l
...
card 1: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
...
Subdevice #7: subdevice #7
card 1: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
...
Subdevice #7: subdevice #7
现在,您可以使用包中的另一个实用程序在环回设备 0(子设备 0)中生成连续音调:
speaker-test -t sine -D hw:Loopback
或者例如告诉mplayer
使用带有选项的设备-ao alsa:device=hw=Loopback
您将不会听到任何声音,直到您还运行sox
让它读取设备的另一侧并将其写入真实硬件(假设这是卡 0):
sox -q -t alsa hw:Loopback,1 -t alsa hw:0 silence 0 1 10.0 2%
(我看到了很多警告sox 警告 alsa: 运行不足)。如果停止扬声器测试,10 秒静默后命令sox
将停止。请注意,如果您静音,mplayer
您会得到静音,但这似乎与数据级别无关(如果您删除 from ,您可以将其可视化-q
)sox
。您需要暂停或降低声音级别mplayer
才能检测到静音。sox
还可能会在音频中引入一两秒的延迟。您应该能够配置 alsa 以将 Loopback 设备设置为默认设备,而不是您的卡 0。
更令人满意的解决方案是让内核声音驱动程序处理实时音频,并sox
仅用于检测静音,丢弃其输出。这似乎是可能的,但仅使用 alsa 也有点复杂,需要我没有的知识,尽管您可以找到将声音复制到两个设备、您的原始声卡和一个可以sox
读取的虚拟设备的示例。
使用pulseaudio来启用的更简单的解决方案监控是可能的,pactl load-module module-combine-sink
我可能会用它来调查。