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

audio linux parental-controls shell

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

chvt 3;  sleep 15;  chvt 7

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

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

  1560  Leonid Volnitsky  2013-02-01


ベストアンサー

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を与える第二の部分を取ります。コメントで示唆されているように、RMSは最大振幅よりもエネルギーを測るのに適しています

ようやく結果にbcを使ってコマンドラインから浮動小数点値の比較ができるようになりました

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

sleep を 1 分間呼び出し、音量をテストし、それを繰り返すループ(バッシュの例を参照)を構築すれば、バックグラウンドで動作させたままにすることができます。最後のステップは、手動で起動する必要がないように、initスクリプトやサービスファイルに追加することです(お使いのOS / distroに依存します)

650  tucuxi  2013-02-01


ピュアデータでできることを説明します

Kid yell prevention using Pure Data

メトロはメトロノームで、”metro 100 “は100msごとに叩き続けます

オーディオはadc~から来ていて、音量はenv~で計算されています。”pd dsp 0″ は叩いた時にDSPをオフにし、”pd dsp 1″ はオンにします。”shell “は渡されたコマンドをシェルで実行します。Linuxのxrandr APIを使って明るさをXに設定していますが、これをWaylandに合わせる必要があります

ご覧のように、猶予期間とロックはオーディオコードよりもはるかに多くのスペースを占有しています

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

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

136  Janus Troelsen  2013-02-05


“音/音声の存在を検出する方法 “をチェックする Thomer M. Gil

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

106  Atropo  2013-02-01


みたいなことをすることで、マイクから情報を得ることができます

arecord -d1 /dev/null -vvv

など、少し設定をいじる必要があるかもしれません

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

そこから先は、出力を解析するだけの簡単な作業です

56  cha0site  2013-02-01


これは私が見てきた中で最も楽しい質問の一つです。私はこのような細かい回答のための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

48  Alexx Roche  2013-02-08


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

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

44  H2CO3  2013-02-01


タイトルとURLをコピーしました