特定のノイズレベルに達した場合、一定期間(ペナルティとして)マシンを「ブランクスクリーン」にする方法を教えてください。


1550

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

chvt 3;  sleep 15;  chvt 7 

これにより、Linuxで画面が15秒間オフになります。コンピューターは大きな音が嫌いだと言った。彼らはこれを完全に信じており、コンピューターに許しを請う。彼らはもっと静かになりましたが、私が幸せになるほどで​​はないので、この教育プロセスを続ける必要があります。ただし、これを手動で行うとは限りません。

これを自動化することは可能ですか?マイクがボックスに取り付けられています。ラウドネスのレベルがしきい値を超えた場合、コマンドを実行します。


3
CTRL + ALT + F7を押すことを学ぶまで
Suici Doga

1
@SuiciDogaちょっと; 彼らは何が起こっているのか分からない!
-wizzwizz4

技術的な解決策をおめでとうございます。しかし、私は子供たちに常に真実を言うことが重要だと思います。
ペテル

回答:


646

SoXから使用soxして、短い音声サンプルを分析します。

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) )) ; # ... 

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


282
最大振幅を取ることはお勧めしません。誰かが拍手したり、似たようなことをしたからといって画面が真っ白になると、子供たちには良くありません。平均がより適切だと思われます。
orlp

34
単なる説明ですが、「平均」とは、RMS振幅を意味しますか?ノイズが2秒間一貫したラウドネスである場合、平均振幅は0に近くなります(正と負の半分が互いに相殺されます)。
ルーク

6
一連のサンプルの単純な「エネルギー」検出器は、すべてのピークの値を加算するだけです。あなたがしたくないなら、あなたはそれを平均する必要さえありません。ピークはsample[n]>sample[n-1]&&sample[n]>sample[n+1]、歌のエネルギーを測定するための基本的なメカニズムとしてこれを使用した任意のポイントであり、非常にうまく機能します。ボリュームレベルに満足しているマジックナンバーを検索するだけです。
カスライ

3
参考のために、実際に子供が叫んでいるときに最初のコマンドのサンプル出力を見たいと思います。
アルビンウォン

3
説明されている使用方法(自動起動+数分ごとに実行)では、cronジョブを使用するのが適切なツールです。初期化スクリプト+ bashループ+スリープを使用するよりも、セットアップがはるかに簡単で堅牢です。
m000

131

Pure Dataを使用してそれを行う方法は次のとおりです。

Pure Dataを使用した子供の怒鳴り防止

メトロはメトロノームであり、「メトロ100」は100ミリ秒ごとに鳴り続けます。

オーディオはadc〜から来ており、ボリュームはenv〜によって計算されます。「pd dsp 0」は叩いたときにDSPをオフにし、「pd dsp 1」はオンにします。「shell」は渡されたコマンドをシェルで実行します。Linuxxrandr APIを使用して明るさをXに設定します。これをWaylandに適応させる必要があります。

ご覧のとおり、猶予期間とロックには、オーディオコードよりも多くのスペースが必要です。

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

PDファイルがであるkidsyell.pd - ysangkok:gist.github.com


11
非常に素晴らしい!この手法を使用して、これを非常に応答性の高いものにすることができます。1分間の平均サウンドレベルを追跡し、それをベースラインとして使用します。その後、周囲の音のレベルに自動的に調整されます。
ハンスクリストフシュタイナー

1
はい、それは@ Hans-ChristophSteinerの理にかなっています。しかし、ある意味では、周囲の騒音レベルは実際に子供たちが大声で叫ぶことを必要としないのでしょうか?もちろん、既存のノイズが白またはピンクの場合、または無視される場合にのみ適用されます。
ヤヌストロエルセン

4
それはいつもより静かだった場合、それは常に周囲レベル以上の20デシベルになるため、週末の朝のように、それは、それはより敏感になるだろう
ハンス・クリストフ・シュタイナー

これは拡張PDですか?
nullpotent

@iccthedral:pd-extendedを使用して作成しましたが、pd-extendedの特定のコンストラクトを使用したかどうかはわかりません。
ヤヌストロ

103

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

基本的に、5秒ごとにサウンドを記録し、を使用してサウンドの振幅をチェックし、soxスクリプトをトリガーするかどうかを決定します。rubyスクリプトを子供向けに簡単に調整できると思います!または、彼が提供したPythonスクリプト(PyAudioを使用)をハッキングすることもできます。


5
検出を回避する5秒未満の爆発についてはどうですか?
RhysW

53

次のようなことを行うことで、マイクから情報を取得できます。

arecord -d1 /dev/null -vvv

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

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

それ以降は、出力を解析するだけの簡単な問題です。


44

これは私が見た中で最も楽しい質問の一つです。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

7
/etc/rc4.d/S99rc.localに行を追加してこの実行を開始し、入力マイクを非増幅から100%に変更すると、最終的にtty3にスローされます(スリープする前に戻ることができます) Ctrl + Alt + F7)で終了し、キーボードが大きすぎて端末を開くことができない場合は、sudo killall too_loudを実行してからCtrl + Alt + F1を押してログインします。)
Alexx Roche

41

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

次に、無限ループでそれを確認し、プリセットのしきい値よりも大きい場合は、X11ライブラリを使用して画面を数秒間オフにするか、代わりに(エレガントではありませんが機能します)をchvt使用してコマンドを呼び出しsystem("chvt 3; sleep 15; chvt 7 ");ます。


2
コマンドを使用するなら、私はそれから異なるものを考えるでしょうchvtArchWikiには良い例があります。
西暦
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.