Pregunta ¿Cómo configuro una máquina como "pantalla en blanco" durante un período de tiempo (como penalización) si se alcanzan ciertos niveles de ruido?


Mis hijos (4 y 5) gritan mucho cuando juegan juegos en la computadora. Encontré una cura efectiva para esto. Cuando escucho ruidos fuertes, entro en la computadora del juego y hago:

chvt 3;  sleep 15;  chvt 7 

Esto apagará la pantalla durante 15 segundos en Linux. Les dije que a la computadora no le gustan los ruidos fuertes. Ellos totalmente creen esto y piden perdón a la computadora. Se volvieron mucho más silenciosos, pero no al nivel en que sería feliz, por lo que necesito continuar este proceso educativo. Sin embargo, no siempre estoy cerca de hacer esto manualmente.

¿Es posible automatizar esto? Un micrófono está conectado a la caja. Si el nivel de volumen pasa algún umbral, entonces quiero ejecutar un comando.


1526


origen


Hasta que aprendan a presionar CTRL + ALT + F7 - Suici Doga


Respuestas:


Utilizar sox de SoX para analizar una muestra de audio corta:

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

Con -t .wav especificamos que procesamos el tipo de wav, "|arecord -d 2" ejecuta el arecord   programa por dos segundos, -n salidas al archivo nulo y con stat especificamos que queremos estadísticas.

La salida de este comando, en mi sistema con algunos discursos de fondo, es:

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

La amplitud máxima se puede extraer a través de:

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

Nosotros grep para la línea que queremos, use tr para recortar los caracteres de espacio y luego cut por el : personaje y toma la segunda parte que nos da 0.068383 en este ejemplo. Según lo sugerido por los comentarios, RMS es una mejor medida de energía que la amplitud máxima.

Finalmente puedes usar bc en el resultado para comparar valores de coma flotante desde la línea de comandos:

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

Si construyes un bucle (ver Ejemplos Bash) que llama dormir durante 1 minuto, prueba el volumen y luego repite, puede dejarlo en segundo plano. El último paso es agregarlo a las secuencias de comandos de inicio o los archivos de servicio (según su sistema operativo / distribución), de modo que ni siquiera tenga que iniciarlo manualmente.


637



Yo no recomendaría tomar la amplitud máxima. No es bueno para los niños cuando su pantalla se queda en blanco solo porque alguien aplaudió o algo similar. El promedio parece más apropiado. - orlp
Solo una aclaración, por "promedio" te refieres a RMS Amplitude verdad? La amplitud media va a estar cerca de 0 si el ruido es de una intensidad constante durante los 2 segundos (las mitades positiva y negativa se cancelarán mutuamente). - Luke
Un simple detector de "energía" para una serie de muestras es simplemente agregar el valor de todos los picos juntos. No tendrías que promediarlo si no quisieras. Un pico es cualquier punto donde sample[n]>sample[n-1]&&sample[n]>sample[n+1] Lo he usado como un mecanismo rudimentario para medir la energía de una canción y funciona bastante bien. Solo busca un número mágico en el que estés satisfecho con el nivel de volumen. - Kaslai
Me gustaría ver un resultado de muestra de tu primer comando cuando realmente se trata de un niño gritando, como referencia. - Alvin Wong
Para el uso descrito (iniciar automáticamente + ejecutar cada pocos minutos), un trabajo cron es la herramienta correcta para usar. Mucho más simple de configurar y más robusto que usar el script de inicio + ciclo de bash + dormir. - m000


Así es como se puede hacer con Datos puros:

Kid yell prevention using Pure Data

Metro es un metrónomo, y "metro 100" sigue golpeando cada 100 ms.

El audio proviene de adc ~, el volumen se calcula mediante env ~. "pd dsp 0" apaga el DSP cuando se golpea, "pd dsp 1" lo enciende. "shell" ejecuta el comando pasado en un shell, utilizo la API de Linux xrandr para establecer el brillo en X, necesita adaptar esto para Wayland.

Como puede ver, el período de gracia y el bloqueo ocupan mucho más espacio que el código de audio.

Hacer una solución con búferes de anillo y / o promedios móviles debería ser mucho más fácil que hacerlo con sox. Así que no creo que sea una mala idea usar Pure Data para esto. Pero la pantalla se borró sola y el bloqueo no encaja con el paradigma del flujo de datos.

El archivo PD está en gist.github.com: ysangkok - kidsyell.pd.


126



¡muy agradable! Podría hacer que esto sea bastante receptivo utilizando esta técnica: rastree el nivel de sonido promedio durante un minuto, luego utilícelo como línea base, de modo que cuando los niños superen los 20 dB por encima de la línea de base, se active. Luego se ajustará automáticamente al nivel de sonido ambiental. - Hans-Christoph Steiner
Sí, eso tiene sentido @ Hans-ChristophSteiner. Pero, en cierto modo, ¿no requeriría el nivel de ruido ambiental que los niños gritaran más fuerte, ya que representarían una proporción menor del ruido general? Eso, por supuesto, solo se aplicaría si el ruido existente es blanco o rosado o si no se lo ignora. - Janus Troelsen
si estuviera más silencioso de lo habitual, como una mañana de fin de semana, entonces lo haría más sensible, ya que siempre estaría a 20 dB por encima del nivel ambiental - Hans-Christoph Steiner
Esta es la PD extendida? - nullpotent
@iccthedral: utilicé pd-extended para hacerlo, pero no sé si utilicé alguna construcción específica extendida por pd. - Janus Troelsen


Comprobar "Cómo detectar la presencia de sonido / audio" por Thomer M. Gil.

Básicamente graba el sonido cada 5 segundos, que verifica la amplitud del sonido, usando sox, y decide si activar un script o no. Creo que puedes adaptar fácilmente el ruby script para tus hijos! O puede elegir piratear la secuencia de comandos de Python (usando PyAudio) que también ha proporcionado.


100



¿Qué hay de esos arrebatos de menos de 5 segundos que evitan la detección? - RhysW


Puede obtener información del micrófono haciendo algo como:

arecord -d1 /dev/null -vvv

Es posible que tenga que jugar un poco con la configuración, como por ejemplo:

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

A partir de ahí, es una cuestión simple de analizar la salida.


52





Esta es una de las preguntas más divertidas que he visto. Me gustaría agradecer a tucuxi  por una respuesta tan buena; que he establecido como 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



Si inicia esta ejecución agregando una línea a /etc/rc4.d/S99rc.local y luego cambia el micrófono de entrada de sin amplificado al 100%, también puede ser arrojado a tty3 (puede retroceder antes de que el sueño termine) con Ctrl + Alt + F7), y si su teclado es demasiado alto para abrir una terminal, ejecute sudo killall too_loud, luego Ctrl + Alt + F1 e inicie sesión allí). - Alexx Roche


Mis 2 centavos para la solución C o C ++: tal vez no sea el enfoque más efectivo, pero en Linux, puede usar el API ALSA (biblioteca de manejo de audio incorporada de Linux) y utilice alguna técnica numérica (por ejemplo, calcular el nivel de sonido promedio cada segundo) para obtener el nivel de ruido.

Luego puede verificarlo en un ciclo infinito, y si es mayor que un umbral preestablecido, puede usar Biblioteca X11 para apagar la pantalla durante unos segundos, o alternativamente (menos elegante, pero funciona) invocar el chvt comando usando system("chvt 3; sleep 15; chvt 7 ");.


41



Si uso el comando, consideraría algo diferente, entonces chvt. ArchWiki tiene buenos ejemplos. - A.D.