“物联网开发实战”学习笔记-(四)智能音箱制作和语音控制



“物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

此次自行打造的智能音箱,在此详细介绍了智能音箱语音控制的实现。

[En]

This time to build their own intelligent speaker, here a detailed introduction of the intelligent speaker voice control implementation.

智能音箱的技术架构

智能音箱主要涉及拾音、前端信号处理、语音识别、自然语言处理和语音合成等技术,现在有些产品甚至提供声纹识别技术。

[En]

Intelligent speaker mainly involves pick-up, front-end signal processing, speech recognition, natural language processing and speech synthesis and other technologies, and now some products even provide voiceprint recognition technology.

其中,智能音箱最重要的是提供各种功能来完成一些任务,比如控制灯光的开启和关闭,这就是所谓的技能。

[En]

Among them, the most important thing of the intelligent speaker is to provide a variety of functions to complete some tasks, such as controlling the light on and off, which is called skill.

整体技术架构如下图所示:

[En]

The overall technical architecture is shown in the following figure:

“物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

; 拾音

Pick Pick就是通过麦克风发出你的声音。

[En]

Pick up is to get your voice through the microphone.

我们都用微信发语音信息,手机通过麦克风接收你说的话。然而,智能音箱所处理的环境更为复杂,因为用户可能会从遥远的地方发出语音命令。

[En]

We all use Wechat to send voice messages, and mobile phones get what you say through a microphone. However, the environment that smart speakers deal with is more complex, because users may give voice commands from faraway places.

因此,智能音箱上一般采用麦克风阵列(Mic Array),也就是按照一定规则排列的多个麦克风,比如下图展示的就是Amazon Echo由 7 个麦克风组成的阵列(绿色圆圈部分)。

“物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

前端语音信号处理

语音信号采集完成后,还需要对语音信号进行前端处理。只有经过处理,智能音箱才能获得相对干净的语音信号,提高语音识别的准确率。

[En]

After collecting the sound signal, the front-end voice signal processing is also needed. Only after processing, the intelligent speaker can obtain a relatively clean speech signal and improve the accuracy of speech recognition.

这些处理技术包括回波消除、噪声抑制、语音检测、声源定位、波束形成和混响消除。

[En]

These processing techniques include echo cancellation, noise suppression, speech detection, sound source location, beamforming and reverberation cancellation.

“物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

; 语音唤醒

语音唤醒就是通过特定的唤醒词激活智能音箱,以执行后续的语音交互任务。一方面,这可以保护用户的隐私,因为只有在醒来后,说话人才会收集和识别用户的语音信息,另一方面,它可以简化语音识别和理解。比如,小米智能音箱的《小艾》就是这样一个唤醒词。

[En]

Voice awakening is to activate the intelligent speaker through specific wake-up words in order to carry out subsequent voice interaction tasks. On the one hand, this can protect the privacy of users, because only after waking up, the speaker collects and recognizes the user’s voice information, and on the other hand, it can simplify speech recognition and understanding. For example, the “Xiao Ai” of Xiaomi’s intelligent speaker is such a wake-up word.

语音识别

语音识别,主要完成的任务是将语音转换成文本,所以也被称为 STT。

自然语言理解

自然语言理解是对语音识别产生的文本进行处理,识别用户意图,产生结构化数据。

[En]

Natural language understanding is to process the text generated by speech recognition, identify the user’s intention, and produce structured data.

技能

技能(Skills)一般要借助后端云平台的强大能力,云平台可以提供知识图谱、家居设备远程控制和音乐等音频资源等能力。

自然语言生成

自然语言生成就是将各种技能的应答结果组织成一种文本语言。例如,当你询问天气时,根据获得的天气条件和温度信息,会生成这样的语句,如:北京今天阳光明媚,最高气温5°,最低气温-6°。自然语言生成和自然语言理解属于自然语言处理的范畴。

[En]

Natural language generation is to organize the response results of various skills into a text language. For example, when you ask about the weather, a statement such as “Beijing is sunny today, the highest temperature is 5 °and the lowest temperature is-6 °” is generated according to the weather condition and temperature information obtained. Natural language generation and natural language understanding belong to the category of natural language processing.

语音合成

语音合成,就是将自然语言生成的文本转换为语音的形式,提供给智能音箱播放出来,给人的感觉就像和音箱在对话。因此,这个过程也叫做 TTS。

智能音箱的开发

