分享

单片机学习:第一篇 基于Python的树莓派语音助手

 新用户79878317 2022-12-24 发布于河南

title: 单片机学习:第一篇 基于Python的树莓派语音助手
tags: 树莓派,python,语音助手,百度AIP

树莓派功能十分强大,作为一个微型电脑,独特的阵脚设计使得树莓派开发的自定义程度非常高。本篇博客通过使用python语言,封装一个简单的语音助手程序。制作一个语音助手你需要如下物品:
``` 
1:一个树莓派(3代、4代皆可)
2:免驱的usb声卡(声卡需接在树莓派usb接口)
3:麦克风(接在声卡上)
4:有线音响(音响可连在声卡上,也可连在树莓派的3.5mm接口上)
(树莓派播放设备默认使用3.5mm接口,具体过程需要自定义播放设备)
```
如果要设置usb声卡输出,参考配置声卡教程:https://www.jianshu.com/p/f414b85b9e71,如果使用默认3.5mm接口输出可以忽略。
设计语音助手有如下过程:录音、语音识别、图灵机器人对话、语音合成,以下对各个过程进行介绍。

一、pyaudio录音


使用python语言进行录音,主要是将说话者声音输出成一段音频文件。对于python来说,这很容易。通过引用pyaudio库,可以进行录音、播放、生成wav文件等。
首先,我们在树莓派上需要下载pyaudio库: ```pip3 install pyaudio```
在pyaudio的官网http://people.csail./hubert/pyaudio/介绍上有对pyaudio的详细介绍,以官网示例:
创建一名为rec的python文件 ```sudo nano rec.py```

  1. import RPi.GPIO as GPIO
  2. import pyaudio
  3. import wave
  4. import os
  5. import sys
  6. def rec_fun():
  7.     # 隐藏错误消息,因为会有一堆ALSA和JACK错误消息,但其实能正常录音
  8.     # os.close(sys.stderr.fileno())
  9.     BUTT = 26    # 开始录音的按钮:一边接GPIO26,一边接地
  10.     GPIO.setmode(GPIO.BCM)
  11.     # 设GPIO26脚为输入脚,电平拉高,也就是说26脚一旦读到低电平,说明按了按钮
  12.     GPIO.setup(BUTT, GPIO.IN, pull_up_down = GPIO.PUD_UP)
  13.     # wav文件是由若干个CHUNK组成的,CHUNK我们就理解成数据包或者数据片段。
  14.     CHUNK = 512 
  15.     FORMAT = pyaudio.paInt16  # pyaudio.paInt16表示我们使用量化位数 16位来进行录音
  16.     RATE = 16000  # 采样率1.6k。
  17.     WAVE_OUTPUT_FILENAME = 'command.wav'
  18.     print('请按住按钮开始录音...')
  19.     GPIO.wait_for_edge(BUTT, GPIO.FALLING)
  20.     # To use PyAudio, first instantiate PyAudio using pyaudio.PyAudio(), which sets up the portaudio system.
  21.     p = pyaudio.PyAudio()
  22.     stream = p.open(format = FORMAT,
  23.                     channels = 1,    # cloud speecAPI只支持单声道
  24.                     rate = RATE,
  25.                     input = True,
  26.                     frames_per_buffer = CHUNK)
  27.     print('录音中...')
  28.     frames = []
  29.     # 按住按钮录音,放开时结束
  30.     while GPIO.input(BUTT) == 0:
  31.         data = stream.read(CHUNK)
  32.         frames.append(data)
  33.     print('录音完成,输出文件:' + WAVE_OUTPUT_FILENAME + '\n')
  34.     stream.stop_stream()
  35.     stream.close()
  36.     p.terminate()
  37.     wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
  38.     wf.setnchannels(1)
  39.     wf.setsampwidth(p.get_sample_size(FORMAT))    # Returns the size (in bytes) for the specified sample format.
  40.     wf.setframerate(RATE)
  41.     wf.writeframes(b''.join(frames))
  42.     wf.close()
  43.     return
  44. # 可以直接运行rec.py进行测试,同时保证该文件import时不会自动运行
  45. if __name__ == '__main__':
  46.     rec_fun()

通过树莓派一 点亮LED灯:https://www./2020/06/21/raspberry/?from=timeline,我们对树莓派的阵脚已经有了大概了解。
按钮录音,是通过按钮控制阵脚高低电平。在上述代码里引用```import RPi.GPIO as GPIO```,选择26号输出脚和GND。
执行后按住按钮开始录音,会在rec.py同目录下生成command.wav文件。

 二、语音识别


我选择了百度AIP平台,使用其语音识别技术。(当然也可使用Google、科大讯飞等平台)
 1. 申请百度AIP账号与应用
