Linux 监听音频线路

Linux 监听音频线路,linux,bash,audio,audio-recording,Linux,Bash,Audio,Audio Recording,在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_fo

在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
a。当噪波>阈值时,开始录制
B当噪音<阈值持续10秒时停止记录
C将录制的片段保存到单独的文件中
是声音处理的瑞士军刀。你可以利用它来分析录音。以下解决方案的唯一缺点是:

  • 你需要把录音分成固定大小的块
  • 您可能会损失录制时间(由于停止/分析/重新启动录制)
  • 因此,进一步的改进可能是分析异步,尽管这会使工作复杂化

    #!/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
    
    #/bin/bash
    噪声阈值=3
    存储\u文件夹=~/recordings
    原始文件夹=~/recordings/tmp
    拆分文件夹=~/recordings/split
    sox_raw_options=“-t raw-r 48k-e signed-b 16”
    分割尺寸=1048576#1M
    mkdir-p${raw_folder}${split_folder}
    测试-a${raw_folder}/in.raw | | mkfifo${raw_folder}/in.raw
    #在后台开始录制和拆分
    rec${sox_raw_options}->${raw_folder}/in.raw 2>/dev/null&
    
    split-b${split_size}-这里有一个如何改进于尔根解决方案的示意图:它只是双缓冲,所以在分析一个文件时,您已经开始记录下一个文件。我猜这个技巧会将间隔减少到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
    
    关键是,在结束记录过程的那一刻,您在后台启动分析,然后在循环中进行另一次旅行,以记录下一个片段。 实际上,您应该首先启动下一个录制过程,然后是分析,但是
    将使控制流更难看。我会先测量一下,看看你会遇到什么样的跳跃。

    这里有一个更好的跳跃

    sox-t也是默认值。/recording.flac沉默1 0.15%1 1.0 5%

    只有当有声音时,它才会产生一个音频文件,并切断静音。因此,没有间隙,也没有像上面那样长时间的沉默

    rec -c CHANNELS -r RATE -b BITS -n OUTPUT.AUDIOTYPE noisered NOISEREDUCTION.noise-profile silence 1 5 1% 1 1t 1%
    
    这将持续监控默认麦克风输入,直到听到的声音超过背景降噪配置文件的1%,然后以hz、位、通道的速率输出AUDIOTYPE(mp4、flac、wav、raw等)文件。在1%的降噪水平下测得的1秒静音后,记录将停止。输出文件将清除背景噪声(大部分)


    现在,如果有人能告诉我如何以编程方式确定录音已停止,我可以使其用于连续监控语音识别。

    以前从未听说过运动,很好的一个。
    date
    的默认输出中有空格。最好使用类似于“2010-04-10T08:55:56”的
    $(日期+%FT%T)
    ,这样它就可以排序并且没有空格。(还有)@Dennis,thanx,改变了这一点。+1是一个很棒的解决方案,但这些缺点是致命的。。。它不适用于电话信息录制系统?第二个脚本在最后一行
    done1
    中有错误,如果我将其更改为
    done
    ,它可以工作,但以慢动作录制音频。请把这个修好。第一个脚本很完美。这个脚本只是退出并说
    已终止
    。没有录制任何文件。它会一直运行到没有声音为止,一旦有声音,它会录制一段时间并退出。您能否提供一个更现成的解决方案,它可以记录很长一段时间而不退出。