【基于MAX98357的Minimax(百度)长文本语音合成TTS 接入教程】

【基于MAX98357的Minimax(百度)长文本语音合成TTS 接入教程】

  • 1. 前言
  • 2. 先决条件
    • 2.1 硬件准备
    • 2.2 软件准备
    • 2.3 接线
  • 3. 核心代码
    • 3.1 驱动实现
    • 3.2 代码解析
  • 4. 播放文本
  • 5. 结论

视频地址:

SeeedXIAO ESP32S3 Sense【基于MAX98357的Minimax(百度)长文本语音合成TTS 接入教程】

1. 前言

随着物联网技术的快速发展,智能设备的交互方式也在不断进化。语音合成技术(TTS)作为人机交互的重要组成部分,正变得越来越普及。本文将介绍如何利用SeeedXIAO ESP32S3 Sense开发板与MAX98357音频放大器结合,实现与Minimax长文本语音合成服务的集成,打造一个功能丰富的语音交互系统。
在这里插入图片描述

2. 先决条件

2.1 硬件准备

  • ESP32开发板(推荐XIAO开发板)
  • MAX98357 I2S 音频放大器模块
  • 扬声器
  • 跳线(杜邦线)

目前这是我使用的ESP32S3官方硬件👍👍👍(小小的身材有大大的力量)只需要35元加摄像头麦克风79元,后期我会整理相关专栏进行Arduino系统学习😘😘😘。有需要可以购买xiao开发板💕💕💕,SeeedXIAO ESP32S3 Sense硬件购买地址:https://s.click.taobao.com/lekazrt
在这里插入图片描述

2.2 软件准备

  1. Arduino IDE:下载并安装 Arduino IDE;
  2. ESP32 开发板库:在 Arduino IDE 中添加 ESP32 支持;
    参考博客:【esp32c3配置arduino IDE教程】
    为安装过程留出一些时间,具体时间可能因您的互联网连接而异。
  3. ESP32-audioI2S库安装
  • 首先到GITHUB下载「ESP32-audioI2S」 仓库地址:https://github.com/schreibfaul1/ESP32-audioI2S/
  • 解压源码包
  • 把解压的文件放进Arduino IDE的libraries文件夹
    在这里插入图片描述
  1. ArduinoJson库安装
    在这里插入图片描述
    安装成功如上

2.3 接线

ESP32与MAX98357的接线非常简单,只需要将ESP32的I2S接口与MAX98357的相应引脚连接即可。具体接线如下:

  • XIAO D4( ESP32的I2S_BCLK_5)连接到MAX98357的BCLK
  • XIAO D3( ESP32的I2S_LRC_4)连接到MAX98357的LRC
  • XIAO D5( ESP32的I2S_DOUT_6)连接到MAX98357的DIN

在这里插入图片描述

3. 核心代码

下面准备进行了基于ESP32 的硬件测试,此部分有源码分享和代码解析两部分

3.1 驱动实现

在Arduino IDE中,首先需要安装ESP32-audioI2S库和ArduinoJson库。然后将ESP32S3N8R8开发板与MAX98357音频放大器结合,实现与Minimax长文本语音合成TTS服务的集成。以下是一个简单的示例接入Minimax 代码:

