2013-02-01 17:14:09 +0000 2013-02-01 17:14:09 +0000
1554
1554

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

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

chvt 3; sleep 15; chvt 7

Cela éteint l'écran pendant 15 secondes sous Linux. Je leur ai dit que l'ordinateur n'aime pas les bruits forts. Ils le croient totalement et supplient l'ordinateur de leur pardonner. Ils sont devenus beaucoup plus silencieux, mais pas au point que je sois heureux, et je dois donc poursuivre 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 alors lancer une commande.

Réponses (6)

647
647
647
2013-02-01 17:36:38 +0000

Utilisez 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 programme arecord pendant deux secondes, -n sort dans le fichier null et avec stat nous spécifions que nous voulons des statistiques.

La sortie de cette commande, sur mon système avec un peu de parole de fond, est :

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, utilisons tr pour supprimer les espaces et ensuite cut par le caractère : et prenons la deuxième partie qui nous donne 0.068383 dans cet exemple. Comme le suggèrent 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 en virgule flottante de la ligne de commande :

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

Si vous construisez une boucle (voir Bash exemples ) qui appelle sleep pendant 1 minute, teste le volume, puis répète, vous pouvez la laisser tourner en arrière-plan. La dernière étape consiste à l'ajouter aux scripts d'init ou aux fichiers de service (selon votre OS / distro), de sorte que vous n'ayez même pas à la lancer manuellement.

133
133
133
2013-02-05 16:20:11 +0000

Voici comment cela peut être fait avec Pure Data :

Metro 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 on frappe, “pd dsp 1” l'active. “shell” exécute la commande passée dans un shell, j'utilise l'API xrandr de Linux pour régler la luminosité sur X, il faut adapter cela pour Wayland.

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

Il devrait être beaucoup plus facile de trouver une solution avec des tampons annulaires 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 d'écran elle-même et le verrouillage ne correspondent pas au paradigme du flux de données.

Le fichier PD se trouve sur gist.github.com : ysangkok - kidsyell.pd .

104
104
104
2013-02-01 17:32:18 +0000

Voir “Comment détecter la présence de son/audio” par Thomer M. Gil .

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

54
54
54
2013-02-01 17:28:44 +0000

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

arecord -d1 /dev/null -vvv

Vous devrez peut-être jouer un peu avec les paramètres, comme

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

A partir de là, il suffit d'analyser la sortie.

46
46
46
2013-02-08 14:10:44 +0000

C'est l'une des questions les plus amusantes que j'ai vues. J'aimerais remercier tucuxi pour une réponse aussi fine ; que j'ai mis comme script de 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
42
42
42
2013-02-01 17:32:58 +0000

Mes 2 cents pour la solution C ou C++ : ce n'est peut-être pas l'approche la plus efficace, mais sous Linux, vous pouvez utiliser l’ ALSA API (bibliothèque de traitement 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 s'il est supérieur à un seuil prédéfini, vous pouvez utiliser la bibliothèque X11 pour éteindre l'écran pendant quelques secondes, ou alternativement (moins élégant, mais ça marche) invoquer la commande chvt en utilisant system("chvt 3; sleep 15; chvt 7 ");.

Questions connexes

6
10
11
10
5