当噪音达到一定水平时,如何让机器在一段时间内“黑屏”(作为惩罚)?

当噪音达到一定水平时,如何让机器在一段时间内“黑屏”(作为惩罚)?

我的孩子(4 岁和 5 岁)在玩电脑游戏时经常大喊大叫。我找到了一种有效的解决方法。当我听到很大的噪音时,我会 ssh 进入游戏电脑并执行以下操作:

chvt 3;  sleep 15;  chvt 7 

这将在 Linux 上关闭屏幕 15 秒。我告诉他们,计算机不喜欢大声的噪音。他们完全相信这一点,并乞求计算机原谅。他们变得安静多了,但还没有达到我满意的程度,所以我需要继续这个教育过程。然而,我并不总是能手动完成这件事。

可以自动执行吗?盒子上装有麦克风。如果音量超过某个阈值,那么我想运行一个命令。

答案1

使用sox索克斯分析一段简短的音频样本:

sox -t .wav "|arecord -d 2" -n stat

我们-t .wav指定处理的 wav 类型,"|arecord -d 2"执行arecord 程序两秒钟,-n输出到空文件并stat指定我们想要的统计数据。

在我的系统上,这个命令的输出带有一些背景语音,如下所示:

Recording WAVE 'stdin' : Unsigned 8 bit, Rate 8000 Hz, Mono
Samples read:             16000
Length (seconds):      2.000000
Scaled by:         2147483647.0
Maximum amplitude:     0.312500
Minimum amplitude:    -0.421875
Midline amplitude:    -0.054688
Mean    norm:          0.046831
Mean    amplitude:    -0.000044
RMS     amplitude:     0.068383
Maximum delta:         0.414063
Minimum delta:         0.000000
Mean    delta:         0.021912
RMS     delta:         0.036752
Rough   frequency:          684
Volume adjustment:        2.370

然后可以通过以下方式提取最大振幅:

grep -e "RMS.*amplitude" | tr -d ' ' | cut -d ':' -f 2

我们grep对于我们想要的线,使用tr修剪掉空格字符,然后cut它按:字符并取第二部分,即0.068383本例中给出的部分。正如评论所建议的那样,有效值是比最大振幅更好的能量测量方法。

您最终可以使用bc在结果上从命令行比较浮点值:

if (( $(echo "$value > $threshold" | bc -l) )) ; # ... 

如果你建立一个循环(参见Bash 示例)调用睡觉1 分钟,测试音量,然后重复,您可以让它在后台运行。最后一步是将其添加到 init 脚本或服务文件中(取决于您的操作系统/发行版),这样您甚至不必手动启动它。

答案2

以下是如何做到这一点纯数据

使用 Pure Data 预防儿童大喊大叫

地铁是一个节拍器,“metro 100”每 100 毫秒就会响一次。

音频来自 adc~,音量由 env~ 计算。“pd dsp 0”在敲击时关闭 DSP,“pd dsp 1”将其打开。“shell”在 shell 中执行传递的命令,我使用 Linux xrandr API 将亮度设置为 X,您需要为 Wayland 调整这一点。

如您所见,宽限期和锁定比音频代码占用更多的空间。

使用环形缓冲区和/或移动平均线来制作解决方案应该比使用 容易得多sox。所以我认为使用 Pure Data 来做这件事并不是一个坏主意。但屏幕消隐本身和锁定并不符合数据流范式。

PD 文件位于gist.github.com: ysangkok - kidsyell.pd

答案3

查看Thomer M. Gil 撰写的“如何检测声音/音频的存在”

基本上,它每 5 秒记录一次声音,然后使用 检查声音幅度,sox并决定是否触发脚本。我认为您可以轻松地ruby为您的孩子改编脚本!或者您也可以选择破解他提供的 Python 脚本(使用 PyAudio)。

答案4

这是我见过的最有趣的问题之一。我想感谢土库西 如此好的答案;我已经将其设置为 bash 脚本

#!/bin/bash

threshold=0.001
# we should check that sox and arecord are installed
if [ $1 ]; then threshold=$1; fi
while [ 1 -gt 0 ]; do
 if(( $(echo "$(sox -t .wav '|arecord -d 2' -n stat 2>&1|grep -e 'RMS.*amplitude'|tr -d ' '|cut -d ':' -f 2 ) > $threshold"|bc -l) ))
 then
  chvt 3; sleep 5; chvt 7;
 fi
done

相关内容