#include <Audio.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "Arduino.h"
//1. Replace with your network credentials
const char* ssid = "J09 502";
const char* password = "qwertyuiop111";      // Change this to your WiFi password
String voice_id = "female-tianmei-jingpin";  //青年大学生音色:male-qn-daxuesheng;甜美女性音色:female-tianmei;男性主持人:presenter_male;女性主持人:presenter_female
// 2. Replace with your OpenAI API key
const char* apiKey = "eyJhbGciOiaWwiOiIiLCJDcmVhdGVUaW1lIjoiMjAyNC0wMy0xNiAxMzoyNDoxOCIsImlzcyI6Im1pbmltYXgifQ.WlEj8Nk0j_WOMXZE9SbIC8sHpwJ6R6Pi8Spl5mahJsW3-Jsz7Ev53sGGz3v__Bd5dDkt7o9-Y8BOW0WZq2ImaN7Rof7YNtYnYnvPNDyGx23_xRqq5co9P5UkC3ciYEcIch2SUZ5QPkXR-sMUPzhdowSYvfdu1N25kdKJ8GE_63NfCnsdDVt8mv0wQSSweJK0yf_C8a8ADdB1uF4vg_WKMDjHlvzERsoNZgX6FYtr-bee85rIyu4U-OrbUvEpR1FLPXa7lTlx65QvhVIYGbIKde7ERIT_7QLOQoVFvPz0gX-H6V7UlmSRgRy4LK_R9mvV5TqCy3v90WK_AFuwEhPXcg";
const char* group_id = "1759482180095975904";
const char* url = "https://api.minimax.chat/v1/t2a_pro?GroupId=1759482180095975904";
char myCharPointer;
//扬声器引脚
#define I2S_DOUT 6  // DIN connection
#define I2S_BCLK 5  // Bit clock
#define I2S_LRC 4   // Left Right ClockAudio audio;
String answerv;
String getvAnswer(void) {HTTPClient http1;http1.setTimeout(10000);http1.begin(url);http1.addHeader("Content-Type", "application/json");String token_key = String("Bearer ") + apiKey;http1.addHeader("Authorization", token_key);// 创建一个StaticJsonDocument对象,足够大以存储JSON数据StaticJsonDocument<200> doc;// 填充数据doc["text"] = "我是鹏鹏的小助手,你好鸭";doc["model"] = "speech-01";doc["audio_sample_rate"] = 32000;doc["bitrate"] = 128000;doc["voice_id"] = voice_id;// 创建一个String对象来存储序列化后的JSON字符串String jsonString;// 序列化JSON到String对象serializeJson(doc, jsonString);int httpResponseCode1 = http1.POST(jsonString);if (httpResponseCode1 != 200) {Serial.println("HTTP Request Failed");http1.end();return "<error>";}String reason = http1.getString();Serial.println("Received response:");Serial.println(reason);http1.end();DynamicJsonDocument jsonDoc1(1024);deserializeJson(jsonDoc1, reason);String outputText = jsonDoc1["audio_file"];return outputText;
}void set_voice() {answerv = getvAnswer();Serial.print(answerv);char myCharPointer[answerv.length() + 1];  // 分配足够的空间来存储字符串strcpy(myCharPointer, answerv.c_str());    // 复制字符串到 myCharPointeraudio.connecttohost(myCharPointer);        //  128k mp3
}void setup() {// Initialize SerialSerial.begin(115200);// Connect to Wi-Fi networkWiFi.mode(WIFI_STA);WiFi.begin(ssid, password);Serial.print("Connecting to WiFi ..");while (WiFi.status() != WL_CONNECTED) {Serial.print('.');delay(1000);}Serial.println(WiFi.localIP());// print the SSID of the network you're attached to:Serial.print("SSID: ");Serial.println(WiFi.SSID());// print your WiFi shield's IP address:IPAddress ip = WiFi.localIP();Serial.print("IP Address: ");Serial.println(ip);audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);audio.setVolume(20);  // 0...21// audio.connecttohost("https://minimax-algeng-chat-tts.oss-cn-wulanchabu.aliyuncs.com/audio%2Ftts-mp3-20240406123922-amZgimLG.mp3?Expires=1712493562&OSSAccessKeyId=LTAI5tGLnRTkBjLuYPjNcKQ8&Signature=omJ5fmpPvXMoR1nk9D8UbJqR3L4%3D"); //  128k mp3
}void loop() {audio.loop();while (Serial.available() > 0) {char voice = Serial.read();// Serial.println(voice);switch (voice) {case '1':voice_id = "male-qn-daxuesheng";break;case '2':voice_id = "female-tianmei";break;case '3':voice_id = "presenter_male";break;case '4':voice_id = "presenter_female";break;}Serial.println(voice_id);set_voice();}}

百度TTS接入代码如下:

#include <WiFi.h>
#include <HTTPClient.h>
#include <UrlEncode.h>
#include "Arduino.h"
#include "WiFiMulti.h"
#include "Audio.h"// 1、修改MAX98357喇叭接口
#define I2S_DOUT 6
#define I2S_BCLK 5
#define I2S_LRC 4Audio audio;
WiFiMulti wifiMulti;
// 2、修改WiFi密码
const char *ssid = "J09 502";
const char *password = "qwertyuiop111";  // Change this to your WiFi password
// 3、修改百度语音助手的用户信息
const char *API_KEY = "BXL2YS5w67Xw5XDq";
const char *SECRET_KEY = "pb2zIW2Nch2uNtceKX";
// 4、修改播放文本内容
String encodedText = "人家刚满18岁";const int PER = 4;
const int SPD = 5;
const int PIT = 5;
const int VOL = 5;
const int AUE = 6;const char *TTS_URL = "https://tsn.baidu.com/text2audio";
String url = TTS_URL;
void setup() {Serial.begin(115200);WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(1000);Serial.println("Connecting to WiFi...");}Serial.println("Connected to WiFi");encodedText = urlEncode(urlEncode(encodedText));tts_get();player();
}
void tts_get() {const char *headerKeys[] = { "Content-Type", "Content-Length" };// 5、修改百度语音助手的tokenurl += "?tok=24.e169f864a91715325118.282335-57722200";url += "&tex=" + encodedText;url += "&per=" + String(PER);url += "&spd=" + String(SPD);url += "&pit=" + String(PIT);url += "&vol=" + String(VOL);url += "&aue=" + String(AUE);url += "&cuid=esp32s3";url += "&lan=zh";url += "&ctp=1";HTTPClient http;Serial.print("URL: ");Serial.println(url);http.begin(url);http.collectHeaders(headerKeys, 2);int httpResponseCode = http.GET();if (httpResponseCode > 0) {if (httpResponseCode == HTTP_CODE_OK) {Serial.print("Content-Type = ");Serial.println(http.header("Content-Type"));String contentType = http.header("Content-Type");if (contentType.startsWith("audio")) {Serial.println("合成成功,返回的是音频文件");// 处理音频文件,保存到SD卡或者播放} else if (contentType.equals("application/json")) {Serial.println("合成出现错误,返回的是JSON文本");// 处理错误信息,根据需要进行相应的处理} else {Serial.println("未知的Content-Type");// 可以添加相应的处理逻辑}} else {Serial.println("Failed to receive audio file");}} else {Serial.print("Error code: ");Serial.println(httpResponseCode);}http.end();
}
void loop() {audio.loop();if (Serial.available()) {  // put streamURL in serial monitoraudio.stopSong();String r = Serial.readString();r.trim();if (r.length() > 5) audio.connecttohost(r.c_str());log_i("free heap=%i", ESP.getFreeHeap());}
}void player() {// WiFi.mode(WIFI_STA);// wifiMulti.addAP(ssid.c_str(), password.c_str());// wifiMulti.run();// if(WiFi.status() != WL_CONNECTED){//     WiFi.disconnect(true);//     wifiMulti.run();// }const char *host = url.c_str();audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);audio.setVolume(12);        // 0...21audio.connecttohost(host);  //  128k mp3
}

同样需要修改WiFi密码和百度TTS配置

3.2 代码解析

  • 修改网络连接:使用WiFi.begin(ssid, password)连接到Wi-Fi网络。
//1. Replace with your network credentials
const char* ssid = "J09 502";
const char* password = "qwertyuiop111";      // Change this to your 
  • 修改API密钥:将获取的apiKey和group_id替换到代码中相应的位置。
// 2. Replace with your OpenAI API key
const char* apiKey = "eyJhbGciOiaWwiOiIiLCJDcmVhdGVUaW1lIjoiMjAyNC0wMy0xNiAxMzoyNDoxOCIsImlzcyI6Im1pbmltYXgifQ.WlEj8Nk0j_WOMXZE9SbIC8sHpwJ6R6Pi8Spl5mahJsW3-Jsz7Ev53sGGz3v__Bd5dDkt7o9-Y8BOW0WZq2ImaN7Rof7YNtYnYnvPNDyGx23_xRqq5co9P5UkC3ciYEcIch2SUZ5QPkXR-sMUPzhdowSYvfdu1N25kdKJ8GE_63NfCnsdDVt8mv0wQSSweJK0yf_C8a8ADdB1uF4vg_WKMDjHlvzERsoNZgX6FYtr-bee85rIyu4U-OrbUvEpR1FLPXa7lTlx65QvhVIYGbIKde7ERIT_7QLOQoVFvPz0gX-H6V7UlmSRgRy4LK_R9mvV5TqCy3v90WK_AFuwEhPXcg";
const char* group_id = "1759482180095975904";
const char* url = "https://api.minimax.chat/v1/t2a_pro?GroupId=1759482180095975904";

去Minimax官网获取:https://www.minimaxi.com/user-center/basic-information

  1. group ID获取
    在这里插入图片描述
  2. api KEy获取
    在这里插入图片描述
  3. const char* url = "https://api.minimax.chat/v1/t2a_pro?GroupId=1759482180095975904";请求不需要变化
  • 音色选择:通过1234分别选择//青年大学生音色:male-qn-daxuesheng;甜美女性音色:female-tianmei;男性主持人:presenter_male;女性主持人:presenter_female
  • 音频播放:使用audio.connecttohost(myCharPointer)将获取的音频文件URL传递给MAX98357进行播放。

以上通过发送HTTP请求到Minimax TTS API,将文本转换为语音。将转换后的语音文件通过MAX98357播放出来。

4. 播放文本

先上烧录配置
在这里插入图片描述

在ESP32上运行上述代码后,它将自动连接到WiFi并开始播放指定的MP3音乐文件。你也可以通过串口发送1234分别选择//青年大学生音色:male-qn-daxuesheng;甜美女性音色:female-tianmei;男性主持人:presenter_male;女性主持人:presenter_female,以实现在线播放。
打开串口115200波特率,选择没有结束符,输入1等待答复
在这里插入图片描述

5. 结论

🥳🥳🥳现在,我们在本教程中,您学习了通过本教程,您应该能够成功地将ESP32S3N8R8开发板与MAX98357音频放大器结合,实现与Minimax长文本语音合成TTS服务的集成。这不仅能够为您的项目增加语音交互功能,还能够提升用户体验。🛹🛹🛹从而实现对外部世界进行感知,充分认识这个有机与无机的环境,在实际应用中,您可能还需要考虑如何优化网络请求的效率、如何处理不同语言和口音的文本,以及如何提高系统的稳定性和响应速度。希望本教程能够作为您开始探索语音合成技术的一个起点,随着技术的不断进步,未来将有更多创新的应用等待着我们去发现和实现。🥳🥳🥳科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣

参考资料:

  • ESP32-audioI2S库
  • MAX98357芯片手册
  • https://github.com/schreibfaul1/ESP32-audioI2S/
  • 【ESP32使用MAX98357播放音频】

如果你有任何问题,可以通过下面的二维码加入鹏鹏小分队,期待与你思维的碰撞😘😘😘

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/320342.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis中的双写一致性问题

双写一致性问题 1.先删除缓存或者先修改数据库都可能出现脏数据。 2.删除两次缓存&#xff0c;可以在一定程度上降低脏数据的出现。 3.延时是因为数据库一般采用主从分离&#xff0c;读写分离。延迟一会是让主节点把数据同步到从节点。 1.读写锁保证数据的强一致性 因为一般放…

监视器和显示器的区别,普通硬盘和监控硬盘的区别

监视器与显示器的区别&#xff0c;你真的知道吗&#xff1f; 中小型视频监控系统中&#xff0c;显示系统是最能展现效果的一个重要环节&#xff0c;显示系统的优劣将直接影响视频监控系统的用户体验满意度。 中小型视频监控系统中&#xff0c;显示系统是最能展现效果的一个重要…

Linux字符设备驱动-详解与实操:驱动架构、设备树、Pinctrl子系统和GPIO子系统、platform、设备树下的platform

如何编写一个驱动程序&#xff1a; &#xff08;1&#xff09;确定主设备号 &#xff08;2&#xff09;定义自己的file_operations结构体&#xff1a; 包含对应的open(drv_open)/read(drv_read)等设备操作函数&#xff0c;需要到内核中去注册 &#xff08;3&#xff09;实现…

【微服务】服务保护(通过Sentinel解决雪崩问题)

Sentinel解决雪崩问题 雪崩问题服务保护方案服务降级保护 服务保护技术SentinelFallback服务熔断 雪崩问题 在微服务调用链中如果有一个服务的问题导致整条链上的服务都不可用&#xff0c;称为雪崩 原因 微服务之间的相互调用&#xff0c;服务提供者出现故障服务的消费者没有…

与Apollo共创生态:让智驾技术为各行业发展赋能

目录 一、引言 二、Apollo七周年大会主要内容回顾 2.1活动回顾链接 2.2Apollo项目介绍 2.2.1Apollo项目发展介绍 2.2.2实验用车传感器介绍 2.2.3硬件连接概述 2.2.4软件概述 2.3Apollo X 企业自动驾驶解决方案介绍 2.3.1Apollo X 企业自动驾驶解决方案优势 2.3.2 Ap…

报错(已解决):无法加载文件 D:\code\NodeJs\pnpm.ps1,因为在此系统上禁止运行脚本。

问题&#xff1a; 在vscode运行uniapp项目需要拉取全部依赖&#xff0c;需要使用到pnpm&#xff0c;在vscode终端运行命令&#xff1a;pnpm install后报错&#xff1a; 解决办法&#xff1a; 1&#xff1a;我未安装pnpm&#xff0c;首先打开电脑cmd&#xff0c;运行下列命令&a…

2024中国(江西)国际先进陶瓷材料及智能装备博览会

2024中国&#xff08;江西&#xff09;国际先进陶瓷材料及智能装备博览会 “中国&#xff08;江西&#xff09;国际先进陶瓷材料及智能装备博览会” 陶瓷三新展 &#xff08;新材料、新装备、新技术&#xff09; 绿色智能、引领未来 2024年11月1日-11月3日 中国江西 南昌…

初识指针(2)<C语言>

前言 前文介绍完了一些指针基本概念&#xff0c;下面介绍一下&#xff0c;const关键字、指针的运算、野指针的成因以及避免&#xff0c;assert函数等。 目录 const&#xff08;常属性&#xff09; 变量的常属性 指针的常属性 指针的运算 ①指针 -整数 ②指针-指针 ③指针与…

浅析扩散模型与图像生成【应用篇】(二十一)——DALLE·2

21. Hierarchical Text-Conditional Image Generation with CLIP Latents 该文提出一种基于层级式扩散模型的由文本生成图像的方法&#xff0c;也就是大名鼎鼎的DALLE2。在DALLE2之前呢&#xff0c;OpenAI团队已经推出了DALLE和GLIDE两个文生图模型了&#xff0c;其中DALLE是基…

Costas-Barker序列模糊函数仿真

文章目录 前言一、Costas 序列二、Barker 码三、Costas-Barker 序列模糊函数仿真1、MATLAB 核心代码2、仿真结果①、Costas-Barker 模糊函数图②、Costas-Barker 距离模糊函数图③、Costas-Barker 速度模糊函数图 四、资源自取 前言 Costas 码是一种用于载波同步的频率调制序列…

(读书笔记-大模型) LLM Powered Autonomous Agents

目录 智能体系统的概念 规划组件 记忆组件 工具组件 案例研究 智能体系统的概念 在大语言模型&#xff08;LLM&#xff09;赋能的自主智能体系统中&#xff0c;LLM 充当了智能体的大脑&#xff0c;其三个关键组件分别如下&#xff1a; 首先是规划&#xff0c;它又分为以下…

Docker在linux安装步骤超详细

官网 Install Docker Engine on CentOS | Docker Docs yum -y install gcc yum -y install gcc-c 安装工具 sudo yum install -y yum-utils 设置国内的镜像 yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yu…

python部署linux

python项目做完了&#xff0c;就涉及到了部署&#xff0c;windows可以打包exe&#xff0c;linux如何部署呢&#xff1f; 部署 Python的打包部署方式有多种&#xff0c;具体取决于项目的需求、规模以及所使用的工具。以下是几种常见的Python打包部署方式&#xff1a; 使用pip安…

vite打包配置

目录 minify默认是esbuild&#xff0c;不能启动下面配置 使用&#xff1a; plugins: [viteMockServe({mockPath: mock})]根目录新建mock/index.ts. 有例子Mock file examples&#xff1a;https://www.npmjs.com/package/vite-plugin-mock-server 开发环境生产环境地址替换。根…

计算机是如何执行指令的

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

权益商城系统源码 现支持多种支付方式

简介&#xff1a; 权益商城系统源码&#xff0c;支持多种支付方式&#xff0c;后台商品管理&#xff0c;订单管理&#xff0c;串货管理&#xff0c;分站管理&#xff0c;会员列表&#xff0c;分销日志&#xff0c;应用配置。 上传到服务器&#xff0c;修改数据库信息&#xff…

软件测试与管理-白盒测试-逻辑覆盖法例题

目录 知识点&#xff1a; 例题 &#xff1a; 知识点&#xff1a; 语句覆盖&#xff1a;设计足够多的测试用例&#xff0c;使得被测试程序中的“ 每条可执行语句至少被执行一次” 优点&#xff1a;可通过源码观察直观地得到测试用例&#xff0c;无须细分每个判定表达式。缺点&am…

保研面试408复习 3——操作系统

文章目录 1、操作系统一、进程有哪几种状态&#xff0c;状态之间的转换、二、调度策略a.处理机调度分为三级&#xff1a;b.调度算法 标记文字记忆&#xff0c;加粗文字注意&#xff0c;普通文字理解。 为什么越写越少&#xff1f; 问就是在打瓦。(bushi) 1、操作系统 一、进程…

企业网站 | 被攻击时该怎么办?

前言 每天&#xff0c;数以千计的网站被黑客入侵。发生这种情况时&#xff0c;被入侵网站可用于从网络钓鱼页面到SEO垃圾邮件或者其它内容。如果您拥有一个小型网站&#xff0c;很容易相信黑客不会对它感兴趣。不幸的是&#xff0c;通常情况并非如此。 黑客入侵网站的动机与所…

后端方案设计文档结构模板可参考

文章目录 1 方案设计文档整体结构2 方案详细设计2.1 概要设计2.2 详细设计方案2.2.1 需求分析2.2.2 业务流程设计2.2.3 抽象类&#xff1a;实体对象建模2.2.4 接口设计2.2.5 存储设计 1 方案设计文档整体结构 一&#xff0c;现状&#xff1a;把项目的基本情况和背景都说清楚&a…