【正点原子i.MX93开发板试用连载体验】录音和关键词识别整合

 本文最早发表于电子发烧友论坛:【新提醒】【正点原子i.MX93开发板试用连载体验】基于深度学习的语音本地控制 - 正点原子学习小组 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com)

接下来我就想把录音和关键词识别整合在一个程序里面。

Python中进行语音操作首先想到的是PyAudio。不过在板子上安装PyAudio遇到一点麻烦。Python仓库里面并没有现成的对应这个板子的软件包,需要在板子上编译生成软件包,而PyAudio又依赖PortAudio,而PortAudio在板子上没有移植,所以PyAudio暂时用不了,这个问题以后再想办法解决。

 

我采用的临时办法是修改前面提到的测试音频的shell脚本,由它录制1秒的语音,然后调用Python程序进行关键字识别,如果是YES就打开开发板上的LED灯,如果是NO就关闭开发板上的LED灯,开灯或关灯完成之后会播放相应的提示音。为了方便调试,在录音之后会自动播放录音结果,以确定录音是否正确。

#!/bin/bash

INIT_FLAG="/home/root/shell/audio/.initialized_audio_device"
RECORD_FILE="test.wav"
PLAY_FILE="/home/root/shell/audio/short.mp3"
RC_LOCAL_FILE="/etc/rc.local"
DELETE_COMMAND="rm -f $INIT_FLAG"

# 将开机自动删除音频初始化标志文件命令加入到开机自启中
add_command() {
    if ! grep -qFx "$DELETE_COMMAND" "$RC_LOCAL_FILE"; then
        echo "$DELETE_COMMAND" >> "$RC_LOCAL_FILE"
        sync
    fi
}
   
# 检查命令是否存在
check_command() {
    command -v "$1" > /dev/null 2>&1
}

# 初始化音频设备
init_audio_device() {
    amixer cset name='PCM Volume' 192
    amixer cset name='Mono Mux' 'Stereo'
    amixer cset name='Playback De-emphasis' 2
    amixer cset name='Capture Digital Volume' 192
    amixer cset name='Capture Mute' 'on'
    amixer cset name='Capture Polarity' 'Normal'
    amixer cset name='3D Mode' 'No 3D'
    amixer cset name='ALC Capture Attack Time' 5
    amixer cset name='ALC Capture Decay Time' 2
    amixer cset name='ALC Capture Function' 'Stereo'
    amixer cset name='ALC Capture Hold Time' 2
    amixer cset name='ALC Capture Max PGA' 3
    amixer cset name='ALC Capture Min PGA' 6
    amixer cset name='ALC Capture NG Switch' 'on'
    amixer cset name='ALC Capture NG Threshold' 9
    amixer cset name='ALC Capture NG Type' 'Mute ADC Output'
    amixer cset name='ALC Capture Target Volume' 15
    amixer cset name='ALC Capture ZC Switch' 'on'
    amixer cset name='Left Channel Capture Volume' 100%
    amixer cset name='Right Channel Capture Volume' 100%
    amixer cset name='Left Mixer Left Bypass Volume' 100%
    amixer cset name='Right Mixer Right Bypass Volume' 100%
    amixer cset name='Output 1 Playback Volume' 100%
    amixer cset name='Output 2 Playback Volume' 100%
    amixer cset name='ZC Timeout Switch' 'on'
    amixer cset name='Left PGA Mux' 'DifferentialL'
    amixer cset name='Right PGA Mux' 'DifferentialR'
    # touch "$INIT_FLAG"
}

# 检查是否已初始化
check_initialized() {
    [ -e "$INIT_FLAG" ]
}

function init_board_mic() {
    # 初始化板载麦克风
    check_command amixer && {
        amixer -q cset name='Differential Mux' 'Line 2'
        amixer -q cset name='Left Line Mux' 'Line 2L'
        amixer -q cset name='Right Line Mux' 'Line 2R'
    }
}

function init_headphone_mic() {
    # 初始化耳机麦克风
    check_command amixer && {
        amixer cset name='Differential Mux' 'Line 1'
        amixer cset name='Left Line Mux' 'Line 1L'
        amixer cset name='Right Line Mux' 'NC'
    }
}

function cleanup() {
    # 清理并退出
    printf "\n清理并退出...\n"
    stty sane  # 还原终端状态
    exit 0
}

