Terminar a gravação sox assim que o silêncio for detectado

16

Estou escrevendo um script que usa sox para me gravar falando. Agora preciso que o sox espere até detectar o som antes de começar a gravar, e eu tenho isso resolvido. Mas também preciso que o sox saia quando houver silêncio por pelo menos 3 segundos. Como é agora, eu tenho que matar manualmente o sox assim que terminar de falar, caso contrário, o sox apenas espera novamente até falar um pouco mais, anexando 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%

Novamente, só para esclarecer, o Sox deve esperar até eu começar a falar e gravar até eu parar de falar, e o programa sox deve sair.

Isaac
fonte

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 silencioso cortará todos os silêncios do meio do arquivo. Quando positivo, apara o silêncio no final do arquivo.

meetar
fonte
11
Essa é uma solução muito mais simples do que a que eu criei, LOL!
Isaac
3

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

  • Garante a criação de dois subdiretórios
  • Calcula dois espectrógrafos da gravação - um antes da normalização e um depois e grava em pastas com carimbo de data.
  • Grava o normalizado em um arquivo em uma pasta com carimbo de data.
  • Reproduz o arquivo normalizado de volta, com dois arquivos .ogg chirp (de volta através do CB Radio operado por voz)

(Cria um repetidor de eco UHF / 2 metros muito prático)

#! / bin / bash
enquanto verdadeiro; Faz
  rec buffer.ogg silêncio 1 0,1 5% 1 1,0 5%
  DATA = `data +% Y% m% d% H% M% S`
  DPATH = `data +% Y /% m /% d /`
  mkdir -p ./spectro/$DPATH
  mkdir -p ./voice/$DPATH
  eco Renomeando arquivo de buffer para $ 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 
feito
Nigel Weeks
fonte
2

Eu encontrei um tipo de maneira instável que meio que resolve esse problema.

Percebi que quando o silêncio é detectado, o sox naturalmente não acrescenta mais nada ao arquivo até ouvir mais som. Então eu decidi que poderia tentar tirar proveito desse fato.

Primeiro, inicio 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=$!

Depois, dou um segundo ao processo de gravação para concluir a inicialização e espero até o arquivo começar a crescer.

dormir 1
até ["$ var1"! = "$ var2"]; Faz
    var1 = `du" /tmp/recording.flac "`
    dormir 1
    var2 = `du" /tmp/recording.flac "`
feito

Após a quebra desse loop, 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).

eco "Som detectado"
até ["$ var1" == "$ var2"]; Faz
    var1 = `du" /tmp/recording.flac "`
    sono 0.5
    var2 = `du" /tmp/recording.flac "`
feito

Agora só preciso sair rec:

eco "Silêncio detectado"
mate $ p

E é isso. Aqui está o script completo:

taxa rec /tmp/recording.flac 32k silêncio 1 0,1 3% -1 3,0 3% &
p = $!
dormir 1
até ["$ var1"! = "$ var2"]; Faz
    var1 = `du" /tmp/recording.flac "`
    dormir 1
    var2 = `du" /tmp/recording.flac "`
feito
eco "Som detectado"
até ["$ var1" == "$ var2"]; Faz
    var1 = `du" /tmp/recording.flac "`
    sono 0.5
    var2 = `du" /tmp/recording.flac "`
feito
eco "Silêncio detectado"
mate $ p

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

Isaac
fonte
1

Isso ouve para sempre, grava 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
Jared Terrell
fonte
2
Bash tem while trueloops
Michael Mrozek