在百度AI开发平台:https://ai.baidu.com/?track=cp:aipinzhuan|pf:pc|pp:AIpingtai|pu:title|ci:|kw:10005792注册账号,再在控制台创建一个新应用
2. python调用百度AIP
官网文档中有详细使用语音识别技术,包括python的示例。首先导入AipSpeech, 即百度AI语音识别的Python SDK客户端(```pip3 install baidu-aip```)。附上代码如下:

  1. from aip import AipSpeech
  2. import os
  3. APP_ID = '你的IDID'
  4. API_KEY = '你的KEYKEY'
  5. SECRET_KEY = '你的secret_key'
  6. # 新建一个 AipSpeech
  7. client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
  8. # 读取文件
  9. def get_file_content(filePath):   #filePath待读取文件名
  10.     with open(filePath, 'rb') as fp:
  11.         return fp.read()
  12. # 语音识别
  13. def stt(filename):
  14.     # 识别本地文件
  15.     result = client.asr(get_file_content(filename),
  16.                         'wav',
  17.                         16000,
  18.                         {'dev_pid': 1537,}      # dev_pid 参数表示识别的语 言类型 1537表示普通话 
  19.                         )
  20.     print (result)
  21.     return result['result']
  22. # 解析返回值,打印语音识别的结果 
  23.     if result['err_msg']=='success.': 
  24.         word = result['result'][0].encode('utf-8')       # utf-8 编码 
  25.         if word!='': 
  26.             if word[len(word)-3:len(word)]==',': 
  27.                 print (word[0:len(word)-3]) 
  28.                 with open('demo.txt','wb') as f: 
  29.                     f.write(word[0:len(word)-3]) 
  30.             else: 
  31.                 print (word.decode('utf-8').encode('gbk')) 
  32.                 with open('demo.txt','wb') as f: 
  33.                     f.write(word) 
  34.                 f.close() 
  35.         else: 
  36.             print ('音频文件不存在或格式错误') 
  37.     else: 
  38.         print ('错误') 
  39. # main 函数 识别本地录音文件 yahboom.wav 
  40. if __name__ == '__main__':
  41.     stt('command.wav')   # command.wav为待读取文件,请替换

 三、与图灵机器人对话


使用图灵机器人基本原理就是使用urllib.request模块,向接口地址发送HTTP POST请求,请求中加入了聊天内容。(返回内容是一个字典)
首先我们需要申请一个机器人:官网入口:http://www./
python代码参考:

  1. import json
  2. import urllib.request
  3. def chat(question):
  4.     api_url = 'http://openapi./openapi/api/v2'
  5.     text_input = question
  6.     req = {
  7.         'perception':
  8.         {
  9.             'inputText':
  10.             {
  11.                 'text': text_input
  12.             },
  13.             'selfInfo':
  14.             {
  15.                 'location':
  16.                 {
  17.                     'city': 'xxx',
  18.                     'province': 'xxx',
  19.                     'street': 'xxx'
  20.                 }
  21.             }
  22.         },
  23.         'userInfo': 
  24.         {
  25.             'apiKey': 'xxxxxxxxxxxxx',    #你的key
  26.             'userId': '123'         #唯一的标识,自选即可
  27.         }
  28.     }
  29.     # 将字典格式的req转为utf8编码的字符串
  30.     req = json.dumps(req).encode('utf8')
  31.     print('\n' + '正在调用图灵机器人API...')
  32.     http_post = urllib.request.Request(api_url, data=req, headers={'content-type': 'application/json'})
  33.     response = urllib.request.urlopen(http_post)    
  34.     print('得到回答,输出为字典格式:')
  35.     response_str = response.read().decode('utf8')
  36.     response_dic = json.loads(response_str)
  37.     intent_code = response_dic['intent']['code'] 
  38.     # 返回网页类的输出方式
  39.     if(intent_code == 10023):
  40.         results_url = response_dic['results'][0]['values']['url']
  41.         results_text = response_dic['results'][1]['values']['text']
  42.         with open('result.txt','w') as f:
  43.             f.write(results_text)  # 自带文件关闭功能,不需要再写f.close()
  44.         answer = {'code': intent_code, 'text': results_text, 'url':results_url}
  45.         print(answer)
  46.         return(answer)
  47.     # 一般的输出方式
  48.     else:
  49.         results_text = response_dic['results'][0]['values']['text']
  50.         answer = {'code': intent_code, 'text': results_text}
  51.         with open('result.txt','w') as f:
  52.             f.write(results_text)  # 自带文件关闭功能,不需要再写f.close()
  53.         print(answer)
  54.         return(answer)
  55. if __name__ == '__main__':
  56.     with open('demo.txt', 'r',encoding='UTF-8') as f:
  57.         text  = f.read()  # 读取文件
  58.     eg_question = text
  59.     chat(eg_question)

 四、语音合成


我同样选择了百度的语音合成(注意,AI平台新建应用后,语音合成技术需要自行领用。语音识别的key与合成的key不一样,使用请注意)。示例文档自行参考,提供参考代码:
 

  1. #encoding:utf8
  2. from aip import AipSpeech
  3. import os
  4. ''' 你的 APPID AK SK '''
  5. APP_ID = 'xxxxx'
  6. API_KEY = 'xxxxxxxxxxxxxxxx'
  7. SECRET_KEY = 'chMdMAS0acD7sPS6FhP3a3iOijU7wMVl'
  8. def speak(text_content):
  9.     client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
  10.     texts = text_content
  11.     result = client.synthesis(texts , options={'vol':5})
  12.     print('\n' + '正在调用语音合成API...')
  13.     if not isinstance(result,dict):
  14.         with open('answer.mp3','wb') as f:
  15.             f.write(result)
  16.     else:print(result)
  17.     print('播放音频中...')
  18.     print('以下均为mplayer的输出内容\n')
  19.     os.system('mplayer answer.mp3')
  20.     return
  21. if __name__ == '__main__':   
  22.     with open('result.txt', 'rb') as f: # 打开文件
  23.          text  = f.read()  # 读取文件       
  24.     eg_text_content = text
  25.     speak(eg_text_content)         


 五、封装


至此,我们的录音、识别、对话、合成已经完成了,开始对这四个py文件进行封装。
在封装时,增加一个获取获取歌曲直链url1.py文件。
一个简单的if else 完成了图灵机器人对话到在线放歌的切换。
当然,读者还可以进一步完善,例如实现与图灵机器人的多次对话直到退出。

需要参考我的全部代码,可以去我的资源下载

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多