[英]Monitoring an audio line
我需要监控我的音频线路在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
SoX是声音处理的瑞士军刀。 您可以利用它来分析录音。 以下解决方案的唯一缺点是:
所以进一步的改进可能是分析异步,虽然这会使工作复杂化。
#!/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作为rec的输出。 通过在此管道上使用split来获取块,应该不会丢失录制时间:
#!/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
这是一个更好的一个;
sox -t alsa default ./recording.flac silence 1 0.1 5% 1 1.0 5%
只有在有声音时才会产生音频文件,并切断静音。 所以没有差距,没有像上面那样的长时间沉默!
下面是如何改进Jü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
关键是当你终止录制过程的那一刻,你在后台启动分析,然后绕循环再次行程来记录下一个片段。 你真的应该首先启动下一个录制过程,然后进行分析,但这会使控制流程变得更加丑陋。 我先测量一下你会发现什么样的跳过。
rec -c CHANNELS -r RATE -b BITS -n OUTPUT.AUDIOTYPE noisered NOISEREDUCTION.noise-profile silence 1 5 1% 1 1t 1%
这将持续监听默认麦克风输入,直到听到超过背景噪音减少曲线的1%的声音,然后在RATE,BITS,CHANNELS输出AUDIOTYPE(mp4,flac,wav,raw等)文件。 在1%的噪声降低水平下测量,静音1秒后录音将停止。 输出文件将被清除背景噪音(主要是)。
现在,如果有人可以告诉我如何确定录制已经以编程方式停止,我可以使其对连续监听语音识别有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.