1570 votes

Comment faire en sorte qu'une machine soit "écran blanc" pendant un certain temps (à titre de pénalité) si certains niveaux de bruit sont atteints ?

Mes enfants (4 et 5 ans) crient beaucoup lorsqu'ils jouent à des jeux sur l'ordinateur. J'ai trouvé un remède efficace à ce problème. Lorsque j'entends des bruits forts, je me connecte à l'ordinateur de jeu et je fais :

chvt 3;  sleep 15;  chvt 7 

Cela éteindra l'écran pendant 15 secondes sous Linux. Je leur ai dit que l'ordinateur n'aime pas les bruits forts. Ils y croient totalement et supplient l'ordinateur de les pardonner. Ils sont devenus beaucoup plus silencieux, mais pas au point de me satisfaire, et je dois donc poursuivre ce processus éducatif. Cependant, je ne suis pas toujours là pour le faire manuellement.

Est-il possible d'automatiser cette opération ? Un microphone est fixé à la boîte. Si le niveau sonore dépasse un certain seuil, je veux lancer une commande.

6 votes

Jusqu'à ce qu'ils apprennent à appuyer sur CTRL + ALT + F7.

2 votes

@SuiciDoga Hey ; ils ne savent pas ce qui se passe !

3 votes

Félicitations pour la solution technique. Mais je pense qu'il est important de toujours dire la vérité aux enfants.

656voto

tucuxi Points 4513

Utilice sox de SoX pour analyser un court échantillon 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 pendant deux secondes, -n vers le fichier nul et avec stat nous spécifions que nous voulons des statistiques.

La sortie de cette commande, sur mon système avec un certain bruit de fond, 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 supprimer les caractères d'espacement, puis cut par le : 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 des 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 répète, vous pouvez le laisser tourner en arrière-plan. La dernière étape consiste à l'ajouter à l'init scripts ou aux fichiers de service (selon votre OS / distro), de sorte que vous ne devez même pas le lancer manuellement.

289 votes

Je vous déconseille de prendre l'amplitude maximale. Ce n'est pas agréable pour les enfants quand leur écran s'éteint juste parce que quelqu'un a applaudi ou quelque chose de similaire. La moyenne semble plus appropriée.

36 votes

Juste une précision, par "moyenne" vous voulez dire Amplitude RMS, n'est-ce pas ? L'amplitude moyenne sera proche de 0 si le bruit est d'une intensité constante pendant les 2 secondes (les moitiés positives et négatives s'annulent).

8 votes

Un simple détecteur d'"énergie" pour une série d'échantillons consiste à additionner la valeur de tous les pics. Il n'est même pas nécessaire de faire la moyenne si on ne le souhaite pas. Un pic est juste un point où sample[n]>sample[n-1]&&sample[n]>sample[n+1] Je l'ai utilisé comme un mécanisme rudimentaire pour mesurer l'énergie d'une chanson et cela fonctionne assez bien. Il suffit de chercher un chiffre magique auquel vous êtes satisfait du niveau de volume.

139voto

Janus Troelsen Points 2168

Voici comment procéder avec Pure Data :

Kid yell prevention using Pure Data

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

L'audio provient de l'adc~, le volume est calculé par env~. "pd dsp 0" désactive le DSP quand on le tape, "pd dsp 1" l'active. "Shell" exécute la commande passée dans un Shell, j'utilise l'API Linux xrandr pour régler la luminosité sur X, vous devez adapter cela 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.

Il devrait être beaucoup plus facile d'élaborer une solution avec des tampons en anneau et/ou des moyennes mobiles qu'avec sox . Je ne pense donc pas que ce soit une mauvaise idée d'utiliser Pure Data pour cela. Mais la suppression de l'écran elle-même et le verrouillage ne correspondent pas au paradigme du flux de données.

Le fichier PD se trouve à l'adresse suivante gist.github.com : ysangkok - kidsyell.pd .

12 votes

Très bien ! Vous pourriez le rendre assez réactif en utilisant cette technique : suivez le niveau sonore moyen sur une minute, puis utilisez-le comme ligne de base, de sorte que lorsque les enfants dépassent de 20 dB la ligne de base, il se déclenche. Ensuite, il s'adaptera automatiquement au niveau sonore ambiant.

2 votes

Oui, cela a du sens @Hans-ChristophSteiner. Mais d'une certaine manière, le niveau de bruit ambiant n'obligerait-il pas les enfants à crier plus fort, puisqu'ils représenteraient une plus petite proportion du bruit global ? Bien sûr, cela ne s'applique que si le bruit existant est blanc, rose ou ignoré.

4 votes

S'il était plus calme que d'habitude, comme un matin de week-end, il serait plus sensible, puisqu'il serait toujours 20 dB au-dessus du niveau ambiant.

108voto

Walter Points 37

Vérifiez "Comment détecter la présence d'un son/audio" par Thomer M. Gil .

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

7 votes

Et ces explosions de moins de 5 secondes qui échappent à la détection ?

56voto

cha0site Points 732

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, par exemple :

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

A partir de là, il s'agit simplement d'analyser la sortie.

49voto

Alex B Points 973

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 mis comme un bash script

#!/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

9 votes

Si vous le lancez en ajoutant une ligne à /etc/rc4.d/S99rc.local et que vous changez le micro d'entrée de non amplifié à 100%, vous pouvez vous aussi vous retrouver projeté sur tty3 (vous pouvez revenir en arrière avant la fin du sommeil avec Ctrl+Alt+F7), et si votre clavier est trop bruyant pour ouvrir un terminal, lancer sudo killall too_loud puis Ctrl+Alt+F1 et vous y connecter).

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X