Wie mache ich einen Computer für einen bestimmten Zeitraum „leer“ (als Strafe), wenn bestimmte Geräuschpegel erreicht werden?

1550

Meine Kinder (4 und 5) schreien viel, wenn sie am Computer spielen. Ich habe ein wirksames Heilmittel dafür gefunden. Wenn ich laute Geräusche höre, schaue ich in den Spielcomputer und mache:

chvt 3;  sleep 15;  chvt 7 

Dadurch wird der Bildschirm unter Linux für 15 Sekunden ausgeschaltet. Ich habe ihnen gesagt, dass der Computer keine lauten Geräusche mag. Sie glauben das völlig und bitten den Computer um Vergebung. Sie wurden viel leiser, aber nicht auf dem Niveau, über das ich mich freuen würde, und deshalb muss ich diesen Bildungsprozess fortsetzen. Ich bin jedoch nicht immer da, um dies manuell zu tun.

Ist es möglich, dies zu automatisieren? Ein Mikrofon ist an der Box angebracht. Wenn der Lautstärkepegel eine Schwelle überschreitet, möchte ich einen Befehl ausführen.

Leonid Volnitsky
quelle
3
Bis sie lernen,
STRG
1
@ SuiciDoga Hey; Sie wissen nicht, was los ist!
wizzwizz4
Herzlichen Glückwunsch zu einer technischen Lösung. Aber ich denke, es ist wichtig, den Kindern immer die Wahrheit zu sagen.
30.

Antworten:

646

Verwenden soxvon SoX eine kurze Hörprobe zu analysieren:

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

Wenn -t .wavwir spezifizieren, verarbeiten wir den wav-Typ, führen "|arecord -d 2"das arecord Programm für zwei Sekunden aus, geben ihn -nin die Nulldatei aus und statgeben an, dass wir Statistiken wollen.

Die Ausgabe dieses Befehls auf meinem System mit etwas Hintergrundsprache ist:

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

Die maximale Amplitude kann dann extrahiert werden über:

grep -e "RMS.*amplitude" | tr -d ' ' | cut -d ':' -f 2

Wir grepfür die Zeile, die wir wollen, verwenden tr, um die Leerzeichen und dann cutdurch das :Zeichen abzuschneiden, und nehmen den zweiten Teil, der uns 0.068383in diesem Beispiel gibt. Wie aus den Kommentaren hervorgeht, ist der Effektivwert ein besseres Maß für die Energie als die maximale Amplitude.

Sie können bcdas Ergebnis schließlich zum Vergleichen von Gleitkommawerten über die Befehlszeile verwenden:

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

Wenn Sie eine Schleife erstellen (siehe Bash-Beispiele ), die Sleep für 1 Minute aufruft , die Lautstärke testet und dann wiederholt, können Sie sie im Hintergrund laufen lassen. Der letzte Schritt ist das Hinzufügen zu den Init-Skripten oder Servicedateien (abhängig von Ihrem Betriebssystem / Ihrer Distribution), sodass Sie sie nicht einmal manuell starten müssen.

Tucuxi
quelle
282
Ich würde es nicht empfehlen, die maximale Amplitude zu wählen. Es ist nicht schön für die Kinder, wenn der Bildschirm leer ist, nur weil jemand geklatscht hat oder so. Durchschnitt scheint angemessener.
Orlp
34
Nur eine Klarstellung, mit "Durchschnitt" meinen Sie RMS Amplitude, oder? Die mittlere Amplitude liegt nahe bei 0, wenn das Rauschen über 2 Sekunden hinweg eine konstante Lautstärke aufweist (die positive und die negative Hälfte heben sich gegenseitig auf).
Luke
6
Ein einfacher "Energie" -Detektor für eine Reihe von Proben besteht darin, den Wert aller Peaks zu addieren. Sie müssten es nicht einmal mitteln, wenn Sie es nicht wollten. Ein Peak ist genau ein Punkt, an dem sample[n]>sample[n-1]&&sample[n]>sample[n+1]ich ihn als rudimentären Mechanismus zum Messen der Energie eines Songs verwendet habe und der recht gut funktioniert. Suchen Sie einfach nach einer magischen Zahl, bei der Sie mit der Lautstärke zufrieden sind.
Kaslai
3
Ich würde gerne eine Beispielausgabe Ihres ersten Befehls sehen, wenn es wirklich darum geht, dass ein Kind schreit, als Referenz.
Alvin Wong
3
Für die beschriebene Verwendung (automatisch starten + alle paar Minuten ausführen) ist ein Cron-Job das richtige Werkzeug. Viel einfacher einzurichten und robuster als die Verwendung von Init-Skript + Bash-Schleife + Sleep.
M000
131

Mit Pure Data geht das so :

Schreiprävention mit Pure Data

Metro ist ein Metronom und "Metro 100" schlägt alle 100 ms.

