当前位置: 首页 > news >正文

【基于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播放音频】

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

相关文章:

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

【基于MAX98357的Minimax&#xff08;百度&#xff09;长文本语音合成TTS 接入教程】 1. 前言2. 先决条件2.1 硬件准备2.2 软件准备2.3 接线 3. 核心代码3.1 驱动实现3.2 代码解析 4. 播放文本5. 结论 视频地址&#xff1a; SeeedXIAO ESP32S3 Sense【基于MAX98357的Minimax&am…...

秋招后端开发面试题 - JVM底层原理

目录 JVM底层原理前言面试题Java 对象的创建过程&#xff1f;什么是指针碰撞&#xff1f;什么是空闲列表&#xff1f;/ 内存分配的两种方式&#xff1f;JVM 里 new 对象时&#xff0c;堆会发生抢占吗&#xff1f;JVM 是怎么设计来保证线程安全的&#xff1f;/ 内存分配并发问题…...

VUE2从入门到精通(一)

**************************************************************************************************************************************************************************** 1、课程概述 【1】前置储备&#xff1a;HTMLCSSJS、WebAPI、Ajax、Node.js 【2】1天&…...

cmake进阶:文件操作之写文件

一. 简介 cmake 提供了 file() 命令可对文件进行一系列操作&#xff0c;譬如读写文件、删除文件、文件重命名、拷贝文件、创建目录等等。 接下来 学习这个功能强大的 file() 命令。 本文学习 CMakeLists.txt语法中写文件操作。 二. cmake进阶&#xff1a;文件操作之写文件…...

ubuntu 安装单节点HBase

下载HBase mkdir -p /home/ellis/HBase/ cd /home/ellis/HBase/ wget https://downloads.apache.org/hbase/2.5.8/hbase-2.5.8-bin.tar.gz tar -xvf hbase-2.5.8-bin.tar.gz安装java jdk sudo apt install openjdk-11-jdksudo vim /etc/profileexport JAVA_HOME/usr/lib/jvm/…...

HTTP 多个版本

了解一下各个版本的HTTP。 上个世纪90年代初期&#xff0c;蒂姆伯纳斯-李&#xff08;Tim Berners-Lee&#xff09;及其 CERN的团队共同努力&#xff0c;制定了互联网的基础&#xff0c;定义了互联网的四个构建模块&#xff1a; 超文本文档格式&#xff08;HTML&#xff09; …...

【DevOps】探索Linux命令行世界:深入了解Shell的力量

目录 一、Linux Shell 详细介绍 1. Shell基础概念 2. Shell的功能特性 3. 常用Shell命令与技巧 4. 高级Shell特性与实践 二、常见的Shell及其比较 1. Bash (Bourne Again SHell) 2. Zsh (Z Shell) 3. Fish (Friendly Interactive SHell) 4. Ksh (Korn SHell) 5. Csh …...

互斥量的使用

文章目录 前言一、互斥量与二进制信号量二、优先级反转与优先级继承三、递归锁 前言 通过学习上一章互斥量理论基础&#xff0c;这一章我们来做一些实验进行验证。 一、互斥量与二进制信号量 互斥量使用和二进制信号量类似 互斥量有优先级继承功能&#xff0c;二进制信号量没有…...

关于面试真题的压迫

1.请描述一下您在使用JavaScript进行DOM操作时&#xff0c;如何提高页面性能和用户体验&#xff1f; 使用事件委托&#xff1a;在父元素上监听事件&#xff0c;而不是为每个子元素都添加事件监听器。这样可以减少事件处理程序的数量&#xff0c;提高性能。 缓存DOM查询&#x…...

1700java进销存管理系统Myeclipse开发sqlserver数据库web结构java编程计算机网页项目

一、源码特点 java web进销存管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为sqlser…...

mysql数据库(排序与分页)

