核桃派
直播中

裸奔小耗子

6年用户 67经验值
擅长:嵌入式技术 处理器/DSP 控制/MCU
私信 关注
[经验]

【核桃派ZeroW开发板体验连载】给ChatGPT装上眼睛,并且还可以语音对话

感谢活动主办方给的试用机会,收到快递后,里面一大堆配件,先来个开箱。
698f19a3a4952a2792a2b111c4cd81c.jpg

把两块板子叠在一起,因为我们需要用到网线来做首次无头登录。另外由于项目中需要用到语音交互,因此需要用拓展板上的3.5mm接口,拓展板在本次项目中不可缺少,必须得加上。
8eaaddfc1dd1ed01fc3c52af6955cce.jpg

我会在接下来一个月的评测期内,配置好开发环境,逐个实现各个功能模块,最终完成整个项目。评测的进程会更新在本篇的评论区中,敬请期待。

回帖(10)

裸奔小耗子

2024-8-15 00:30:16

首先我们安装一下固件,配置好开发环境。


去官网下载最新的Debian镜像,最新的镜像链接可以在官方wiki上找到,我选择用github方式下载server版的镜像。因为板载内存仅有1个H,如果带有图形环境的话再进行项目开发会比较吃力。
image.png


选择图里的V2.4_07-12_server_WalnutPi-1b_6.1.31_debian12.img.rar就可以。


接下来,我们需要一个烧录工具,我推荐使用便携版的balenaEtcher。虽然这个工具文件较大,但操作非常简单,一键即可完成烧录。而且便携版不需要安装,使用起来也很方便。

随后,找一张容量在16G以上的内存卡,插入电脑,打开balenaEtcher,选择相应的镜像和内存卡,点击烧录,等待过程完成即可。


5

完成烧录后,把内存卡插入开发板,开发板上电,这样系统就算完成了烧录工作。


举报

裸奔小耗子

2024-8-15 00:47:03

由于我没有HDMI显示器和键盘,因此无法按照官方WIKI那样使用桌面系统。因此,在首次启动时,我需要采用无头方式来配置无线网络。好在核桃派的接口非常齐全,不但有串口接口可以实现无头登录,拓展板上更集合了网线接口,可以直接使用有线网来ssh登录,非常方便。这里我们就使用有线网的方式来进行配置。


把板子插上网线后,可以通过登录路由器管理界页面来找到核桃派的IP地址。但是考虑到每个人的路由器不一样,或许有些路由器并不支持此功能,因此我们可以使用一个简单的小软件Advanced IP Scanner来扫描整个网段的设备,用来找到核桃派的ip


找到ip后,在电脑上打开cmd,在里面输入以下ssh命令,就可以连接到核桃派。我们使用pi用户登录,密码同样为pi。
image.png


接下来连接无线wifi。网上大多教程使用的都是nmcli这个工具,但其实有个更加方便地工具可以使用,nmtui,它还可以自动连接已连接的网络。


sudo nmtui

image.png


选择第二个选项激活网络连接,找到自己家的WiFi按回车输入密码即可完成连接。


这时候我们就可以用sudo ifconfig查看到无线网卡的ip,就可以拔掉网线,使用wifi登录ssh了。


举报

裸奔小耗子

2024-8-15 00:55:26

开发环境搭建


整个项目是在python下进行开发的。为了不污染系统环境,我们会使用虚拟环境来进行开发。有linux python开发经验的小伙伴一定会知道,linux平台中很多python包并不是通过pip的方式进行安装的,而是通过apt包管理器安装在系统环境中的,这是为了有权限对硬件或是内核进行操作。因此,创建虚拟环境时需要导入系统环境包。


由于一部分包需要用到apt安装,另一部分需要用到sudo安装,而有一些包之间还会存在冲突和兼容问题,因此我把所有需要安装的包和创建虚拟环境的命令都写在了一个bash中,只需要一键运行这个bash,就可以自动完成环境配置工作。


#!/bin/bash

sudo apt update
sudo apt full-upgrade -y
sudo apt autoremove -y

cd ~
mkdir jarvis_walnutpi
cd jarvis_walnutpi

sudo apt install gcc python3-dev -y
sudo apt install python3.11-venv -y
python -m venv venv --system-site-packages
source venv/bin/activate

pip install -U "fastapi[standard]"

sudo apt install python3-pyaudio -y

pip install -U SpeechRecognition
sudo apt install flac -y

