Question Comment puis-je créer un "écran blanc" de machine pour une période de temps (sous forme de pénalité) si certains niveaux de bruit sont atteints?


Mes enfants (4 et 5 ans) crient beaucoup en jouant à des jeux sur ordinateur. J'ai trouvé un remède efficace pour cela. Quand j'entends des bruits forts, je ssh dans l'ordinateur du jeu et fais:

chvt 3;  sleep 15;  chvt 7 

Cela éteindra l'écran pendant 15 secondes sous Linux. Je leur ai dit que l'ordinateur n'aimait pas les bruits forts. Ils y croient totalement et prient l'ordinateur pour son pardon. Ils sont devenus beaucoup plus silencieux, mais pas au niveau que je serais heureux, et je dois donc continuer ce processus éducatif. Cependant, je ne suis pas toujours là pour le faire manuellement.

Est-il possible d'automatiser cela? Un microphone est attaché à la boîte. Si le niveau sonore dépasse un certain seuil, je veux exécuter une commande.


1526
2018-02-01 17:14


origine


Jusqu'à ce qu'ils apprennent à appuyer sur CTRL + ALT + F7 - Suici Doga


Réponses:


Utilisation sox de SoX analyser un petit extrait audio:

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

Avec -t .wav nous spécifions que nous traitons le type wav, "|arecord -d 2" exécute le arecord   programme pendant deux secondes, -n sorties vers le fichier nul et avec stat nous précisons que nous voulons des statistiques.

La sortie de cette commande, sur mon système avec un discours en arrière-plan, est la suivante:

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

L'amplitude maximale peut alors être extraite via:

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

nous grep pour la ligne que nous voulons, utilisez tr pour rogner les caractères d'espace, puis cut par le : personnage et prendre la deuxième partie qui nous donne 0.068383 dans cet exemple. Comme suggéré par les commentaires, RMS est une meilleure mesure de l'énergie que l'amplitude maximale.

Vous pouvez enfin utiliser bc sur le résultat pour comparer les valeurs à virgule flottante à partir de la ligne de commande:

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

Si vous construisez une boucle (voir Exemples de Bash) qui appelle dormir pendant 1 minute, teste le volume, puis se répète, vous pouvez le laisser en arrière-plan. La dernière étape consiste à l'ajouter aux scripts d'initialisation ou aux fichiers de service (en fonction de votre système d'exploitation / distribution), de sorte que vous n'avez même pas à le lancer manuellement.


637
2018-02-01 17:36



Je recommanderais de prendre l'amplitude maximale. Ce n'est pas bien pour les enfants quand leur écran devient blanc parce que quelqu'un applaudit ou quelque chose de similaire. La moyenne semble plus appropriée. - orlp
Juste une précision, par "moyenne" vous voulez dire RMS Amplitude non? L'amplitude moyenne sera proche de 0 si le niveau sonore est constant sur les 2 secondes (les moitiés positive et négative s'annulent). - Luke
Un simple détecteur "d'énergie" pour une série d'échantillons consiste simplement à ajouter la valeur de tous les pics ensemble. Vous ne devriez même pas faire la moyenne si vous ne le vouliez pas. Un pic est juste n'importe où où sample[n]>sample[n-1]&&sample[n]>sample[n+1] Je l’ai utilisé comme mécanisme rudimentaire pour mesurer l’énergie d’une chanson et cela fonctionne assez bien. Recherchez simplement un nombre magique auquel vous êtes satisfait du niveau de volume. - Kaslai
J'aimerais voir un exemple de sortie de votre première commande quand il s'agit d'un enfant qui crie, pour référence. - Alvin Wong
Pour l'utilisation décrite (démarrer automatiquement + exécuter toutes les quelques minutes), un travail cron est le bon outil à utiliser. Beaucoup plus simple à installer et plus robuste que l'utilisation du script init + bash loop + sleep. - m000


Voici comment cela peut être fait avec Données pures:

Kid yell prevention using Pure Data

Métro est un métronome et "metro 100" continue à frapper toutes les 100 ms.

L'audio provient de adc ~, le volume est calculé par env ~. "pd dsp 0" désactive le DSP quand il est frappé, "pd dsp 1" l'allume. "shell" exécute la commande passée dans un shell, j'utilise l'API Linux xrandr pour définir la luminosité sur X, vous devez l'adapter pour Wayland.

