2013-02-01 17:14:09 +0000 2013-02-01 17:14:09 +0000
1554

一定のノイズレベルに達した場合、機械を一定時間(ペナルティとして)「空白画面」にするにはどうすればいいですか?

うちの子供(4歳と5歳)がパソコンでゲームをするとよく怒鳴る。これに効果的な治療法を見つけました。大きな音が聞こえたら、ゲームコンピュータに ssh して、次のようにします。

chvt 3; sleep 15; chvt 7

これでLinuxでは15秒間画面が消えます。私はコンピュータが大きな音を好まないことを彼らに伝えました。彼らはこれを完全に信じて、コンピュータに許しを請う。彼らはずっと静かになったが、私が喜ぶレベルではないので、私はこの教育プロセスを継続する必要があります。しかし、私はいつも手動でこれを行うために周りにいるわけではありません。

これを自動化することは可能なのでしょうか?箱にマイクを付けています。ラウドネスのレベルがある閾値を超えたらコマンドを実行したいのですが、自動化は可能でしょうか?

回答 [6]

647
2013-02-01 17:36:38 +0000
sox -t .wav "|arecord -d 2" -n stat

soxではwavタイプを処理すると指定し、-t .wavでは "|arecord -d 2" プログラムを2秒間実行し、arecordではヌルファイルに出力し、-nでは統計を取ると指定しています。

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

目的の行に stat を使用してスペース文字を削除し、 grep tr 文字に置き換えて、この例では cut が得られる 2 番目の部分を取ります。コメントで示唆されているように、RMS は最大振幅よりもエネルギーの測定に適しています。 最後のステップは、手動で起動する必要がないように、initスクリプトやサービスファイルに追加することです (OS / distro に依存します)。

647
133
2013-02-05 16:20:11 +0000

Pure Data ](http://en.wikipedia.org/wiki/Pure_Data)を使うとこうなります。

Kid yell prevention using Pure Data

Metro はメトロノームで、"metro 100 "が100msごとに鳴り続けます。

音声はadc~から来ており、音量はenv~で計算されます。"pd dsp 0 "は叩くとDSPをオフにし、"pd dsp 1 "はオンにする。"shell" は、渡されたコマンドをシェルで実行します。

見ての通り、グレースピリオドとロックはオーディオコードよりもはるかに多くのスペースを占有しています。

リングバッファや移動平均を使ったソリューションを作るのは、soxでやるよりもずっと簡単なはずです。このためにPure Dataを使うのは悪い考えではないと思います。しかし、画面のブランキング自体とロックはデータフローのパラダイムには合わない。

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

133
104
2013-02-01 17:32:18 +0000

Check "How to detect the presence of sound/audio" by Thomer M. Gil .

基本的には5秒ごとに音を記録し、soxを使って音の振幅をチェックし、スクリプトを起動するかどうかを判断します。rubyのスクリプトは、あなたの子供のために簡単に適応させることができると思います。あるいは、彼が提供してくれたPythonスクリプト(PyAudioを使って)をハックすることもできます。

104
54
2013-02-01 17:28:44 +0000

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

arecord -d1 /dev/null -vvv

のようにすることで、マイクから情報を得ることができます。

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

ここからは、出力を解析するだけの簡単な問題です。

54
46
2013-02-08 14:10:44 +0000

これは私が見た中で最も楽しい質問の一つです。このような素晴らしい回答をしてくれた tucuxi に感謝したいと思います;

#!/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
``` をバッシュスクリプトとして設定しました。
46
42
2013-02-01 17:32:58 +0000

CまたはC++での解決策についての私の2セント: 最も効果的なアプローチではないかもしれませんが、Linuxでは ALSA API (Linuxの内蔵オーディオ処理ライブラリ)を使用して、ノイズのレベルを得るために数値的なテクニック(例えば、毎秒の平均音圧を計算する)を使用することができます。

その後、無限ループでチェックして、それがプリセットの閾値よりも大きければ、 X11ライブラリ を使って数秒間画面をオフにするか、代わりに(あまりエレガントではありませんが、動作します)chvtを使ってsystem("chvt 3; sleep 15; chvt 7 ");コマンドを呼び出すことができます。

42