pip install -U opencv-python
pip install -U torchvision==0.15.2
pip install -U ultralytics

pip install -U "g4f[all]"

pip install -U edge-tts
pip install -U pydub
sudo apt install ffmpeg libavcodec-extra -y

这些包安装是需要一些时间1的,通过ssh安装会存在一个风险,一旦出现ssh掉线,安装也会被终止。为了避免这种情况,我们可以使用screen工具来新建一个窗口,在这个窗口内执行安装程序,这样即使我们关闭窗口,安装也不会中止。


sudo apt install screen
screen -R setup

接下来运行上面的sh文件,我用了半个小时左右,完成后我们就完成了全部环境配置工作。


举报

裸奔小耗子

2024-8-15 01:17:49

音频输入


由于核桃派上的3.5mm接口仅可以做音频输出使用,不能输入,因此这个项目我计划使用电脑来进行音频输入,输入完成后将录音的bytes数据通过FastAPI发送到核桃派,接着核桃派进行语音识别,图像视频,大语言模型调用,TTS合成音频,播放。大预言返回的文本结果可以作为返回值返回给PC。相当于将PC仅作为一个网络麦克风使用。


那首先我们先把PC这块语音输入的问题给解决了。我们在pc上使用的库同样也是pyaudio,用pydub来进行测试。先安装所需的库:


pip install pyaudio
pip install pydub
pip install numpy

然后我写了下面代码用来获取声音。


import time
import pyaudio
import pydub
import numpy as np
import io


def listen(_min_db=200, _end_delay=1.0, _timeout=60):
    _CHANNELS = 1
    _RATE = 16000
    _CHUNK = 1024
    _FORMAT = pyaudio.paInt16

    _p = pyaudio.PyAudio()
    _stream = _p.open(
        format=_FORMAT,
        channels=_CHANNELS,
        rate=_RATE,
        input=True,
        frames_per_buffer=_CHUNK,
    )

    print("开始计时")

    _buffer = io.BytesIO()

    _flag_record = True  # 判断是否继续录音
    _flag_start = False  # 开始录音节点
    _flag_end = False  # 判断声音小了

    _time_wait = time.time()
    _time_start = 0
    _time_end = 0

    while _flag_record:
        _data = _stream.read(_CHUNK, exception_on_overflow=False)
        _buffer.write(_data)
        _db = np.max(np.frombuffer(_data, dtype=np.short))
        print(_db)

        if _flag_start == False and _db > _min_db:
            _flag_start = True
            print("开始录音")
            _time_start = time.time()

        if _flag_start:
            if _flag_end == False and _db < _min_db:
                _flag_end = True
                _time_end = time.time()
                print(f"间隔{_end_delay}s后开始检测是否还是小声")
                continue

            if _flag_end == True and _db > _min_db:
                _flag_end = False
                print("大声,继续录音")
                continue

            if _flag_end == True and time.time() - _time_end > _end_delay:
                _flag_record = False
                print("结束录音")
                continue

        if time.time() - _time_wait > _timeout:  # 超时直接退出
            _flag_record = False
            print("超时")
            continue

    _stream.stop_stream()
    _stream.close()
    _p.terminate()

    _buffer.seek(0)
    _audio = pydub.AudioSegment.from_file(
        _buffer,
        format="raw",
        frame_rate=_RATE,
        channels=_CHANNELS,
        sample_width=_p.get_sample_size(_FORMAT),
    )
    _audio = _audio.set_frame_rate(16000)
    _wav = io.BytesIO()
    _audio.export(_wav, format="wav")
    return _wav


if __name__ == "__main__":
    import pydub.playback as playback

    save = False

    result = listen()

    sound = pydub.AudioSegment.from_file(result, format="wav")
    playback.play(sound)

    if save:
        with open("audio.wav", "wb") as file:
            file.write(result.getbuffer())


代码运行起来后程序会循环检测麦克风的声压,当升压超过阈值后,也就是定义的_min_db=200,则开始录音;当超过一段时间音量小于阈值后,则认为说话结束,停止录音。


录音仅用到pyaudio,pydub是用来把声音数据和数据头组装起来形成wav文件的。在下面的测试运行代码中使用了pydub的播放功能来把录到的音频再播放出来,可以用作测试。


如果电脑的录音和播放功能正常,运行这段代码,就可以完成上述功能测试。如果把save改成1,还可以得到保存好的wav录音文件。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分