Monitorando o nível do microfone com uma ferramenta de linha de comando no Linux

17

Estou procurando uma ferramenta que me diga, em menos de meio segundo, se o microfone está captando algum som acima de um certo limite. (Pretendo silenciar o canal principal com outra ferramenta de linha de comando, como o amixer.)

Christian Neverdal
fonte

Respostas:

8

Essa solução evitará gravar repetidamente no disco e, mesmo que, na pior das hipóteses, leve um segundo em vez dos menos de meio segundo desejados, eu achei rápido o suficiente depois de tentar. Então, aqui estão os dois scripts que eu uso:

./detect:

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"

Dificilmente elegante, mas funciona.

Nota: Se você quiser algo mais gradual, adicione algo como isto:

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

para silenciar e

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

para sem som.

Christian Neverdal
fonte
7
Uma solução um pouco mais elegante, que suporta resolução de meio segundo e não requer um arquivo temporário: 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 é um pouco exagerado, math-blog.com/2012/07/23/… result = $ (AUDIODEV = hw: 1 rec -n stat trim 0 .5 2> & 1 | grep "Amplitude máxima" | grep -o " [0-9] \. [0-9] * $ "); eco "$ resultado> 0,01" | bc
kevinf 15/06/16
1
Lembre-se de que 'Amplitude máxima' não é o único indicador de um som alto. Um som com alta frequência (por exemplo, tilintar de óculos) pode ser percebido como muito alto pelos ouvidos humanos, mas o som '' Amplitude máxima '' não será muito diferente do som mais baixo. Portanto, em alguns casos, faria sentido analisar a "frequência aproximada" também.
Ka3ak 19/05
2

Apenas uma versão sem script python e TALKING_PERIOD, que configura quantos segundos serão exibidos no nível DOWN_SOUND_PERC e depois subirá para o nível 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

feito

R4v0
fonte
0

Existe uma ferramenta chamada pavômetro que permite ver o nível do microfone, interface de captura aberta do pavilhão,

Em seguida, ajuste o nível de som da captura usando o comando pavucontrol. Em pavucontrol, acesse dispositivos de entrada e ajuste a sensibilidade do microfone.

Edit: No script bash por R4v0, feito está dentro do código.

Edit2: Eu queria aumentar o volume cada vez que houver ruído, então eu editei mais do que menos e cancelei a conversa

    if (( $(echo "$nmb < 0.3" |bc -l) )); then
Haytham-Med Haytham
fonte
5
"ferramenta de linha de comando"
deltaray 26/10/16
0

Modifiquei o script bash para aumentar o volume de acordo com o nível de ruído ao redor.

Você pode alterar minimum_volume, maximum_volume [o valor está em porcentagem].

To_Do: incremento ainda não testado. sox e bc precisam 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
fonte
E defina o final da linha no seu editor de código como unix.
haytham-med haytham 31/08/19
Eu poderia usar isso para 1. ouvir um nível de ruído, 2. 'desaparecer' na reprodução de um arquivo de áudio, 3. tempo limite após x minutos, 4. 'desaparecer' e interromper o áudio, 5. se o nível de ruído atingido voltar a ponto anterior no referido arquivo de áudio? A funcionalidade fade in fade out não é tão importante quanto a parte do currículo para mim. Isso seria fácil de implementar? Estou tentando descobrir como criar um gerador de ruído branco automatizado usando o bash e os utilitários padrão, se possível. Eu quase fiz meu próprio post, mas isso parece meio caminho para a solução que estou procurando.
BasicObject 7/09/19