Supervisión del nivel del micrófono con una herramienta de línea de comandos en Linux

17

Estoy buscando una herramienta que me diga, en menos de medio segundo, si el micrófono está captando algún sonido por encima de un cierto umbral. (Planeo silenciar el canal maestro con otra herramienta de línea de comandos, como amixer).

Christian Neverdal
fuente

Respuestas:

8

Esta solución evitará escribir repetidamente en el disco, y aunque en el peor de los casos toma un segundo en lugar del deseado menos de medio segundo, descubrí que es lo suficientemente rápido después de probarlo. Entonces, aquí están los dos scripts que uso:

./detectar:

while true; do
    arecord -d 1 /dev/shm/tmp_rec.wav ; sox -t .wav /dev/shm/tmp_rec.wav -n stat 2>\
    &1 | grep "Maximum amplitude" | cut -d ':' -f 2 | ./check.py
    if [ $? -eq 0 ] ; then
         amixer set Master 0
    else
         amixer set Master 80
    fi
done

./check.py:

#!/usr/bin/env python
import sys

number = 0.0
thing="NO"

line = sys.stdin.readline()
thing = line.strip()
number = float(thing)

if number < 0.15:
    raise Exception,"Below threshold"

Apenas elegante, pero funciona.

Nota: Si quieres algo más gradual, agrega algo como esto:

   for i in `seq 0 80 | tac`; do
      amixer set Master $i
   done

para silenciar y

   for i in `seq 0 80`; do
      amixer set Master $i
   done

por no silenciar.

Christian Neverdal
fuente
77
Una solución un poco más elegante, que admite una resolución de medio segundo y no requiere un archivo temporal: while true; do amixer set Master $(rec -n stat trim 0 .5 2>&1 | awk '/^Maximum amplitude/ { print $3 < .15 ? 80 : 0 }'); done
nandhp
1
Python es un poco exagerado, math-blog.com/2012/07/23/… result = $ (AUDIODEV = hw: 1 rec -n stat trim 0 .5 2> & 1 | grep "Amplitud máxima" | grep -o " [0-9] \. [0-9] * $ "); echo "$ resultado> 0.01" | aC
kevinf
1
Solo tenga en cuenta que 'Amplitud máxima' no es el único indicador de un sonido fuerte. Un sonido con una frecuencia alta (por ejemplo, tintineo de anteojos) puede ser percibido como muy fuerte por los oídos humanos, pero la "amplitud máxima" de los sox no será muy diferente de la más baja. Entonces, en algunos casos, también tendría sentido analizar la 'frecuencia aproximada'.
ka3ak
2

Solo versión sin script de python y TALKING_PERIOD, que configura cuántos segundos sonarán en el nivel DOWN_SOUND_PERC, luego pasa al nivel UP_SOUND_PERC.

#!/bin/bash

TALKING_PERIOD=16
UP_SOUND_PERC=65
DOWN_SOUND_PERC=45
counter=0
while true; do

echo "counter: " $counter

if [ "$counter" -eq 0 ]; then
    nmb=$(arecord -d 1 /dev/shm/tmp_rec.wav ; sox -t .wav /dev/shm/tmp_rec.wav -n stat 2>&1 | grep "Maximum amplitude" | cut -d ':' -f 2)

    echo "nmb: " $nmb

    if (( $(echo "$nmb > 0.3" |bc -l) )); then
        echo "ticho"
        amixer -D pulse sset Master 45%
        counter=$TALKING_PERIOD
    else
        echo "hlasno"
        amixer -D pulse sset Master 65%
    fi
fi

if [[ $counter -gt 0 ]]; then
        ((counter--))
fi

sleep 1

hecho

R4v0
fuente
0

Existe una herramienta llamada pavumeter que le permite ver el nivel del micrófono, la interfaz de captura abierta de pavumeter,

Luego ajuste el nivel de sonido de captura usando el control de pavu. En el control de pavu, vaya a los dispositivos de entrada y ajuste la sensibilidad del micrófono.

