技術共有

【Jiandian Atom i.MX93開発ボードトライアルシリアル体験】録音とキーワード認識の統合

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

この記事は最初にエレクトロニクス愛好家フォーラムで公開されました。[新着リマインダー] [Jiandian Atomic i.MX93 開発ボード試用シリアル体験] 深層学習に基づく音声ローカル制御 - 時間厳守の Atomic Learning Group - 電子技術フォーラム - 人気のプロエレクトロニクス フォーラム (elecfans.com)

次は、録音とキーワード認識を 1 つのプログラムに統合したいと考えています。

Python で音声操作を実行するときに最初に思い浮かぶのは PyAudio です。ただし、PyAudio をボードにインストールするときに少し問題が発生しました。 Python ウェアハウスには、このボードに対応する既製のソフトウェア パッケージはなく、PyAudio はボード上でコンパイルおよび生成される必要があり、PortAudio はボードに移植されていないため、PyAudio は使用できません。当面は、この問題を解決する方法を後で見つけます。

 

私が採用した一時的な方法は、前述の音声をテストするためのシェル スクリプトを変更し、1 秒間の音声を録音し、キーワード認識のための Python プログラムを呼び出します。YES の場合、開発上の LED ライトをオンにします。 NO の場合、開発ボードの LED ライトをオフにします。ライトをオンまたはオフにすると、対応するプロンプトが再生されます。デバッグを容易にするために、録音後に録音結果が自動的に再生され、録音が正しいかどうかが判断されます。

  1. #!/bin/bash
  2. INIT_FLAG="/home/root/shell/audio/.initialized_audio_device"
  3. RECORD_FILE="test.wav"
  4. PLAY_FILE="/home/root/shell/audio/short.mp3"
  5. RC_LOCAL_FILE="/etc/rc.local"
  6. DELETE_COMMAND="rm -f $INIT_FLAG"
  7. # 将开机自动删除音频初始化标志文件命令加入到开机自启中
  8. add_command() {
  9. if ! grep -qFx "$DELETE_COMMAND" "$RC_LOCAL_FILE"; then
  10. echo "$DELETE_COMMAND" >> "$RC_LOCAL_FILE"
  11. sync
  12. fi
  13. }
  14. # 检查命令是否存在
  15. check_command() {
  16. command -v "$1" > /dev/null 2>&1
  17. }
  18. # 初始化音频设备
  19. init_audio_device() {
  20. amixer cset name='PCM Volume' 192
  21. amixer cset name='Mono Mux' 'Stereo'
  22. amixer cset name='Playback De-emphasis' 2
  23. amixer cset name='Capture Digital Volume' 192
  24. amixer cset name='Capture Mute' 'on'
  25. amixer cset name='Capture Polarity' 'Normal'
  26. amixer cset name='3D Mode' 'No 3D'
  27. amixer cset name='ALC Capture Attack Time' 5
  28. amixer cset name='ALC Capture Decay Time' 2
  29. amixer cset name='ALC Capture Function' 'Stereo'
  30. amixer cset name='ALC Capture Hold Time' 2
  31. amixer cset name='ALC Capture Max PGA' 3
  32. amixer cset name='ALC Capture Min PGA' 6
  33. amixer cset name='ALC Capture NG Switch' 'on'
  34. amixer cset name='ALC Capture NG Threshold' 9
  35. amixer cset name='ALC Capture NG Type' 'Mute ADC Output'
  36. amixer cset name='ALC Capture Target Volume' 15
  37. amixer cset name='ALC Capture ZC Switch' 'on'
  38. amixer cset name='Left Channel Capture Volume' 100%
  39. amixer cset name='Right Channel Capture Volume' 100%
  40. amixer cset name='Left Mixer Left Bypass Volume' 100%
  41. amixer cset name='Right Mixer Right Bypass Volume' 100%
  42. amixer cset name='Output 1 Playback Volume' 100%
  43. amixer cset name='Output 2 Playback Volume' 100%
  44. amixer cset name='ZC Timeout Switch' 'on'
  45. amixer cset name='Left PGA Mux' 'DifferentialL'
  46. amixer cset name='Right PGA Mux' 'DifferentialR'
  47. # touch "$INIT_FLAG"
  48. }
  49. # 检查是否已初始化
  50. check_initialized() {
  51. [ -e "$INIT_FLAG" ]
  52. }
  53. function init_board_mic() {
  54. # 初始化板载麦克风
  55. check_command amixer && {
  56. amixer -q cset name='Differential Mux' 'Line 2'
  57. amixer -q cset name='Left Line Mux' 'Line 2L'
  58. amixer -q cset name='Right Line Mux' 'Line 2R'
  59. }
  60. }
  61. function init_headphone_mic() {
  62. # 初始化耳机麦克风
  63. check_command amixer && {
  64. amixer cset name='Differential Mux' 'Line 1'
  65. amixer cset name='Left Line Mux' 'Line 1L'
  66. amixer cset name='Right Line Mux' 'NC'
  67. }
  68. }
  69. function cleanup() {
  70. # 清理并退出
  71. printf "n清理并退出...n"
  72. stty sane # 还原终端状态
  73. exit 0
  74. }
  75. function switch_mode() {
  76. # 录音/播音模式切换
  77. case $1 in
  78. 1)
  79. # 进入录音模式
  80. check_command amixer && {
  81. amixer -q cset name='Left Mixer Left Bypass Switch' 'on'
  82. amixer -q cset name='Right Mixer Right Bypass Switch' 'on'
  83. amixer -q cset name='Left Mixer Left Playback Switch' 'off'
  84. amixer -q cset name='Right Mixer Right Playback Switch' 'off'
  85. }
  86. ;;
  87. 2)
  88. # 进入播音模式
  89. check_command amixer && {
  90. amixer -q cset name='Left Mixer Left Bypass Switch' 'off'
  91. amixer -q cset name='Right Mixer Right Bypass Switch' 'off'
  92. amixer -q cset name='Left Mixer Left Playback Switch' 'on'
  93. amixer -q cset name='Right Mixer Right Playback Switch' 'on'
  94. }
  95. ;;
  96. 3)
  97. # 关闭录音和播音模式
  98. check_command amixer && {
  99. amixer -q cset name='Left Mixer Left Bypass Switch' 'off'
  100. amixer -q cset name='Right Mixer Right Bypass Switch' 'off'
  101. amixer -q cset name='Left Mixer Left Playback Switch' 'off'
  102. amixer -q cset name='Right Mixer Right Playback Switch' 'off'
  103. amixer -q cset name='Left Line Mux' 'NC'
  104. amixer -q cset name='Right Line Mux' 'NC'
  105. }
  106. ;;
  107. esac
  108. }
  109. function apply_config() {
  110. # printf "n可选麦克风测试项目:n"
  111. # printf "1. 耳机麦克风n"
  112. # printf "2. 板载麦克风n"
  113. # while true; do
  114. # read -r -p "请输入您的选择: " choice
  115. # if [[ "$choice" == "1" || "$choice" == "2" ]]; then
  116. # break
  117. # else
  118. # printf "无效输入。请输入1或2。n"
  119. # fi
  120. # done
  121. choice=2
  122. printf "n应用麦克风配置项 %sn" "$choice"
  123. case $choice in
  124. 1)
  125. switch_mode 1
  126. init_headphone_mic
  127. ;;
  128. 2)
  129. switch_mode 1
  130. init_board_mic
  131. ;;
  132. *)
  133. printf "无效选项n"
  134. ;;
  135. esac
  136. }
  137. # 捕获Ctrl+C信号,并调用cleanup函数
  138. trap cleanup SIGINT
  139. # 检查是否已初始化,如果没有,则进行初始化
  140. # if ! check_initialized; then
  141. # printf "第一次运行,执行音频设备初始化...n"
  142. init_audio_device
  143. # add_command
  144. # fi
  145. while true; do
  146. while true; do
  147. command=1
  148. case $command in
  149. 1)
  150. apply_config
  151. printf "n开始录音...n"
  152. #sleep 1
  153. check_command arecord && arecord -f cd -d 1 -r 16000 "$RECORD_FILE"
  154. switch_mode 2
  155. printf "n播放录音...n"
  156. check_command aplay && aplay "$RECORD_FILE"
  157. switch_mode 3
  158. # 调用Python程序并捕获其输出
  159. output=$(python3 simple_audio.py --input=test.wav)
  160. echo "$output"
  161. # 检查输出是否包含">>> YES"
  162. if echo "$output" | grep -q ">>> YES"; then
  163. echo "Python程序输出YES,执行相应代码..."
  164. echo 1 > /sys/class/leds/sys-led/brightness
  165. echo heartbeat > /sys/class/leds/sys-led/trigger
  166. # 在这里添加当输出为YES时需要执行的代码
  167. switch_mode 2
  168. #gst-play-1.0 haodeyiweinindakai.mp3
  169. aplay haodeyiweinindakai.wav
  170. switch_mode 3
  171. elif echo "$output" | grep -q ">>> NO"; then
  172. echo "Python程序输出NO,执行其他代码..."
  173. echo none > /sys/class/leds/sys-led/trigger
  174. echo 0 > /sys/class/leds/sys-led/brightness
  175. # 在这里添加当输出为NO时需要执行的代码
  176. switch_mode 2
  177. #gst-play-1.0 haodeyiweininguanbi.mp3
  178. aplay haodeyiweininguanbi.wav
  179. switch_mode 3
  180. else
  181. echo "Python程序输出未知结果,或者没有输出结果。"
  182. # 可以选择添加处理未知输出的代码
  183. fi
  184. #break
  185. ;;
  186. 2)
  187. switch_mode 2
  188. printf "n开始播音,按 Ctrl+C 可退出播音n"
  189. gst-play-1.0 --audiosink="alsasink" "$PLAY_FILE"
  190. switch_mode 3
  191. #break
  192. ;;
  193. *)
  194. cleanup
  195. ;;
  196. esac
  197. done
  198. break
  199. done


完全なプログラムについては、圧縮パッケージを参照してください。※添付ファイル:yes-no-test.zip 。コア スクリプト コードは次のとおりです。

 

以下のビデオから判断すると、必要な効果は基本的に達成されています。当初は基板のマイク録音の影響で認識に影響が出るのではないかと心配していましたが、今のところ大きな問題はないようです。最初にファイルに録音する方法で、時間が1秒しかないので、少しゆっくり話していると録音が完了しない場合もあるので、かなり面倒です。これには、その後の Python の音声処理の最適化が必要です。

[Jiandian Atomic i.MX93 開発ボード トライアル] 音声を使用して「YES」または「NO」を言い、LED ライトを制御します

 

さらに、現在使用されているモデルは事前にトレーニングされており、中国語のプロンプト単語は使いやすくするために後でトレーニングされる予定です。