Fim da gravação sox quando o silêncio é detectado

15

Eu estou escrevendo um script que usa sox para me gravar falando. Agora eu preciso do sox para esperar até que ele detecte o som antes que ele comece a gravar, e eu descobri isso. Mas eu também preciso do sox para sair quando houver silêncio por pelo menos 3 segundos. Como é agora, eu tenho que matar manualmente sox uma vez que eu terminar de falar, caso contrário, sox apenas aguarda novamente até que eu fale mais um pouco, acrescentando ao arquivo de saída (não é isso que eu quero). Aqui está o comando para gravação que estou usando agora:

rec /tmp/recording.flac rate 32k silence 1 0.1 3% -1 3.0 3%

Mais uma vez, só para ficar claro, o Sox deve esperar até eu começar a falar e depois gravar até que eu pare de falar, então o programa sox deve sair.

    
por Isaac 06.11.2012 / 22:31

4 respostas

13

Remova o sinal negativo do seu comando original:

rec /tmp/recording.flac rate 32k silence 1 0.1 3% 1 3.0 3%

Quando a "contagem abaixo" for negativa, o comando silenciar cortará todos os silêncios do meio do arquivo. Quando é positivo, corta o silêncio do final do arquivo.

    
por 05.12.2012 / 00:39
2

Encontrei uma espécie de instabilidade que resolve esse problema.

Notei que quando o silêncio é detectado, o Sox naturalmente não acrescenta mais nada ao arquivo até ouvir mais som. Então decidi que poderia tentar aproveitar esse fato.

Primeiro de tudo, eu começo o gravador de som do sox em segundo plano:

rec /tmp/recording.flac rate 32k silence 1 0.1 3% -1 3.0 3% &

Em seguida, recebo o PID do processo de gravação com: p=$!

Em seguida, dou um segundo ao processo de gravação para concluir a inicialização e aguardo até que o arquivo comece a crescer.

sleep 1
until [ "$var1" != "$var2" ]; do
    var1='du "/tmp/recording.flac"'
    sleep 1
    var2='du "/tmp/recording.flac"'
done

Após esse loop quebrar, isso significa que o som foi detectado. Então, agora eu crio outro loop para esperar até que os dados parem de ser anexados ao arquivo (isso acontecerá quando o sox detectar o silêncio novamente).

echo "Sound Detected"
until [ "$var1" == "$var2" ]; do
    var1='du "/tmp/recording.flac"'
    sleep 0.5
    var2='du "/tmp/recording.flac"'
done

Agora só preciso sair do rec :

echo "Silence Detected"
kill $p

E é isso. Aqui está o script completo:

rec /tmp/recording.flac rate 32k silence 1 0.1 3% -1 3.0 3% &
p=$!
sleep 1
until [ "$var1" != "$var2" ]; do
    var1='du "/tmp/recording.flac"'
    sleep 1
    var2='du "/tmp/recording.flac"'
done
echo "Sound Detected"
until [ "$var1" == "$var2" ]; do
    var1='du "/tmp/recording.flac"'
    sleep 0.5
    var2='du "/tmp/recording.flac"'
done
echo "Silence Detected"
kill $p

Agora eu preferiria uma maneira melhor e mais estável de fazer isso, mas isso terá que funcionar por enquanto.

    
por 07.11.2012 / 21:55
2

Eu alterei as idéias acima um pouco mais. Ele grava para sempre, grava todo o ruído até que (aproximadamente) um segundo de silêncio é encontrado. Então:

  • Garante que dois subdiretórios sejam criados
  • Calcula dois espectrógrafos da gravação - um antes da normalização e outro depois, e grava em pastas datamestadas.
  • Grava o normalizado em um arquivo para uma pasta com registro de dados.
  • Reproduz o arquivo normalizado, com dois arquivos .ogg chirp (de volta através do CB Radio operado por voz)

(Produz um repetidor de eco de UHF / 2 muito pouco)

#!/bin/bash
while true; do
  rec buffer.ogg silence 1 0.1 5% 1 1.0 5%
  DATE='date +%Y%m%d%H%M%S'
  DPATH='date +%Y/%m/%d/'
  mkdir -p ./spectro/$DPATH
  mkdir -p ./voice/$DPATH
  echo Renaming buffer file to $DATE
  sox buffer.ogg -n spectrogram -x 300 -y 200 -z 100 -t $DATE.ogg -o ./spectro/$DPATH/$DATE.png
  sox buffer.ogg normbuffer.ogg gain -n -2
  sox normbuffer.ogg -n spectrogram -x 300 -y 200 -z 100 -t $DATE.norm.ogg -o ./spectro/$DPATH/$DATE.norm.png
  mv normbuffer.ogg ./voice/$DPATH/$DATE.ogg
  play pre.ogg ./voice/$DPATH/$DATE.ogg post.ogg 
done
    
por 18.08.2015 / 11:58
0

Isso escuta para sempre, registra apenas os últimos sons até ouvir um segundo de silêncio, depois grava o arquivo, marca o tempo e reinicia:

#!/bin/bash
/usr/bin/sox -t alsa default /home/default/working/recording.wav silence 1 0.1 5% 1 1.0 5%
DATE=$(date +%Y%m%d%H%M%S)
mv /home/default/working/recording.wav /home/default/waiting/$DATE.recording.wav
/home/default/startrecord.sh
    
por 02.07.2013 / 19:53