2010-04-10 2 views
10

J'ai besoin de surveiller mon audio line-in sous Linux, et dans le cas où l'audio est joué, le son doit être enregistré et enregistré dans un fichier. Similaire à comment motion surveille le flux vidéo.Surveillance d'une ligne audio

Est-il possible de faire cela avec bash? quelque chose le long des lignes 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: Le flux que je voudrais obtenir de ce programme est

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

Jamais entendu parler de mouvement avant, un bon –

+0

La sortie par défaut de 'date' a des espaces dedans. Il serait préférable d'utiliser quelque chose comme '$ (date +% FT% T)' qui ressemble à: "2010-04-10T08: 55: 56" donc c'est triable et n'a pas d'espaces. [ISO 8601] (http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/date_and_time_format.htm) (et [ici] (http://en.wikipedia.org/wiki/ISO_8601)) –

+0

@Dennis, merci, a changé cela. – Stefan

Répondre

5

SoX est le couteau suisse de traitement du son. Vous pouvez l'utiliser pour analyser les enregistrements. La seule lacune des solutions folowing est:

  1. Vous devez diviser les enregistrements des morceaux de taille fixe
  2. Vous pouvez perdre le temps d'enregistrement (en raison de tuer/analyse/remise en marche des enregistrements)

Donc, d'autres améliorations pourraient être l'analyse asynchrone, même si cela va compliquer le travail.

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

Mise à jour:

La solution suivante utilise un fifo en sortie de rec. En utilisant divisé sur ce tuyau pour obtenir les morceaux, il devrait y avoir aucune perte de temps d'enregistrement:

#!/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 pour une solution géniale, mais ces raccourcis sont fatals ... Cela ne fonctionnera pas pour quelque chose comme un système d'enregistrement de message téléphonique? – Stefan

+0

Le deuxième script a une erreur dans la dernière ligne 'done1' et si je le change en' done' cela fonctionne mais enregistre l'audio au ralenti. Veuillez corriger ceci. Le premier script est parfait. – Wally

0

Voici un aperçu de la façon d'améliorer la solution de J ü rgen: il est juste une double mémoire tampon, de sorte que pendant que vous êtes analyser un fichier que vous avez déjà commencé à enregistrer le suivant. Je suppose que cette astuce permettra de réduire les écarts de l'ordre de 100 millisecondes, mais vous devrez faire quelques expériences pour le savoir.

Complètement non testé!

#!/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 clé est que le moment où vous tuez le processus d'enregistrement, vous lancez une analyse en arrière-plan, puis prendre un autre voyage autour de la boucle pour enregistrer le fragment suivant. Vraiment, vous devriez d'abord lancer le processus d'enregistrement suivant, puis l'analyse, mais rendra le flux de contrôle un peu plus laid. Je mesurerais d'abord pour voir quels types de sauts vous obtenez.

+0

Ce script se ferme et dit 'Terminated'. Aucun fichier enregistré. – Wally

2

En voici une encore meilleure;

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

Il produit un fichier audio, seulement quand il y a du son, et coupe le silence. Donc, pas de lacunes et pas de longs silences comme les choses ci-dessus!

+0

Il fonctionne jusqu'à ce qu'il n'y ait pas de son et dès qu'il y a du son, il enregistre pendant très peu de temps et se ferme. Pouvez-vous s'il vous plaît donner une solution plus prête à l'emploi qui enregistre réellement depuis longtemps sans cesser de fumer. – Wally

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

Ceci surveille l'entrée du microphone par défaut en continu jusqu'à ce qu'un son est entendu qui dépasse 1% du profil réduit le bruit de fond, puis la sortie d'un fichier de AUDIOTYPE (mp4, flac, wav, cru, etc.) à le RATE hz, BITS, CHANNELS. L'enregistrement s'arrêtera après 1 seconde de silence, mesuré à 1% des niveaux réduits de bruit. Le fichier de sortie sera nettoyé du bruit de fond (principalement).

Maintenant, si quelqu'un peut simplement me dire comment déterminer que l'enregistrement s'est arrêté par programmation, je peux le rendre utile pour la surveillance continue de la reconnaissance vocale.