了解完智能音箱的基本技术构成,下面就可以基于树莓派开发一个自己的简易智能音箱,这里我们用的是树莓派 Raspberry Pi 4 系列
麦克风阵列
麦克风阵列我使用的是 ReSpeaker 2-Mics Pi HAT,它的 2 个麦克风分布在模组的两边。我们现在来配置一下,让它可以在树莓派上正常工作。
您可以使用以下命令安装其驱动程序。首先,最好切换树莓派软件安装源,切换到国内的腾讯云安装源,这样下载安装速度更快。运行以下命令修改配置文件:

[En]

You can install its driver with the following command. First of all, you’d better switch the raspberry pie software installation source and switch it to the domestic Tencent Cloud installation source, so that the download and installation speed is faster. Run the following command to modify the configuration file:

$ sudo vim /etc/apt/sources.list

将该文件修改为以下内容:

[En]

Modify the file to the following:

deb https://mirrors.cloud.tencent.com/raspbian/raspbian/ buster main contrib non-free rpi
Uncomment line below then 'apt-get update' to enable 'apt-get source'
deb-src https://mirrors.cloud.tencent.com/raspbian/raspbian/ buster main contrib non-free rpi

修改另一个软件安装源的配置文件,如下所示:

[En]

Modify the configuration file for another software installation source, as follows:

$ sudo vim /etc/apt/sources.list.d/raspi.list

修改后的文件内容如下:

deb https://mirrors.cloud.tencent.com/raspberrypi/ buster main
Uncomment line below then 'apt-get update' to enable 'apt-get source'
deb-src https://mirrors.cloud.tencent.com/raspberrypi/ buster main

然后,您需要运行以下命令来更新安装源:

[En]

Then, you need to run the following command to update the installation source:

$ sudo apt-get clean all
$ sudo apt-get update

现在,你可以运行下面命令安装麦克风阵列的驱动程序。因为这个驱动依赖的 wm8960 编解码器没有包含在树莓派系统的内核里面,需要重新加载内核,编译驱动,所以整个过程比较久。在等待的过程中,你可以先阅读这一讲的其他部分。

$ sudo apt-get install git
$ git clone --depth=1 https://github.com/respeaker/seeed-voicecard
$ cd seeed-voicecard
$ sudo ./install.sh
$ sudo reboot