Editar: en el script bash de R4v0, hecho está dentro del código.

Edit2: quería subir el volumen cada vez que hay ruido, así que solo edité más que ser menor y cancelé el peroid hablando

    if (( $(echo "$nmb < 0.3" |bc -l) )); then
haytham-med haytham
fuente
55
"herramienta de línea de comando"
deltaray
0

Modifiqué el script bash para aumentar el volumen de acuerdo con el nivel de ruido circundante.

Puede cambiar el volumen mínimo, el volumen máximo [el valor está en porcentaje].

To_Do: incremento aún no probado. Sox y BC necesitan ser instalados.

#!/bin/bash

minimum_volume=20
maximum_volume=60
increment=10

counter=0
while true; do

# echo "counter: " $counter


nmb=$(arecord -d 1 /dev/shm/tmp_rec.wav ; sox -t .wav /dev/shm/tmp_rec.wav -n stat 2>&1 | grep "Maximum amplitude" | cut -d ':' -f 2)
echo "nmb: " $nmb

    if (( $(echo "$nmb <= 0.1" |bc -l) )); then
    amixer -D pulse sset Master $minimum_volume%
    else 
        if (( $(echo "$nmb <= 0.2" |bc -l) )); then
        amixer -D pulse sset Master $(($minimum_volume+ $increment))%
        else
            if (( $(echo "$nmb <= 0.3" |bc -l) )); then
            amixer -D pulse sset Master $(($minimum_volume+ $increment+ $increment))%
                else
                    if (( $(echo "$nmb <= 0.4" |bc -l) & maximum_volume>=40)); then
                    amixer -D pulse sset Master $(($minimum_volume+ $increment+ $increment+ $increment))%
                    else
                        if (( $(echo "$nmb <= 0.5" |bc -l) & maximum_volume>=50)); then
                        amixer -D pulse sset Master $(($minimum_volume+ $increment+ $increment+ $increment+ $increment))%
                        else
                            if (( $(echo "$nmb <= 0.6" |bc -l) & maximum_volume>=60)); then
                            amixer -D pulse sset Master $(($minimum_volume+ $increment+ $increment+ $increment+ $increment+ $increment))%  
                            else
                                if (( $(echo "$nmb <= 0.7" |bc -l) & maximum_volume>=70)); then
                                amixer -D pulse sset Master $(($minimum_volume+ $increment+ $increment+ $increment+ $increment+ $increment+ $increment))%
                                else
                                    if (( $(echo "$nmb <= 0.8" |bc -l) & maximum_volume>=80)); then
                                    amixer -D pulse sset Master $(($minimum_volume+ $increment+ $increment+ $increment+ $increment+ $increment+ $increment+ $increment))%
                                    else
                                        if (( $(echo "$nmb <= 0.9" |bc -l) & maximum_volume>=90)); then
                                        amixer -D pulse sset Master $(($minimum_volume+ $increment+ $increment+ $increment+ $increment+ $increment+ $increment+ $increment+ $increment))%
                                        else
                                            amixer -D pulse sset Master $(($maximum_volume+ $minimum_volume))%
                                        fi
                                    fi
                                fi
                            fi
                        fi
                    fi
                fi
            fi
        fi

sleep 1
done
haytham-med haytham
fuente
Y configure el final de línea en su editor de código en unix.
haytham-med haytham
¿Podría usar esto para 1. escuchar un nivel de ruido, 2. 'desvanecerse' al reproducir un archivo de audio, 3. tiempo de espera después de x minutos, 4. 'desvanecerse' y detener el audio, 5. si el nivel de ruido se reunió nuevamente, reanudar desde punto anterior en dicho archivo de audio? La funcionalidad de fundido en fundido no es tan importante como la parte del currículum para mí. ¿Sería esto fácil de implementar? Estoy tratando de descubrir cómo hacer un generador automático de ruido blanco usando bash y utilidades estándar si es posible. Casi hice mi propia publicación, pero esto parece ser parte de la solución que estoy buscando.
BasicObject