web-dev-qa-db-ja.com

特定の騒音レベルに達した場合に、(ペナルティとして)一定期間にわたってマシンを「空白の画面」にするにはどうすればよいですか?

私の子供たち(4と5)は、コンピューターでゲームをするときに大声を出しました。私はこれに対する効果的な治療法を見つけました。大きな音が聞こえたら、ゲームコンピュータに向かってsshして、

chvt 3;  sleep 15;  chvt 7 

Linuxでは15秒間画面が消えます。私は彼らがコンピューターは大きな音が好きではないと言った。彼らはこれを完全に信じ、許しを求めてコンピュータに頼みます。彼らははるかに静かになりましたが、私が幸せになるほどのレベルではなかったので、この教育プロセスを続ける必要があります。しかし、私はこれを手動で行うことを常に避けているわけではありません。

これを自動化することは可能ですか?マイクが箱に取り付けられています。音量のレベルがあるしきい値を超えたら、コマンドを実行します。

1545

短いオーディオサンプルを分析するには、SoXsoxを使用します。

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

-t .wavを使用してwavタイプを処理するように指定し、"|arecord -d 2"arecord プログラムを2秒間実行し、-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を与える2番目の部分を取ります。コメントで示唆されているように、 RMS は最大振幅よりもエネルギーの優れた尺度です。

最後に bc を使用して、コマンドラインからの浮動小数点値を比較できます。

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

あなたが sleep を呼び出すループ( bashの例 を参照)を作るなら1分、ボリュームをテストしてから繰り返すと、バックグラウンドで実行したままにすることができます。最後のステップはそれをinitスクリプトやサービスファイルに追加することです(あなたのOS /ディストリビューションによって)、手動で起動する必要すらありません。

643
tucuxi

これが 純粋なデータ でどのようにできるかです:

Kid yell prevention using Pure Data

Metro はメトロノームで、 "metro 100"は100ミリ秒ごとに鳴り響きます。

音声はadc〜から来ていて、音量はenv〜によって計算されます。 「pd dsp 0」を押すとDSPがオフになり、「pd dsp 1」を押すとオンになります。 "Shell"はシェルで渡されたコマンドを実行します、私は明るさをXに設定するためにLinux xrandr APIを使います、あなたはWaylandのためにこれを適応させる必要があります。

ご覧のとおり、猶予期間とロックはオーディオコードよりも多くのスペースを占めます。

リングバッファや移動平均を使って解を作るのは、soxを使って解くのよりもずっと簡単なはずです。したがって、これにPure Dataを使用するのは悪い考えではないと思います。しかし、画面自体が空白になり、ロックがデータフローパラダイムに合いません。

PDファイルは Gist.github.com:ysangkok - kidsyell.pd にあります。

130
Janus Troelsen

Thomer M. Gilによる 「サウンド/オーディオの存在を検出する方法」を確認してください

基本的にsoxを使用して音の振幅をチェックするよりも5秒ごとに音を記録し、スクリプトをトリガーするかどうかを決定します。私はあなたがあなたの子供のためにRubyスクリプトを簡単に適応させることができると思います!あるいは、彼が提供したPythonスクリプト(PyAudioを使用)をハックすることもできます。

102
Atropo

マイクから情報を取得するには、次のようにします。

arecord -d1 /dev/null -vvv

次のような設定で少し遊ぶ必要があるかもしれません。

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

それ以降は、出力を解析するという簡単なことです。

53
cha0site

これは私が見た中でもっと楽しい質問の一つです。私はそのようなすばらしい答えに対して tucuxi に感謝します。 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
43
Alexx Roche

CまたはC++ソリューションに関する私の2セント:おそらく最も効果的なアプローチではありませんが、Linuxでは、 ALSA API (組み込みオーディオ)を使用できます。ノイズのレベルを取得するために(例えば、毎秒平均サウンドレベルを計算する)いくつかの数値手法を使用して(Linuxの処理ライブラリ)。

それから、無限ループでそれをチェックすることができます、そしてそれが事前設定されたしきい値より大きいなら、あなたはいくつかのためにスクリーンを消すために X11ライブラリ を使うことができます秒、あるいは(より洗練されていませんが、うまくいきます)system("chvt 3; sleep 15; chvt 7 ");を使用してchvtコマンドを呼び出します。

41
H2CO3