目录 一. 排序数据 1.1 排序规则 1.2 单列排序 1.我们也可以使用列的别名&#xff0c;给别名进行排序 2.列的别名只能在 ODER BY 中使用&#xff0c; 不能在WHERE中使用。 3.强调格式&#xff1a;WHERE 需要在 FROM 后&#xff0c; ORDER BY 之前 1.3 二级排序&…...

Android 实时监听Activity堆栈变化(系统应用)

private val mIActivityManager: IActivityManager ActivityManagerNative.asInterface(ServiceManager.getService(Context.ACTIVITY_SERVICE)) 方式一&#xff08;registerProcessObserver&#xff09; &#xff1a; mIActivityManager.registerProcessObserver(mIProcess…...

双目深度估计原理立体视觉

双目深度估计原理&立体视觉 0. 写在前面1. 双目估计的大致步骤2. 理想双目系统的深度估计公式推导3. 双目标定公式推导4. 极线校正理论推导 0. 写在前面 双目深度估计是通过两个相机的对同一个点的视差来得到给该点的深度。 标准系统的双目深度估计的公式推导需要满足:1)两…...

Redis探索之旅(基础)

目录 今日良言&#xff1a;满怀憧憬&#xff0c;阔步向前 一、基础命令 1.1 通用命令 1.2 五大基本类型的命令 1.2.1 String 1.2.2 Hash 1.2.3 List 1.2.4 Set 1.2.5 Zset 二、过期策略以及单线程模型 2.1 过期策略 2.2 单线程模型 2.3 Redis 效率为什么这么高 三…...

C语言/数据结构——每日一题(链表的中间节点)

一.前言 今天我在LeetCode刷到了一道单链表题&#xff0c;想着和大家分享一下这道题&#xff1a;https://leetcode.cn/problems/middle-of-the-linked-list。废话不多说让我们开始今天的知识分享吧。 二.正文 1.1题目描述 1.2题目分析 这道题有一个非常简便的方法——快慢指…...

这是用VS写的一个tcp客户端和服务端的demo

服务端&#xff1a; 客户端&#xff1a; 其实这里面的核心代码就两行。 客户端的核心代码&#xff1a; //套接字连接服务端 m_tcpSocket->connectToHost(_ip,_port);//通过套接字发送数据m_tcpSocket->write(ui.textEditSend->toPlainText().toUtf8());//如果收到信…...

代码随想录算法训练营day18 | 102.二叉树的层序遍历、226.翻转二叉树、101. 对称二叉树

102.二叉树的层序遍历 迭代法 层序遍历使用队列&#xff0c;同时记录每层的个数 class Solution:def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:res []if not root:return resqueue collections.deque()queue.append(root)while queue:size len…...

工厂自动化升级改造参考(01)--设备通信协议详解及选型

以下是整合了通信协议的特点、应用场景、优缺点以及常用接口方式的描述: 以太网/IP: 来历: 以太网是一种局域网技术,由罗伯特梅特卡夫和大卫博格在1973年开发。IP是网络层协议,负责在网络中的设备间传输数据。特点:基于标准的以太网技术,使用TCP/IP协议栈,支持高速数据传…...

数据结构与算法之经典排序算法

一、简单排序 在我们的程序中&#xff0c;排序是非常常见的一种需求&#xff0c;提供一些数据元素&#xff0c;把这些数据元素按照一定的规则进行排序。比如查询一些订单按照订单的日期进行排序&#xff0c;再比如查询一些商品&#xff0c;按照商品的价格进行排序等等。所以&a…...

VSCode通过SSH连接虚拟机Ubuntu失败

问题说明 最近使用VSCode通过SSH连接Ubuntu&#xff0c;通过VSCode访问Ubuntu进行项目开发&#xff0c;发现连接失败 在VSCode中进行SSH配置 这些都没有问题&#xff0c;但在进行连接时候出现了问题&#xff0c;如下&#xff1a; 出现了下面这个弹窗 解决方法 发现当…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...