Der Ton kommt von adc ~, die Lautstärke wird von env ~ berechnet. "pd dsp 0" schaltet den DSP aus, wenn er angeschlagen ist, "pd dsp 1" schaltet ihn ein. "shell" führt den übergebenen Befehl in einer Shell aus. Ich verwende die Linux-xrandr-API, um die Helligkeit auf X zu setzen. Sie müssen dies für Wayland anpassen.

Wie Sie sehen können, beansprucht die Nachfrist und das Sperren viel mehr Platz als der Audio-Code.

Eine Lösung mit Ringpuffern und / oder gleitenden Durchschnitten zu erstellen, sollte viel einfacher sein als dies zu tun sox. Daher halte ich es nicht für eine schlechte Idee, Pure Data dafür zu verwenden. Die Bildschirmausblendung selbst und die Sperrung passen jedoch nicht zum Datenfluss-Paradigma.

Die PD-Datei finden Sie unter gist.github.com: ysangkok - kidsyell.pd .

Janus Troelsen
quelle
11
Sehr schön! Mit dieser Technik können Sie die Reaktion deutlich verbessern: Verfolgen Sie den durchschnittlichen Schallpegel über eine Minute und verwenden Sie ihn dann als Basis, damit er ausgelöst wird, wenn die Kinder mehr als 20 dB über der Basislinie liegen. Dann passt es sich automatisch an den Umgebungsgeräuschpegel an.
Hans-Christoph Steiner
1
Ja, das macht Sinn @ Hans-ChristophSteiner. Aber in gewisser Weise, würde der Umgebungslärmpegel nicht tatsächlich erfordern, dass die Kinder lauter schreien, da sie einen geringeren Anteil am Gesamtlärm haben würden? Das würde natürlich nur zutreffen, wenn das vorhandene Rauschen weiß oder rosa ist oder auf andere Weise ignoriert wird.
Janus Troelsen
4
Wäre es leiser als sonst, wie an einem Wochenendmorgen, würde es empfindlicher, da es immer 20 dB über dem Umgebungspegel wäre
Hans-Christoph Steiner
Dies ist die erweiterte PD?
nullpotent
@iccthedral: Ich habe pd-extended verwendet, um es zu erstellen, aber ich weiß nicht, ob ich pd-extended-spezifische Konstrukte verwendet habe.
Janus Troelsen
103

Überprüfen Sie "Erkennen von Ton / Audio" von Thomer M. Gil .

Grundsätzlich zeichnet es den Ton alle 5 Sekunden auf, prüft dann anhand der Tonamplitude soxund entscheidet, ob ein Skript ausgelöst wird oder nicht. Ich denke , man kann leicht die Anpassung rubySkript für Ihre Kinder! Sie können auch das von ihm bereitgestellte Python-Skript (mit PyAudio) hacken.

Atropo
quelle
5
Was ist mit den Ausbrüchen, die weniger als 5 Sekunden dauern und die Erkennung verhindern?
RhysW
53

Sie können Informationen vom Mikrofon abrufen, indem Sie folgende Aktionen ausführen:

arecord -d1 /dev/null -vvv

Möglicherweise müssen Sie ein wenig mit den Einstellungen spielen, z. B .:

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

Von da an ist es einfach, die Ausgabe zu analysieren.

cha0site
quelle
44

Dies ist eine der spaßigeren Fragen, die ich gesehen habe. Ich möchte mich bei tucuxi für eine so gute antwort bedanken ; das habe ich als bash script gesetzt

#!/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
Alexx Roche
quelle
7
Wenn Sie dies starten, indem Sie eine Zeile zu /etc/rc4.d/S99rc.local hinzufügen und dann das Eingangsmikrofon von unverstärkt auf 100% ändern, werden Sie möglicherweise ebenfalls auf tty3 versetzt (Sie können zurückspringen, bevor der Ruhezustand beendet ist) mit Strg + Alt + F7) und wenn Ihre Tastatur zu laut ist, um ein Terminal zu öffnen, um sudo killall too_loud auszuführen, dann Strg + Alt + F1 und melden Sie sich dort an.)
Alexx Roche
41

Meine 2 Cent für die C- oder C ++ - Lösung: Vielleicht nicht der effektivste Ansatz, aber unter Linux können Sie die ALSA-API (integrierte Audiobearbeitungsbibliothek von Linux) verwenden und einige numerische Techniken anwenden (zum Beispiel die Berechnung des durchschnittlichen Klangs) Pegel jede Sekunde), um den Geräuschpegel zu erhalten.

Dann können Sie es in einer Endlosschleife überprüfen und, wenn es größer als ein voreingestellter Schwellenwert ist, können Sie die X11-Bibliothek verwenden , um den Bildschirm für einige Sekunden auszuschalten, oder alternativ (weniger elegant, aber es funktioniert) den chvtBefehl mit aufrufen system("chvt 3; sleep 15; chvt 7 ");.

H2CO3
quelle
2
Wenn ich einen Befehl benutze, würde ich dann etwas anderes in Betracht ziehen chvt. ArchWiki hat schöne Beispiele.
AD