在树莓派重新启动后,您可以在树莓派终端输入以下命令,以查看音频输入和输出设备是否正常工作。<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>After the raspberry pie restarts, you can enter the following command at the raspberry pie terminal to see if the audio input and output devices are working properly.</font>*</details>
`javascript
$ arecord -l
$ aplay -l

“物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

如果一切正常,我们就可以测试录音和播放功能了。在 ReSpeaker 2-Mics Pi HAT 的耳机插口上插入耳机或者扬声器,运行下面的命令,并说几句话。

$ arecord -d 5 test.wav
$ aplay test.wav

另外,你也可以通过软件 AlsaMixer(命令 alsamixer)来配置声音设置和调整音量,左、右箭头键用于选择通道或设备,向上、向下箭头控制当前所选设备的音量。退出程序使用 ALT + Q,或者按 Esc 键。
为了简化开发,并考虑到麦克风硬件的局限性,我们不会关注前端语音信号处理的开发。接下来,我们直接来实现语音唤醒。

[En]

In order to simplify the development and take into account the limitations of microphone hardware, we will not pay attention to the development of front-end voice signal processing. Next, we come directly to the realization of voice awakening.

语音唤醒
为了实现语音唤醒,我们需要选择一款运行在覆盆子馅饼上的轻量级唤醒单词监控器。

[En]

In order to achieve voice wake-up, we need to choose a lightweight wake-up word monitor that runs on raspberry pie.

课程上选择的是Mycroft Precise,它是一个基于 RNN 神经网络的语音唤醒工具。
接下来,我们在树莓派安装 Mycroft Precise。因为需要训练唤醒词模型,我们需要基于源代码来编译、安装。
首先,我们通过 git 命令把 Mycroft Precise 的源代码下载到树莓派的 /home/pi 目录:

$ cd ~
$ git clone https://github.com/mycroftai/mycroft-precise
$ cd mycroft-precise

在安装之前,把 pypi 的安装源修改到清华数据源,可以获得更快的下载速度。我们打开目录中的 setup.sh 文件:

$ vim setup.sh

将文件中的这行内容:

extra-index-url=https://www.piwheels.org/simple

替换成下面的内容:

index-url=https://pypi.tuna.tsinghua.edu.cn/simple
extra-index-url=https://www.piwheels.org/simple

然后我们运行它自己的安装脚本来开始编译和安装。如果执行中途中断,您可以重新执行该命令以继续安装过程。

[En]

Then we run its own installation script to start compiling and installing. If the execution is interrupted in the middle, you can re-execute the command to continue the installation process.

$ ./setup.sh

安装完成后,我们开始使用 Mycroft Precise 来训练一个唤醒词模型,唤醒词可以根据喜好来选择,比如”芝麻开门”。
我们需要先激活 Python 的虚拟环境,因为 Mycroft Precise 在安装过程中创建了这个虚拟环境。

$ source .venv/bin/activate

接下来,我们通过工具 precise-collect 来收集语音模型训练的声音素材,运行后,根据提示录制 12 段声音。

$ precise-collect
Audio name (Ex. recording-##): geektime.##

Press space to record (esc to exit)...

Recording...

Saved as geektime-00.wav
Press space to record (esc to exit)...

然后,我们需要将这些声音随机分为两份,一份是训练样本,包括 8 个声音文件,另一份是测试样本,包括 4 个声音文件,并且把这两份样本分别放到 geektime/wake-word/ 和 /geektime/test/wake-word/ 这两个目录下面。
接着,我们执行下面的命令,生成神经网络模型 geektime.net:

$ precise-train -e 60 geektime.net geektime/

最后,我们还需要将 geektime.net 的模型格式做一下转换,将它从 Keras 模型格式改为 TensorFlow 模型格式,因为 TensorFlow 模型更加通用。

$ precise-convert geektime.net

执行完成后,我们将获得两个文件:

[En]

When the execution is complete, we will get two files:

geektime.pb,TensorFlow 模型文件
geektime.pb.params,包含 Mycroft Precise 在处理音频时需要的一些参数信息。
当然,为了提高模型的准确性,我们还可以使用 precise-train-incremental 工具来增加负样本,重新训练刚才的模型。如果环境复杂的话,你可以尝试一下。
然后,我们可以运行一段代码来测试这个唤醒词模型。不过,因为 portaudio 这个库在树莓派上运行有问题,我们需要先修复一下 portaudio 库。你可以运行下面的命令:

$ sudo apt-get remove libportaudio2
$ sudo apt-get install libasound2-dev
$ git clone -b alsapatch https://github.com/gglockner/portaudio
$ cd portaudio
$ ./configure && make
$ sudo make install
$ sudo ldconfig

测试程序的代码如下:

File:kwsdemo.py
#!/usr/bin/env python3

from precise_runner import PreciseEngine, PreciseRunner

engine = PreciseEngine('precise-engine/precise-engine', 'geektime.pb')
runner = PreciseRunner(engine, on_activation=lambda: print('hello'))
runner.start()

Sleep forever
from time import sleep
while True:
    sleep(10)

现在,我们把 kwsdemo.py 文件,还有两个 geektime.pb 模型相关的文件,都上传到树莓派的 Mycroft Precise 目录下,然后运行 kwsdemo.py 文件,说出”芝麻开门”几个字,就会看到终端显示出”hello”这个单词。
语音识别
对于语音识别,我们直接采用腾讯云提供的语音识别 SDK 来完成(你需要提前在腾讯云控制台开通这个服务)。它会将语音发送到云端,由云端服务器计算出文本信息。你可以通过下面命令来安装:

$ pip3 install tencentcloud-sdk-python

在开始使用之前,你需要访问这个链接创建一个密钥,然后记录下 SecretId 和 SecretKey 的信息。
您可以参考以下代码来完成录制文件的识别。

[En]

You can refer to the following code to complete the identification of a recording file.

from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.asr.v20190614 import asr_client, models
import base64
import io
import sys

SECRET_ID = "你的Secret ID"
SECRET_KEY = "你的Secret Key"

try:
    cred = credential.Credential(SECRET_ID, SECRET_KEY)
    httpProfile = HttpProfile()
    httpProfile.endpoint = "asr.tencentcloudapi.com"
    clientProfile = ClientProfile()
    clientProfile.httpProfile = httpProfile
    clientProfile.signMethod = "TC3-HMAC-SHA256"
    client = asr_client.AsrClient(cred, "ap-beijing", clientProfile)
    #读取文件以及 base64
    with open('./geektime-00.wav', "rb") as f:
        if sys.version_info[0] == 2:
            content = base64.b64encode(f.read())
        else:
            content = base64.b64encode(f.read()).decode('utf-8')
        f.close()
    #发送请求
    req = models.SentenceRecognitionRequest()
    params = {"ProjectId":0,"SubServiceType":2,"SourceType":1,"UsrAudioKey":"sessionid-geektime"}
    req._deserialize(params)
    req.DataLen = len(content)
    req.Data = content
    req.EngSerViceType = "16k_zh"
    req.VoiceFormat = "wav"
    resp = client.SentenceRecognition(req)
    print(resp.to_json_string())

except TencentCloudSDKException as err:
    print(err)

语音合成

语音合成,就是我们希望把类似”我已经把灯关了”这样的文本信息,转换为音频,便于智能音箱播放出来。你可以基于离线的 TTS 引擎来实现,比如HanTTS这个项目。
当然,我们也可以使用腾讯云的语音合成服务(需要提前在腾讯云控制台开通该服务)。您可以参考以下代码:

[En]

Of course, we can also use Tencent Cloud’s voice synthesis service (you need to activate this service on the Tencent Cloud console in advance). You can refer to the following code:

import json
import base64

from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.tts.v20190823 import tts_client, models

SECRET_ID = "你的Secret ID"
SECRET_KEY = "你的Secret Key"

try:
    cred = credential.Credential(SECRET_ID, SECRET_KEY)
    httpProfile = HttpProfile()
    httpProfile.endpoint = "tts.tencentcloudapi.com"

    clientProfile = ClientProfile()
    clientProfile.httpProfile = httpProfile
    client = tts_client.TtsClient(cred, "ap-beijing", clientProfile)

    req = models.TextToVoiceRequest()
    params = {
        "Text": "我已经把灯关了",
        "SessionId": "sessionid-geektime",
        "ModelType": 1,
        "ProjectId": 0,
        "VoiceType": 1002
    }
    req.from_json_string(json.dumps(params))

    resp = client.TextToVoice(req)
    print(resp.to_json_string())

    if resp.Audio is not None:
        audio = resp.Audio
        data = base64.b64decode(audio)
        wav_file = open("temp.wav", "wb")
        wav_file.write(data)
        wav_file.close()

except TencentCloudSDKException as err:
    print(err)

通过智能音箱控制电灯

为了达到控制智能灯光的目的,需要使用物联网平台提供的开发接口。

[En]

In order to achieve the purpose of controlling intelligent lights, we need to use the development interface provided by the Internet of things platform.

首先,我们进入物联网发展平台,选择了“智慧家居”这个项目。通过智能音箱控制电灯

[En]

First of all, we enter the development platform of the Internet of things and choose the “smart home” project. Control of electric lights through intelligent speakers

为了达到控制智能灯光的目的,需要使用物联网平台提供的开发接口。

[En]

In order to achieve the purpose of controlling intelligent lights, we need to use the development interface provided by the Internet of things platform.

首先,我们进入物联网发展平台,选择了“智慧家居”这个项目。

[En]

First of all, we enter the development platform of the Internet of things and choose the “smart home” project.

“物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

然后,点击左侧的”应用开发”,进入新建应用的界面,点击”新建应用”。

“物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

完成后,点击应用列表里面的应用名称,进入应用的详情页面。你可以看到应用的 SecretId 和 SecretKey 信息。这里,你需要将下面”关联产品”中的智能电灯勾选上。只有建立关联,应用才可以控制这个设备。

“物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

具体代码可以参考腾讯提供的开源实现,包括iOS、Android和小程序。
不过,这种方式需要用户账号的登录认证,在树莓派上不太方便。还有一个方式就是基于物联网开发平台提供的通用 API 接口。其中的”设备远程控制”接口可以满足我们的需求。
具体的控制方法,你可以参考下面的代码(注意,目前只支持 ap-guangzhou 区域)。

import json
from led2.main import PRODUCT_ID
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.iotexplorer.v20190423 import iotexplorer_client, models

SECRET_ID = "你的Secret ID"
SECRET_KEY = "你的Secret Key"
PRODUCT_ID = "你的ProductID"

def Light_control(state):
    try:
        cred = credential.Credential(SECRET_ID, SECRET_KEY)
        httpProfile = HttpProfile()
        httpProfile.endpoint = "iotexplorer.tencentcloudapi.com"

        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile
        client = iotexplorer_client.IotexplorerClient(cred, "ap-guangzhou", clientProfile)

        req = models.ControlDeviceDataRequest()
        data = {
            "power_switch": state
        }
        data_str = json.dumps(data)

        params = {
            "DeviceName": "Led_1",
            "ProductId": PRODUCT_ID,
            "Data": data_str
        }
        req.from_json_string(json.dumps(params))

        resp = client.ControlDeviceData(req)
        print(resp.to_json_string())

    except TencentCloudSDKException as err:
        print(err)

Light_control(0)

接下来,唤醒你的第一个智能立体声音响。

[En]

Next, wake up your first smart stereo.

学习笔记总结自’物联网开发实战’–郭朝斌
笔记仅供学习和交流,请勿将其用于商业目的。

[En]

Notes are for learning and communication only, please do not use them for commercial purposes.

Original: https://blog.csdn.net/weixin_47567401/article/details/113832567
Author: 翼达口香糖
Title: “物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/526649/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球