Frage Wie mache ich eine Maschine für einen bestimmten Zeitraum (als Strafe) "leerer Bildschirm", wenn bestimmte Geräuschpegel erreicht werden?


Meine Kinder (4 und 5) schreien viel, wenn sie Computerspiele spielen. Ich habe dafür eine wirksame Heilung gefunden. Wenn ich laute Geräusche höre, schiebe ich mich in den Spielecomputer und mache:

chvt 3;  sleep 15;  chvt 7 

Dadurch wird der Bildschirm für 15 Sekunden unter Linux 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 ruhiger, aber nicht auf dem Niveau, auf dem ich glücklich wäre, und deshalb muss ich diesen Bildungsprozess fortsetzen. Ich bin aber nicht immer dazu da, um das manuell zu machen.

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


1526
2018-02-01 17:14


Ursprung


Bis sie lernen, STRG + ALT + F7 zu drücken - Suici Doga


Antworten:


Benutzen sox von SoX um ein kurzes Audio-Sample zu analysieren:

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

Mit -t .wav wir spezifizieren wir verarbeiten den wav typ, "|arecord -d 2" führt das aus arecord   Programm für zwei Sekunden, -n Ausgaben in die Nulldatei und mit stat wir spezifizieren, wir wollen Statistiken.

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 grep für die Linie, die wir wollen, verwenden tr um die Leerzeichen wegzuschneiden und dann cut es von der : Charakter und nimm den zweiten Teil, der uns gibt 0.068383 in diesem Beispiel. Wie von Kommentaren vorgeschlagen, RMS ist ein besseres Maß für Energie als maximale Amplitude.

Sie können endlich verwenden bc auf das Ergebnis, um Fließkommawerte von der Befehlszeile zu vergleichen:

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

Wenn Sie eine Schleife erstellen (siehe Bash-Beispiele) das anruft Schlaf für 1 Minute, testet die Lautstärke, und dann wiederholt, können Sie es im Hintergrund laufen lassen. Der letzte Schritt besteht darin, es den Init-Skripten oder -Dienstdateien hinzuzufügen (abhängig von Ihrem Betriebssystem / Distribution), so dass Sie es nicht einmal manuell starten müssen.


637
2018-02-01 17:36



Ich würde es nicht empfehlen, die maximale Amplitude zu nehmen. Es ist nicht nett für die Kinder, wenn ihr Bildschirm leer wird, nur weil jemand geklatscht hat oder ähnliches. Durchschnitt scheint passender. - orlp
Nur eine Klarstellung, mit "Durchschnitt" meinst du RMS Amplitude richtig? Die mittlere Amplitude wird nahe bei 0 liegen, wenn das Geräusch über die 2 Sekunden eine konsistente Lautstärke aufweist (die positiven und negativen Hälften heben sich gegenseitig auf). - Luke
Ein einfacher "Energie" -Detektor für eine Reihe von Proben besteht darin, einfach den Wert aller Peaks zusammenzufassen. Sie müssten es nicht einmal durchschnittlich machen, wenn Sie nicht wollten. Ein Peak ist nur ein beliebiger Punkt sample[n]>sample[n-1]&&sample[n]>sample[n+1] Ich habe das als einen rudimentären Mechanismus benutzt, um die Energie eines Liedes zu messen, und es funktioniert ganz gut. Suchen Sie einfach nach einer magischen Zahl, bei der Sie mit der Lautstärke zufrieden sind. - Kaslai
Ich würde gerne eine Beispielausgabe von Ihrem ersten Befehl sehen, wenn es wirklich zu einem Kind kommt, als Referenz. - Alvin Wong
Für die beschriebene Verwendung (automatisch starten + alle paar Minuten ausführen) ist ein Cron-Job das richtige Werkzeug. Viel einfacher zu installieren und robuster als die Verwendung von init script + bash loop + sleep. - m000


Hier ist, wie es gemacht werden kann Reine Daten:

Kid yell prevention using 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 durchgebrannt ist, "pd dsp 1" schaltet ihn ein. "shell" führt den übergebenen Befehl in einer Shell aus. Ich benutze die Linux xrandr API, um die Helligkeit auf X zu setzen. Sie müssen dies für Wayland anpassen.

