2010-04-10 14 views
10

Devo monitorare il mio audio line-in in linux e, nel caso in cui l'audio venga riprodotto, il suono deve essere registrato e salvato su un file. È simile a come motion controlla il feed video.Monitoraggio di una linea audio

È possibile farlo con bash? qualcosa sulla falsariga di:

#!/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: Il flusso mi piacerebbe ottenere da questo programma è

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

Mai sentito parlare di movimento prima, bello –

+0

L'output predefinito di 'date' contiene degli spazi. Sarebbe meglio usare qualcosa come '$ (date +% FT% T)' che assomiglia a: "2010-04-10T09: 55: 56" quindi è ordinabile e non ha spazi. [ISO 8601] (http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/date_and_time_format.htm) (e [qui] (http://en.wikipedia.org/wiki/ISO_8601)) –

+0

@Dennis, grazie, ha cambiato. – Stefan

risposta

5

SoX è il coltellino svizzero di elaborazione del suono. Puoi utilizzarlo per analizzare le registrazioni. L'unico inconveniente delle soluzioni folowing è:

  1. è necessario dividere le registrazioni di pezzi di dimensioni fisse
  2. Si può perdere il tempo di registrazione (a causa di uccidere/analisi/riavvio delle registrazioni)

Quindi ulteriori miglioramenti potrebbero essere l'analisi asincrona, anche se questo complicherà il lavoro.

#!/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 

Aggiornamento:

La seguente soluzione utilizza un FIFO come uscita da rec. Utilizzando divisa su questo tubo per ottenere i pezzi, non ci dovrebbe essere alcuna perdita di tempo di registrazione:

#!/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 per una soluzione eccezionale, ma quelle mancanze sono fatali ... Non funzionerà per qualcosa come un sistema di registrazione dei messaggi telefonici? – Stefan

+0

Il secondo script ha un errore nell'ultima riga 'done1' e se lo cambio in' done' funziona ma registra l'audio al rallentatore. Per favore aggiustalo. Il primo copione è perfetto. – Wally

0

Ecco uno schizzo di come migliorare il soluzione J ü di rgen: è sufficiente fare doppio-buffering, così mentre siete analizzando un file hai già iniziato a registrare il prossimo. Immagino che questo trucco ridurrà le lacune dell'ordine di 100 millisecondi, ma dovresti fare alcuni esperimenti per scoprirlo.

Completamente non testato!

#!/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 chiave è che il momento si uccide il processo di registrazione, che si avvia l'analisi in background e poi prendere un altro viaggio intorno al ciclo di registrare il frammento successivo. In realtà dovresti avviare prima il processo di registrazione successivo, poi l'analisi, ma quello renderà il flusso di controllo un po 'più brutto. Misurerei prima per vedere che tipo di salti stai ricevendo.

+0

Questo script si chiude e dice "Terminato". Nessun file registrato. – Wally

2

Eccone uno ancora migliore;

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

Produce un file audio, solo quando c'è il suono, e taglia fuori il silenzio. Quindi niente spazi vuoti e silenzi lunghi come le cose di cui sopra!

+0

Viene eseguito fino a quando non viene emesso alcun suono e non appena viene emesso un suono, registra per un tempo molto breve e si chiude. Potete per favore fornire una soluzione più pronta che registri effettivamente per molto tempo senza smettere. – Wally

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

Ciò monitorare l'ingresso microfono predefinito continuamente fino a sentire un suono che supera 1% del profilo di rumore di fondo ridotto, quindi generare un file di AUDIOTYPE (mp4, flac, wav, crudo, etc.) a il tasso hz, bit, canali. La registrazione si interromperà dopo 1 secondo di silenzio, misurato all'1% dei livelli di riduzione del rumore. Il file di output verrà pulito dal rumore di fondo (principalmente).

Ora, se qualcuno può semplicemente dirmi come determinare che la registrazione si è arrestata a livello di programmazione, posso renderla utile per il monitoraggio continuo del riconoscimento vocale.