function switch_mode() {
    # 录音/播音模式切换
    case $1 in
        1)
            # 进入录音模式
            check_command amixer && {
                amixer -q cset name='Left Mixer Left Bypass Switch' 'on'
                amixer -q cset name='Right Mixer Right Bypass Switch' 'on'
                amixer -q cset name='Left Mixer Left Playback Switch' 'off'
                amixer -q cset name='Right Mixer Right Playback Switch' 'off'
            }
            ;;
        2)
            # 进入播音模式
            check_command amixer && {
                amixer -q cset name='Left Mixer Left Bypass Switch' 'off'
                amixer -q cset name='Right Mixer Right Bypass Switch' 'off'
                amixer -q cset name='Left Mixer Left Playback Switch' 'on'
                amixer -q cset name='Right Mixer Right Playback Switch' 'on'
            }
            ;;
	3)
            # 关闭录音和播音模式
            check_command amixer && {
                amixer -q cset name='Left Mixer Left Bypass Switch' 'off'
                amixer -q cset name='Right Mixer Right Bypass Switch' 'off'
                amixer -q cset name='Left Mixer Left Playback Switch' 'off'
                amixer -q cset name='Right Mixer Right Playback Switch' 'off'
		amixer -q cset name='Left Line Mux' 'NC'
        	amixer -q cset name='Right Line Mux' 'NC'
	    }
            ;;	
    esac
}

function apply_config() {
    # printf "\n可选麦克风测试项目:\n"
    # printf "1. 耳机麦克风\n"
    # printf "2. 板载麦克风\n"

    # while true; do
    #     read -r -p "请输入您的选择: " choice

    #     if [[ "$choice" == "1" || "$choice" == "2" ]]; then
    #         break
    #     else
    #         printf "无效输入。请输入1或2。\n"
    #     fi
    # done
    choice=2
    printf "\n应用麦克风配置项 %s\n" "$choice"
    case $choice in
        1)
	    switch_mode 1
            init_headphone_mic
            ;;
        2)
	    switch_mode 1
            init_board_mic
            ;;
        *)
            printf "无效选项\n"
            ;;
    esac
}

# 捕获Ctrl+C信号,并调用cleanup函数
trap cleanup SIGINT

# 检查是否已初始化,如果没有,则进行初始化
# if ! check_initialized; then
#     printf "第一次运行,执行音频设备初始化...\n"
    init_audio_device
#     add_command
# fi

while true; do
    while true; do
        command=1
        case $command in
            1)
                apply_config
                printf "\n开始录音...\n"
                #sleep 1
		check_command arecord && arecord -f cd -d 1 -r 16000 "$RECORD_FILE"
                switch_mode 2
                printf "\n播放录音...\n"
                check_command aplay && aplay "$RECORD_FILE"
		        switch_mode 3
                # 调用Python程序并捕获其输出  
                output=$(python3 simple_audio.py --input=test.wav)  
                echo "$output"

                # 检查输出是否包含">>> YES"  
                if echo "$output" | grep -q ">>> YES"; then  
                    echo "Python程序输出YES,执行相应代码..."  
			echo 1 > /sys/class/leds/sys-led/brightness
			echo heartbeat > /sys/class/leds/sys-led/trigger
                    # 在这里添加当输出为YES时需要执行的代码  
		    switch_mode 2
                    #gst-play-1.0 haodeyiweinindakai.mp3
			aplay haodeyiweinindakai.wav
		    switch_mode 3
                    
                elif echo "$output" | grep -q ">>> NO"; then  
                    echo "Python程序输出NO,执行其他代码..."  
			echo none > /sys/class/leds/sys-led/trigger 
			echo 0 > /sys/class/leds/sys-led/brightness
                    # 在这里添加当输出为NO时需要执行的代码  
		    switch_mode 2
                    #gst-play-1.0 haodeyiweininguanbi.mp3      
			aplay haodeyiweininguanbi.wav
		    switch_mode 3
                else  
                    echo "Python程序输出未知结果,或者没有输出结果。"  
                    # 可以选择添加处理未知输出的代码  
                fi
                #break
                ;;
            2)
                switch_mode 2
                printf "\n开始播音,按 Ctrl+C 可退出播音\n"
                gst-play-1.0 --audiosink="alsasink" "$PLAY_FILE"
		        switch_mode 3
                #break
                ;;
            *)
                cleanup
                ;;
        esac
    done

    break
done


完整的程序见压缩包*附件:yes-no-test.zip。核心的脚本代码如下:

 

从下面的视频看,基本实现了所需要的效果。原来担心板子的麦克风录音效果会影响识别,目前看问题不大。由于采用的是先录音成文件的方法,而且时间仅有1秒,所以使用时还是比较麻烦的,有的时候说话稍微慢了点就没有录制完全。这个需要后续优化一下Python的语音处理。

【正点原子i.MX93开发板试用】使用语音说出YES或NO控制LED灯

 

另外,目前使用的模型是预训练好的,后面计划会训练中文的提示词,以方便使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神一样的老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值