我的孩子(4岁和5岁)在计算机上玩游戏时大喊大叫。我找到了有效的解决方法。当我听到很大的声音时,我便进入游戏计算机并执行以下操作:

chvt 3;  sleep 15;  chvt 7 


这将在Linux上关闭屏幕15秒钟。我告诉他们,计算机不喜欢吵闹的声音。他们完全相信这一点,并乞求计算机的宽恕。他们变得安静了许多,但没有达到我满意的程度,因此我需要继续进行这一教育过程。但是,我并不总是手动执行此操作。

可以自动化吗?麦克风已连接到盒子。如果响度级别超过某个阈值,那么我要运行命令。

评论

直到他们学会按CTRL + ALT + F7

@SuiciDoga嘿;他们不知道发生了什么!

恭喜您获得技术解决方案。但我认为,务必始终向孩子们讲真话。

#1 楼

使用SoX中的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。正如评论所建议的那样,RMS比最大幅度是更好的能量度量。

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

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


如果构建一个循环(请参阅Bash示例),该循环调用sleep 1分钟,测试音量,然后重复,您可以使其在后台运行。最后一步是将其添加到初始化脚本或服务文件(取决于您的OS /发行版),这样您甚至不必手动启动它。

评论


我不建议采用最大振幅。当孩子们的屏幕变黑只是因为有人鼓掌或类似的东西时,这对于孩子们来说并不好。平均似乎更合适。

–orlp
13年2月1日在17:59

只是澄清一下,用“平均”表示RMS幅度正确吗?如果噪声在2秒钟内保持一致的响度,则平均幅度将接近0(正负两半将相互抵消)。

–卢克
13年2月2日在20:10

一个用于一系列样本的简单“能量”检测器就是将所有峰的值加在一起。如果您不想,则不必平均。峰值只是sample [n]> sample [n-1] && sample [n]> sample [n + 1]的任何点,我已经将其用作测量歌曲能量的基本机制,并且效果很好。只需搜索一个令您满意的音量数字即可。

–卡斯莱
13年2月3日,下午1:45

我想看到您的第一个命令的示例输出,它确实涉及到孩子大喊大叫,以供参考。

–黄永Al
13年2月3日,11:39

对于所描述的用法(自动启动+每隔几分钟运行),cron作业是使用的正确工具。与使用初始化脚本+ bash循环+睡眠相比,它更容易设置且更可靠。

–m000
13年3月24日在14:08

#2 楼

使用Pure Data的方法如下:



节拍器是节拍器,“ metro 100”持续每100 ms敲打一次。

音频来自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。

评论


非常好!您可以使用此技术使其响应迅速:跟踪一分钟的平均声音水平,然后将其用作基线,以便当孩子超过基线20 dB以上时触发。然后它将自动调整为环境声音级别。

– Hans-Christoph Steiner
13年5月5日在16:33

是的,@ Hans-ChristophSteiner很有意义。但是,从某种意义上说,环境噪声水平是否真的不要求孩子大声喊叫,因为他们占总噪声的比例较小?当然,这仅在现有噪声为白色或粉红色或以其他方式忽略时适用。

– Janus Troelsen
13年5月5日在16:40

如果它比平时安静(如周末早晨),则它将使其更加灵敏,因为它总是比环境水平高20 dB

– Hans-Christoph Steiner
2013年2月5日在16:42



这是扩展PD吗?

–无能
13年2月9日在15:09

@iccthedral:我使用了pd-extended来制作它,但是我不知道是否使用了任何pd-extended的特定构造。

– Janus Troelsen
13年2月10日在12:56

#3 楼

选中Thomer M. Gil的“如何检测声音/音频的存在”。

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

评论


那些不到5秒就避免检测的爆发怎么办?

– RhysW
13年2月4日在10:13

#4 楼

您可以通过执行以下操作从麦克风获取信息:

arecord -d1 /dev/null -vvv


您可能需要稍微进行一些设置,例如:

arecord -d1 -Dhw:0 -c2 -fS16_LE /dev/null -vvv


从那里开始,只需解析输出即可。

#5 楼

这是我所看到的更有趣的问题之一。我要感谢tucuxi
这样好的回答;我已将其设置为bash脚本

#!/bin/bash

threshold=0.001
# we should check that sox and arecord are installed
if [  ]; then threshold=; 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


评论


如果您通过在/etc/rc4.d/S99rc.local中添加一行来开始运行,然后将输入麦克风从未放大更改为100%,那么您最终也可能会被扔到tty3(可以在睡眠之前跳回去) (Ctrl + Alt + F7),如果您的键盘太大而无法打开终端,请运行sudo killall too_loud,然后按Ctrl + Alt + F1并在那里登录。)

– Alexx Roche
13年2月10日在12:45

#6 楼

我花2美分购买C或C ++解决方案:也许不是最有效的方法,但是在Linux上,您可以使用ALSA API(Linux的内置音频处理库)并使用某种数值技术(例如,计算平均声音)

然后可以无限循环检查它,如果它大于预设的阈值,则可以使用X11库关闭屏幕几秒钟或更短的时间(虽然不太优雅,但可以工作)使用chvt调用system("chvt 3; sleep 15; chvt 7 ");命令。

评论


如果使用命令我会考虑不同的东西然后chvt。 ArchWiki有很好的例子。

– A.D.
13年2月5日在13:20