2010-04-10 10 views
10

Necesito monitorear mi audio con entrada de línea en linux, y en el caso de que se reproduzca audio, el sonido debe grabarse y guardarse en un archivo. Similar a cómo motion monitorea la alimentación de video.Monitorizar una línea de audio

¿Es posible hacer esto con bash? algo a lo largo de las líneas de:

#!/bin/bash 

# audio device 
device=/dev/audio-line-in 

# below this threshold audio will not be recorded. 
noise_threshold=10 

# folder where recordings are stored 
storage_folder=~/recordings 

# run indefenitly, until Ctrl-C is pressed 
while true; do 
    # noise_level() represents a function to determine 
    # the noise level from device 
    if noise_level($device) > $noise_threshold; then 
    # stream from device to file, can be encoded to mp3 later. 
    cat $device > $storage_folder/$(date +%FT%T).raw   
    fi; 
done; 

EDIT: El flujo me gustaría obtener de este programa es

a. when noise > threshold, start recording 
b. stop recording when noise < threshold for 10 seconds 
c. save recorded piece to separate file 
+0

Nunca escuché sobre el movimiento anterior, bueno uno –

+0

La salida predeterminada de 'date' tiene espacios en él. Sería mejor usar algo como '$ (date +% FT% T)' que se parece a: "2010-04-10T08: 55: 56" por lo que es ordenable y no tiene espacios. [ISO 8601] (http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/date_and_time_format.htm) (y [aquí] (http://en.wikipedia.org/wiki/ISO_8601)) –

+0

@Dennis, gracias, cambió eso. – Stefan

Respuesta

5

SoX es la navaja suiza de procesamiento de sonido. Puede utilizarlo para analizar grabaciones. La única desventaja de las soluciones folowing es:

  1. necesita dividir las grabaciones a trozos de tamaño fijo
  2. Usted puede perder el tiempo de grabación (debido a la muerte/análisis/reinicio de las grabaciones)

Por lo tanto, se podrían realizar más mejoras analizando asíncronas, aunque esto complicará el trabajo.

#!/bin/bash 

record_interval=5 
noise_threshold=3 
storage_folder=~/recordings 

exec 2>/dev/null  # no default error output 
while true; do 
    rec out.wav & 
    sleep $record_interval 
    kill -KILL %1 
    max_level="$(sox out.wav -n stats -s 16 2>&1|awk '/^Max\ level/ {print int($3)}')" 
    if [ $max_level -gt $noise_threshold ];then 
    mv out.wav ${storage_folder}/recording-$(date +%FT%T).wav; 
    else 
    rm out.wav 
    fi 
done 

Actualización:

La siguiente solución utiliza un fifo como salida de rec. Mediante el uso de escisión en este tubo para obtener los trozos, no debería haber ninguna pérdida de tiempo de grabación:

#!/bin/bash 

noise_threshold=3 
storage_folder=~/recordings 
raw_folder=~/recordings/tmp 
split_folder=~/recordings/split 
sox_raw_options="-t raw -r 48k -e signed -b 16" 
split_size=1048576 # 1M 

mkdir -p ${raw_folder} ${split_folder} 

test -a ${raw_folder}/in.raw || mkfifo ${raw_folder}/in.raw 

# start recording and spliting in background 
rec ${sox_raw_options} - >${raw_folder}/in.raw 2>/dev/null & 
split -b ${split_size} - <${raw_folder}/in.raw ${split_folder}/piece & 


while true; do 
    # check each finished raw file 
    for raw in $(find ${split_folder} -size ${split_size}c);do 
    max_level="$(sox $sox_raw_options ${raw} -n stats -s 16 2>&1|awk '/^Max\ level/ {print int($3)}')" 
    if [ $max_level -gt $noise_threshold ];then 
     sox ${sox_raw_options} ${raw} ${storage_folder}/recording-$(date +%FT%T).wav; 
    fi 
    rm ${raw} 
    done 
    sleep 1 
done1 
+0

+1 para una solución increíble, pero esas deficiencias son fatales ... ¿No funcionará para algo así como un sistema de grabación de mensajes telefónicos? – Stefan

+0

El segundo script tiene un error en la última línea 'done1' y si lo cambio a' done' funciona, pero graba el audio en cámara lenta. Por favor arregla esto El primer guion es perfecto. – Wally

0

Aquí hay un bosquejo de cómo mejorar en solución J ü de rgen: es sólo el doble búfer, así que mientras usted está Al analizar un archivo, ya ha empezado a grabar el siguiente. Supongo que este truco reducirá los huecos al orden de 100 milisegundos, pero tendrías que hacer algunos experimentos para averiguarlo.

¡Completamente no probado!

#!/bin/bash 

record_interval=5 
noise_threshold=3 
storage_folder=~/recordings 

exec 2>/dev/null  # no default error output 

function maybe_save { # out.wav date 
    max_level="$(sox "$1" -n stats -s 16 2>&1| 
       awk '/^Max\ level/ {print int($3)}')" 
    if [ $max_level -gt $noise_threshold ]; then 
     mv "$1" ${storage_folder}/recording-"$2" 
    else 
     rm "$1" 
    fi 
} 

i=0 
while true; do 
    this=out$i.wav 
    rec $this & 
    pid=$? 
    if [ $i -gt 9 ]; then i=0; else i=$(expr $i + 1); fi 
    archive=$(date +%FT%T).wav; 
    sleep $record_interval 
    kill -TERM $pid 
    maybe_save $this $archive & 
done 

La clave es que el momento en que matas el proceso de grabación, que inicie el análisis de los antecedentes y luego tomar otro viaje alrededor del circuito para grabar el siguiente fragmento. Realmente debería iniciar primero el siguiente proceso de grabación, luego el análisis, pero hará que el flujo de control sea un poco más feo. Medí primero para ver qué tipo de saltos estás recibiendo.

+0

Este script simplemente se cierra y dice 'Terminated'. No hay archivos grabados. – Wally

2

Aquí hay una aún mejor;

sox -t alsa default ./recording.flac silence 1 0.1 5% 1 1.0 5%

Produce un archivo de audio, sólo cuando hay sonido, y se corta el silencio. ¡Entonces no hay lagunas ni silencios largos como las cosas de arriba!

+0

Se ejecuta hasta que no haya sonido y tan pronto como haya sonido, graba durante muy poco tiempo y se cierra. ¿Puede dar una solución más preparada que realmente registre durante mucho tiempo sin dejar de fumar? – Wally

0
rec -c CHANNELS -r RATE -b BITS -n OUTPUT.AUDIOTYPE noisered NOISEREDUCTION.noise-profile silence 1 5 1% 1 1t 1% 

Esto controlará la entrada de micrófono por defecto de forma continua hasta que se escucha un sonido que supera el 1% del perfil de ruido de fondo reducido, entonces la salida un archivo de AudioType (MP4, FLAC, WAV, crudo, etc.) a la VELOCIDAD hz, BITS, CANALES. La grabación se detendrá después de 1 segundo de silencio medido al 1% de los niveles de ruido reducido. El archivo de salida se limpiará del ruido de fondo (principalmente).

Ahora, si alguien me puede decir cómo determinar que la grabación se detuvo por programación, puedo hacer que sea útil para el monitoreo continuo del reconocimiento de voz.

Cuestiones relacionadas