Wie Sie sehen können, benötigen Kulanzzeitraum und Sperren viel mehr Speicherplatz als der Audiocode.

Eine Lösung mit Ringpuffern und / oder gleitenden Durchschnitten sollte viel einfacher sein als mit sox. Daher denke ich, dass es keine schlechte Idee ist, Pure Data dafür zu verwenden. Aber das Screen-Blanking selbst und das Locking passt nicht zum Datenfluss-Paradigma.

Die PD-Datei ist um gist.github.com: ysangkok - kidsyell.pd.


126
2018-02-05 16:20



Sehr schön! Mit dieser Technik können Sie die Reaktionszeit so anpassen, dass Sie den durchschnittlichen Schallpegel über eine Minute verfolgen und dann als Basis verwenden, sodass die Kinder, wenn sie über 20 dB über der Grundlinie liegen, auslösen. Dann passt es sich automatisch an den Umgebungsgeräuschpegel an. - Hans-Christoph Steiner
Ja, das macht Sinn @ Hans-ChristophSteiner. Aber würde der Umgebungsgeräuschpegel tatsächlich die Kinder nicht dazu zwingen, lauter zu schreien, da sie einen geringeren Anteil des Gesamtlärms ausmachen würden? Das würde natürlich nur gelten, wenn das vorhandene Rauschen weiß oder pink ist oder sonst ignoriert wird. - Janus Troelsen
wenn es leiser als sonst war, wie ein Wochenendmorgen, dann würde es es empfindlicher machen, da es immer 20 dB über dem Umgebungsniveau liegen würde - 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 irgendwelche pd-erweiterten spezifischen Konstrukte verwendet habe. - Janus Troelsen


Prüfen "Wie man das Vorhandensein von Sound / Audio erkennt" von Thomer M. Gil.

Im Grunde nimmt es den Ton alle 5 Sekunden auf, dann prüft er die Tonamplitude mit soxund entscheidet, ob ein Skript ausgelöst wird oder nicht. Ich denke du kannst das leicht anpassen ruby Skript für Ihre Kinder! Oder Sie können sich dafür entscheiden, das von ihm bereitgestellte Python-Skript (mit PyAudio) zu hacken.


100
2018-02-01 17:32



Was ist mit diesen Ausbrüchen in weniger als 5 Sekunden, die eine Entdeckung verhindern? - RhysW


Sie können Informationen vom Mikrofon abrufen, indem Sie Folgendes tun:

arecord -d1 /dev/null -vvv

Möglicherweise müssen Sie mit den Einstellungen ein wenig spielen, zum Beispiel:

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

Von da an ist es eine einfache Angelegenheit, die Ausgabe zu analysieren.


52
2018-02-01 17:28





Das ist eine der spaßigeren Fragen, die ich gesehen habe. Ich würde gerne ... danken Tucuxi  für so eine feine Antwort; Das habe ich als Bash-Skript festgelegt

#!/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
2018-02-08 14:10



Wenn du das startest, indem du eine Zeile zu /etc/rc4.d/S99rc.local hinzufügst und dann das Eingangsmikrofon von unverstärkt auf 100% änderst, kannst du auch zu tty3 übergeworfen werden (du kannst zurück springen, bevor der Sleep ist mit Strg + Alt + F7), und wenn Ihre Tastatur zu laut ist, um ein Terminal zu öffnen, sudo killall too_loud und dann Strg + Alt + F1 ausführen und sich dort anmelden.) - Alexx Roche


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 Audio-Handling-Bibliothek von Linux) und verwenden Sie einige numerische Technik (zum Beispiel die Berechnung der durchschnittlichen Schallpegel pro Sekunde), um das Niveau des Lärms 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 das verwenden X11-Bibliothek um den Bildschirm für einige Sekunden auszuschalten, oder alternativ (weniger elegant, aber es funktioniert) rufen Sie die chvt Befehl verwenden system("chvt 3; sleep 15; chvt 7 ");.


41
2018-02-01 17:32



Wenn ich den Befehl verwende, würde ich etwas anderes betrachten chvt. ArchWiki hat schöne Beispiele. - A.D.