Мониторинг аудио линии - PullRequest
       20

Мониторинг аудио линии

11 голосов
/ 10 апреля 2010

Мне нужно контролировать мой звук линейный вход в Linux, и в случае воспроизведения звука звук должен быть записан и сохранен в файл. Похоже на то, как движение контролирует видео поток.

Возможно ли это сделать с помощью bash? что-то вроде:

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

РЕДАКТИРОВАТЬ: поток, который я хотел бы получить из этой программы

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

Ответы [ 4 ]

5 голосов
/ 10 апреля 2010

SoX - это швейцарский армейский нож обработки звука. Вы можете использовать его для анализа записей. Единственный недостаток следующих решений:

  1. Вам нужно разделить записи на фрагменты фиксированного размера
  2. Вы можете потерять время записи (из-за уничтожения / анализа / перезапуска записей)

Таким образом, дальнейшие улучшения могут быть выполнены в асинхронном анализе, хотя это усложнит работу.

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

Обновление:

Следующее решение использует fifo в качестве вывода из рек. При использовании разделения на этот канал для получения фрагментов не должно быть потери времени записи:

#!/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
2 голосов
/ 28 февраля 2014

Вот еще лучший вариант:

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

Он создает аудиофайл только при наличии звука и выключает тишину.Так что никаких пробелов и никаких долгих глушителей, как в материале выше!

0 голосов
/ 09 января 2017
rec -c CHANNELS -r RATE -b BITS -n OUTPUT.AUDIOTYPE noisered NOISEREDUCTION.noise-profile silence 1 5 1% 1 1t 1%

Это будет непрерывно контролировать вход микрофона по умолчанию до тех пор, пока не будет слышен звук, превышающий 1% профиля с уменьшенным фоновым шумом, а затем выведет файл AUDIOTYPE (mp4, flac, wav, raw и т. Д.) Со скоростью RATE, БИТЫ, КАНАЛЫ. Запись остановится через 1 секунду тишины, измеренная при 1% уровня шума. Выходной файл будет очищен от фонового шума (в основном).

Теперь, если кто-то может просто сказать мне, как определить, что запись была остановлена ​​программно, я могу сделать это полезным для непрерывного мониторинга распознавания голоса.

0 голосов
/ 10 апреля 2010

Вот эскиз того, как улучшить решение J? Ugenl: rgen: это просто двойная буферизация, поэтому, анализируя один файл, вы уже начали записывать следующий. Я предполагаю, что этот трюк уменьшит разрывы до порядка 100 миллисекунд, но вам придется провести несколько экспериментов, чтобы выяснить это.

Полностью не проверено!

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

Ключ в том, что в тот момент, когда вы завершаете процесс записи, вы запускаете анализ в фоновом режиме, а затем совершаете еще одно путешествие по циклу, чтобы записать следующий фрагмент. На самом деле вы должны сначала запустить следующий процесс записи, затем анализ, но это сделает поток управления немного страшнее. Сначала я измерю, чтобы увидеть, какие скипы вы получаете.

...