2010-04-10 8 views
10

Ich muss meine Audio Line-in in Linux überwachen, und im Falle, dass Audio gespielt wird, muss der Ton aufgezeichnet und in einer Datei gespeichert werden. Ähnlich wie motion überwacht den Video-Feed.Überwachung einer Audioleitung

Ist es möglich, dies mit bash zu tun? etwas entlang der Linien von:

#!/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: Der Fluss ich von diesem Programm erhalten möchten, ist

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

Noch nie zuvor von einer Bewegung gehört, nice one –

+0

Die Standardausgabe von 'date' enthält Leerzeichen. Es wäre besser, etwas wie "$ (Datum +% FT% T)" zu verwenden, das wie folgt aussieht: "2010-04-10T08: 55: 56", also ist es sortierbar und hat keine Leerzeichen. [ISO 8601] (http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/date_and_time_format.htm) (und [hier] (http://en.wikipedia.org/wiki/ISO_8601)) –

+0

@Dennis, danke, das geändert. – Stefan

Antwort

5

SoX das Schweizer Taschenmesser der Tonverarbeitung ist. Sie können damit Aufzeichnungen analysieren. Das einzige Manko der Folowing Lösungen ist:

  1. Sie müssen die Aufnahmen mit fester Größe Brocken aufzuteilen
  2. Sie verlieren können Zeiterfassung (wegen Tötung/Analyse/Neustarten von Aufnahmen)

So könnten weitere Verbesserungen die Analyse asynchron machen, obwohl dies den Job verkomplizieren wird.

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

Update:

Die folgende Lösung eine Fifo als Ausgabe von rec verwendet. Durch die Verwendung von Split auf diesem Rohr die Stücke zu bekommen, sollte es kein Verlust der Aufnahmezeit:

#!/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 für tolle Lösung, aber diese Shortcommings sind fatal ... Es funktioniert nicht für so etwas wie ein Telefon Nachricht Aufzeichnungssystem? – Stefan

+0

Das zweite Skript hat einen Fehler in der letzten Zeile 'done1' und wenn ich es in' done' ändere, funktioniert es aber nimmt Audio in Zeitlupe auf. Bitte beheben Sie dies. Das erste Skript ist perfekt. – Wally

0

Hier ist eine Skizze, wie auf J ü rgen-Lösung zu verbessern: es ist nur Double-Buffering, also, während Sie Analysieren einer Datei, die Sie bereits aufgenommen haben, die nächste. Ich schätze, dass dieser Trick Lücken in der Größenordnung von 100 Millisekunden reduzieren wird, aber Sie müssten einige Experimente durchführen, um das herauszufinden.

Völlig ungetestet!

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

Der Schlüssel ist, dass, sobald Sie den Aufnahmeprozess zu töten, Sie Analyse im Hintergrund starten und dann um die Schleife eine weitere Reise nehmen Sie die nächste Fragment aufzunehmen. Wirklich sollten Sie den nächsten Aufnahmeprozess zuerst starten, dann die Analyse, aber das wird die Kontrolle ein bisschen hässlicher machen. Ich würde zuerst messen, um zu sehen, welche Arten von Sprüngen Sie bekommen.

+0

Dieses Skript beendet sich und sagt 'Beendet'. Keine Dateien aufgezeichnet. – Wally

2

Hier ist ein noch besseres;

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

Es erzeugt eine Audiodatei, nur wenn es Ton ist, und die Stille schneidet. Also keine Lücken und kein langes Schweigen wie das Zeug oben!

+0

Es läuft, bis kein Ton mehr zu hören ist und sobald es einen Ton gibt, zeichnet es für eine sehr kurze Zeit auf und hört auf. Kannst du bitte eine fertige Lösung geben, die tatsächlich lange aufzeichnet, ohne aufzuhören? – Wally

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

Dies wird die Standard-Mikrofoneingang kontinuierlich überwachen, bis ein Ton zu hören ist, dass 1% der Hintergrundgeräusche reduziert Profil überschreitet, dann Ausgabe eine Datei von AUDIOTYPE (mp4, flac, wav, raw, etc.) bei die Rate hz, BITS, KANÄLE. Die Aufzeichnung stoppt nach 1 Sekunde Stille, gemessen bei 1% der geräuschreduzierten Pegel. Die Ausgabedatei wird (hauptsächlich) von Hintergrundgeräuschen befreit.

Nun, wenn mir jemand sagen kann, wie man feststellen kann, dass die Aufzeichnung programmgesteuert gestoppt wurde, kann ich es für die kontinuierliche Überwachung der Spracherkennung nützlich machen.