Comme vous pouvez le constater, le délai de grâce et le verrouillage prennent beaucoup plus de place que le code audio.

Faire une solution avec des tampons annulaires et / ou des moyennes mobiles devrait être beaucoup plus facile que de le faire avec sox. Donc, je ne pense pas que ce soit une mauvaise idée d'utiliser Pure Data pour cela. Mais le masquage de l'écran et le verrouillage ne correspondent pas au paradigme de flux de données.

Le fichier PD est à gist.github.com: ysangkok - kidsyell.pd.


126
2018-02-05 16:20



très agréable! Vous pouvez faire en sorte que cette technique soit très réactive: suivez le niveau sonore moyen pendant une minute, puis utilisez-le comme base, de sorte que lorsque les enfants dépassent 20 dB au-dessus de la ligne de base, cela se déclenche. Ensuite, il s'ajustera automatiquement au niveau sonore ambiant. - Hans-Christoph Steiner
Oui, c'est logique @ Hans-ChristophSteiner. En un sens, le niveau de bruit ambiant ne nécessiterait-il pas que les enfants hurlent plus fort, car ils constitueraient une plus petite proportion du bruit global? Cela ne s'appliquerait bien sûr que si le bruit existant est blanc ou rose ou ignoré. - Janus Troelsen
si c'était plus calme que d'habitude, comme un week-end le matin, cela le rendrait plus sensible, car il serait toujours à 20 dB au-dessus du niveau ambiant - Hans-Christoph Steiner
Ceci est le PD étendu? - nullpotent
@ccthedral: j'ai utilisé pd-extended pour le faire, mais je ne sais pas si j'ai utilisé des constructions spécifiques au format pd. - Janus Troelsen


Vérifier "Comment détecter la présence de son / audio" par Thomer M. Gil.

Fondamentalement, il enregistre le son toutes les 5 secondes, que vérifie l'amplitude du son, en utilisant sox, et décide si déclencher un script ou non. Je pense que vous pouvez facilement adapter le ruby script pour vos enfants! Ou vous pouvez choisir de pirater le script Python (en utilisant PyAudio) qu'il a également fourni.


100
2018-02-01 17:32



Qu'en est-il des explosions de moins de 5 secondes qui évitent la détection? - RhysW


Vous pouvez obtenir des informations du microphone en faisant quelque chose comme:

arecord -d1 /dev/null -vvv

Vous devrez peut-être jouer un peu avec les paramètres, tels que:

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

À partir de là, il s'agit simplement d'analyser le résultat.


52
2018-02-01 17:28





C'est l'une des questions les plus amusantes que j'ai vues. Je tiens à remercier tucuxi  pour une si belle réponse; que j'ai défini comme un script 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

43
2018-02-08 14:10



Si vous commencez à cette course en ajoutant une ligne à /etc/rc4.d/S99rc.local puis changer le micro d'entrée de unamplified à 100%, vous pouvez finir par être trop jeté vers tty3 (vous pouvez revenir en arrière avant que le sommeil est over avec Ctrl + Alt + F7), et si votre clavier est trop fort pour ouvrir un terminal, lancez sudo killall too_loud puis Ctrl + Alt + F1 et connectez-vous. - Alexx Roche


Mes 2 centimes pour la solution C ou C ++: peut-être pas l'approche la plus efficace, mais sous Linux, vous pouvez utiliser le API ALSA (bibliothèque de gestion audio intégrée de Linux) et utiliser une technique numérique (par exemple, calculer le niveau sonore moyen chaque seconde) pour obtenir le niveau de bruit.

Ensuite, vous pouvez le vérifier dans une boucle infinie, et si elle est supérieure à un seuil prédéfini, vous pouvez utiliser le Bibliothèque X11 pour éteindre l'écran pendant quelques secondes, ou alternativement (moins élégant, mais ça marche) invoque le chvt commande en utilisant system("chvt 3; sleep 15; chvt 7 ");.


41
2018-02-01 17:32



Si vous utilisez la commande, je considérerais quelque chose de différent chvt. ArchWiki a de beaux exemples. - A.D.