小智AI音频开发 libopus + Eclipse C/C++ MinGW 编解码测试用例
小智AI音频开发 libopus + Eclipse C/C++ MinGW 编解码测试用例
目录
- 小智AI音频开发 libopus + Eclipse C/C++ MinGW 编解码测试用例
- 前言
- 移植
- 编解码测试
- libopus编码器的控制参数
- 信号类型
- 比特率
- 带宽
- 编码复杂度
- 前向纠错
- 声道
- 不连续传输
- 位深
- 帧持续时长
- 码率
- VBR约束
- 应用类型
- 示例代码
前言
最近ESP32小智AI很火,研究了小智的技术架构后,随即想在中移ML307R上重写小智的固件,这样就不用WIFI了,并且还省掉一块ESP32开发板。
ESP32小智的语音编解码使用的是libopus这个库,在espidf上已经是现成的组件包,而如果我想在Ml307r上实现,那么就要自己移植这个库了。
移植最快的办法就是先在windows上以纯C的形式移植好,liboous库是可以根据平台进行编译的,有x86、arm等,根据实际的平台编译可以获得更好的编解码效率,我为了跨平台更通用,直接去掉了平台,以纯C的形式移植,这样不管用在哪里,都能够无缝移植,甚至直接用在单片机上!
libopus下载地址:https://opus-codec.org/downloads/
移植测试环境:
- 系统:win10
- IDE:Eclipse C/C++
- libopus移植版本:1.4
移植
libopus在1.4及以前的版本,提供了win32下的配置文件示例,而在1.4以后的版本,由于作者改用了cmake进行编译,没有移植的config.h参考,只能通过构建工具生成config.h头文件,所以本文采用1.4版本来移植。
需要移植的目录结构:
- include:头文件
- silk:silk音频编码器
- arm:arm架构相关,不要
- fixed:定点运算代码,需要
- float:浮点运算代码,需要
- mips:mips指令集相关,不要
- x86:x86架构相关,不要
- tests:测试代码,不要
- src:源码,去除repacketizer_demo.c文件,这是示例代码
- celt:celt音频编码器,去除pus_custom_demo.c文件,这是示例代码
- arm:不要
- mips:不要
- tests:不要
- x86:不要
增加version.h
头文件,内容如下:
#ifndef VERSION_H
#define VERSION_H#define PACKAGE_VERSION "1.4"#endif /* VERSION_H */
增加配置头文件config.h
,内容如下:
/***********************************************************************
Copyright (c) 2011, Skype Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Internet Society, IETF or IETF Trust, nor the
names of specific contributors, may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/#ifndef CONFIG_H
#define CONFIG_H#define VAR_ARRAYS
//#define USE_ALLOCA
//#define NONTHREADSAFE_PSEUDOSTACK#define FIXED_POINT 1#define OPUS_BUILD 1#define REMOVE_FOR_MALLOC 1#define DISABLE_FLOAT_API 1#include "version.h"#endif /* CONFIG_H */
在eclipse中定义全局宏HAVE_CONFIG_H
,如下如所示:
增加头文件包含,如下图所示:
此时编译,就可以直接编译通过了。。
编解码测试
注意:opus是有损的,经过编码又解码后的数据肯定和原始数据是不一样的,所以只能通过播放器听一下编解码前后的音频文件是否有区别,以此来验证代码是否正确。
虽然有损,但是几乎听不出来有差异。
我用python录制了一段原始语音数据:test.pcm
该条语音参数如下:
- 通道数:1
- 采样率:24000
- 帧周期:60ms
- 位深度:16bit
测试代码提供了CBR和VBR模式。
代码测试步骤为:读取原始pcm数据->编码->解码->写入编解码后的文件
audacity这个软件是开源的,可以直接播放pcm格式的原始音频数据。
打开audacity软件,文件->导入->原始数据,参数如下设置:
第一条语音轨道是vbr模式编解码后的音频数据,第二条是cbr模式编解码后的音频数据,第三条轨道是原始的音频轨道数据,可以看到几乎没有差别,说明代码是没有问题的。
libopus编码器的控制参数
信号类型
opus_encoder_ctl(encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
- OPUS_SIGNAL_MUSIC:音乐
- OPUS_SIGNAL_VOICE:语音
比特率
opus_encoder_ctl(encoder, OPUS_SET_BITRATE(OPUS_AUTO)); // 动态比特率
opus_encoder_ctl(encoder, OPUS_SET_BITRATE(48000)); // 固定比特率
-
动态比特率:根据实际音频复杂度输出,每个包的大小不同,编码时间也比较短,可以在未说话时有效减小带宽和数据量。(默认)。
-
固定比特率:根据设定的比特率输出音频,每个输出包的大小相同,编码时间会加长,不推荐使用。
带宽
opus_encoder_ctl(encoder, OPUS_SET_BANDWIDTH(OPUS_AUTO));
设置音频主要处于哪个频率的带宽,一般设置成自动就可以。
编码复杂度
opus_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(0));
更高的复杂度拥有更好的音频质量,同时耗时会更长,实际上在PC上测试,输出音频并没有什么不同。
- 取值范围:0-10
前向纠错
opus_encoder_ctl(encoder, OPUS_SET_INBAND_FEC(1));
用于增强数据可靠性的数字信号处理技术,用算法修复丢失的数据包。
- 0:关
- 1:开(默认)
声道
opus_encoder_ctl(encoder, OPUS_SET_FORCE_CHANNELS(1));
强制设置通道数。
不连续传输
opus_encoder_ctl(encoder, OPUS_SET_DTX(0));
不连续传输,仅应用于LPC层。
- 0:关(默认)
- 1:开
位深
opus_encoder_ctl(encoder, OPUS_SET_LSB_DEPTH(16));
设置位深,取值在8-24之间,默认为24。
帧持续时长
opus_encoder_ctl(encoder, OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_60_MS));
设定每个数据包的实际时间长度,根据实际音频数据填写。
取值:
#define OPUS_FRAMESIZE_ARG 5000 /**< Select frame size from the argument (default) */
#define OPUS_FRAMESIZE_2_5_MS 5001 /**< Use 2.5 ms frames */
#define OPUS_FRAMESIZE_5_MS 5002 /**< Use 5 ms frames */
#define OPUS_FRAMESIZE_10_MS 5003 /**< Use 10 ms frames */
#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */
#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */
#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */
#define OPUS_FRAMESIZE_80_MS 5007 /**< Use 80 ms frames */
#define OPUS_FRAMESIZE_100_MS 5008 /**< Use 100 ms frames */
#define OPUS_FRAMESIZE_120_MS 5009 /**< Use 120 ms frames */
码率
opus_encoder_ctl(encoder, OPUS_SET_VBR(1));
- 1:设置为动态码率(VBR)模式(默认)
- 0:设置为静态码率(CBR)模式
码率一般分为静态码率和动态码率,CBR模式虽然说压缩要更快,但是数据量大,现在已经逐渐被VBR方式取代。
如果设置为CBR模式,每次调用opus_encode
函数编码后的数据包的大小是固定的,但如果设置为VBR模式,每次编码的数据包的大小是可变的,数据量会更小。
VBR约束
opus_encoder_ctl(encoder, OPUS_SET_VBR_CONSTRAINT(1));
在编码器中启用或禁用约束VBR,当编码器处于CBR模式时,此设置将被忽略。
- 0:关闭约束
- 1:开启约束(默认)
应用类型
opus_encoder_ctl(encoder, OPUS_SET_APPLICATION(OPUS_APPLICATION_VOIP));
配置编码器的预期应用程序类型,取值:
- OPUS_APPLICATION_VOIP:适合收听较高质量和清晰度的大多数VoIP/视频会议应用
- OPUS_APPLICATION_AUDIO:适合广播/高保真应用,其中解码的音频应尽可能靠近输入端
- OPUS_APPLICATION_RESTRICTED_LOWDELAY:仅在最重要的时刻最低可实现延迟时使用。不能使用语音优化模式。
示例代码
/** main.c** Created on: 2025年3月24日* Author: hello*/#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>#include "opus.h"#define MAX_PACKET 1500#define SAMPLING_RATE 24000
#define CHANNELS 1
#define FRAME_DURATION 60
#define BITDEPTH 16
#define FRAME_SIZE ((SAMPLING_RATE * FRAME_DURATION) / 1000)
#define FRAME_SIZE_BYTES (FRAME_SIZE << 1)
#define FRAME_SIZE_DURATION OPUS_FRAMESIZE_60_MS#define debug_printf(...) do{printf(__VA_ARGS__);printf("\n");fflush(stdout);}while(0)void test(int vbr)
{int len = 0, err = 0;int frame_size = FRAME_SIZE;OpusEncoder *encoder = NULL;OpusDecoder *decoder = NULL;FILE* fps = NULL;FILE* fpd = NULL;opus_int16 pcmbuf[MAX_PACKET];uint8_t opusbuf[MAX_PACKET];debug_printf("\r\ntest run, vbr enable = %d", vbr);// 创建编码器encoder = opus_encoder_create(SAMPLING_RATE, CHANNELS, OPUS_APPLICATION_AUDIO, &err);if(err != OPUS_OK || encoder == NULL){debug_printf("create encoder failed ! err:%d", err);goto __exit;}// 创建解码器decoder = opus_decoder_create(SAMPLING_RATE, CHANNELS, &err);if(err != OPUS_OK || decoder == NULL){debug_printf("create decoder failed ! err:%d", err);goto __exit;}// 初始化解码器参数opus_encoder_ctl(encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));opus_encoder_ctl(encoder, OPUS_SET_BITRATE(OPUS_AUTO));opus_encoder_ctl(encoder, OPUS_SET_BANDWIDTH(OPUS_AUTO));opus_encoder_ctl(encoder, OPUS_SET_VBR(vbr));opus_encoder_ctl(encoder, OPUS_SET_VBR_CONSTRAINT(1));opus_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(0));opus_encoder_ctl(encoder, OPUS_SET_INBAND_FEC(1));opus_encoder_ctl(encoder, OPUS_SET_FORCE_CHANNELS(CHANNELS));opus_encoder_ctl(encoder, OPUS_SET_DTX(0));opus_encoder_ctl(encoder, OPUS_SET_LSB_DEPTH(BITDEPTH));opus_encoder_ctl(encoder, OPUS_SET_EXPERT_FRAME_DURATION(FRAME_SIZE_DURATION));opus_encoder_ctl(encoder, OPUS_SET_APPLICATION(OPUS_APPLICATION_VOIP));fps = fopen("test.pcm", "rb");if(vbr == 0){fpd = fopen("cbr-test.pcm", "wb+");}else{fpd = fopen("vbr-test.pcm", "wb+");}while(fread(pcmbuf, 1, FRAME_SIZE_BYTES, fps) != 0){// 编码len = opus_encode(encoder, pcmbuf, frame_size, opusbuf, MAX_PACKET);if(len < 0 || len > MAX_PACKET){debug_printf("encode failed ! err:%d", len);break;}debug_printf("encode len: %-4d toc:0x%02X", len, opusbuf[0]);// 解码len = opus_decode(decoder, opusbuf, len, pcmbuf, frame_size, 0);if(len != frame_size){debug_printf("decode failed ! err:%d", len);break;}// 存文件fwrite(pcmbuf, 1, FRAME_SIZE_BYTES, fpd);}__exit:opus_encoder_destroy(encoder);opus_decoder_destroy(decoder);fclose(fps);fclose(fpd);debug_printf("done");
}int main()
{test(0); // 恒定码率(CBR)模式test(1); // 动态码率(VBR)模式return 0;
}
ends…
相关文章:
小智AI音频开发 libopus + Eclipse C/C++ MinGW 编解码测试用例
小智AI音频开发 libopus Eclipse C/C MinGW 编解码测试用例 目录 小智AI音频开发 libopus Eclipse C/C MinGW 编解码测试用例前言移植编解码测试libopus编码器的控制参数信号类型比特率带宽编码复杂度前向纠错声道不连续传输位深帧持续时长码率VBR约束应用类型 示例代码 前言…...
Spring Boot定时任务设置与实现
Spring Boot定时任务设置与实现 在Spring Boot中,可以使用Scheduled注解来创建定时任务。以下是一个简单的示例,展示了如何在项目启动后每5秒调用一次指定的方法。 1. 添加依赖 首先,确保你的pom.xml文件中包含Spring Boot的依赖ÿ…...
海康/大华/宇视/华为/汉邦/天地伟业/英飞拓/科达/中星微/同为/天视通等主流监控设备RTSP地址
RTSP协议是TCP/IP协议体系中的一个应用层协议,该协议主要规定了一对多应用程序如何有效地通过IP网络传送多媒体数据,特别适用于音视频数据的实时传输和控制。 目前监控市场厂家众多,各个厂家的RTSP地址格式不尽一致 以下是海康威视、大华股份…...
FreeRTOS 队列结构体 xQUEUE 深度解析
一、核心成员与功能设计 FreeRTOS 的队列结构体 xQUEUE 是任务间通信(IPC)的核心数据结构,通过统一的设计支持队列、信号量、互斥量等多种同步机制。其设计体现了 **"数据拷贝 结构复用"** 的理念,兼顾轻量化与扩展…...
system V 消息队列信息量(了解)
目录 system V 消息队列 消息队列的基本原理 消息队列数据结构 消息队列接口介绍 消息队列相关函数 消息队列的释放 向消息队列发送数据 向消息队列接收消息 System V 信号量 信号量相关概念 信号量的数据结构 信号量相关函数 进程互斥 system V IPC联系 system V…...
CSS rem、vw/vh、less
目录 分辨率、视口与二倍图 一、分辨率与像素基础 1. 物理像素(Physical Pixels) 2. 逻辑像素(CSS 像素) 二、视口(Viewport)控制 1. 视口类型 2. 设置理想视口 三、二倍图(Retina/HiD…...
CHI协议——retry
一、核心目标 防止请求阻塞:当Completer暂时无法处理请求(比如tracker不够被占满)时,通过retry机制避免请求在 REQ Channel堆积,确保系统流畅运行。 retry机制只存在于REQ Channel,在DAT/RSP/SNP Channel不存在 二、Retry Flow…...
在linux部署网站
在Linux部署网站,需要准备一个纯净的系统 一、系统环境准备 1.设置静态IP地址 2.关闭默认防火墙 systemctl disable firewalld --now 3.配置SSH密钥登录 4.yum update -y && reboot # 更新系统内核 5.yum install -y wget curl unzip # 安装…...
语义网是什么
语义网(Semantic Web)是由万维网发明者 蒂姆伯纳斯-李(Tim Berners-Lee) 在20世纪90年代末提出的概念,目标是让互联网上的数据不仅对人类可读,还能被机器自动理解、关联和推理。它通过为数据添加明确的语义…...
51单片机
本文来源:腾讯元宝 51单片机是对所有兼容Intel 8031指令系统的8位单片机的统称,其技术起源于1981年Intel推出的8051内核微控制器(Micro Control Unit)。作为嵌入式系统领域的经典代表,它具有以下核心特点和应用价值: 一、技术特…...
初2数学-1.勾股定理
复习勾股定理: 1. ; 2. ; 3. ; 4. 后面3个式子都是根据相似三角形对应边成比例推出来的。 第4个式子来做例子: 三角形CBD与三角形 ACD相似,所以: h:c2 c1 : h. 【例题] ABCD为菱形,边长为…...
Java条码与二维码生成技术详解
一、技术选型分析 1.1 条码生成方案 Barbecue是最成熟的Java条码库,支持: Code 128EAN-13/UPC-AUSPS Inteligent Mail等12种工业标准格式 1.2 二维码方案对比 库名称维护状态复杂度功能扩展性ZXing★★★★☆较高强QRGen★★★☆☆简单一般BoofCV★…...
Spring Boot 集成 Quartz 实现定时任务(Cron 表达式示例)
Spring Boot 集成 Quartz 实现定时任务(Cron 表达式示例) 前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Spring Boot 观察定时任务执行5. Quartz Cron 表达式详解6. 结论 前言 在 Spring Boot 项目中,我们经常…...
数智读书笔记系列025《智能医疗:医学人工智能的未来》
一、书籍概述与核心价值 1.1 书籍定位与影响力 《智能医疗:医学人工智能的未来》在智能医疗领域占据着独特且重要的位置,作为首部由德勤管理咨询引进的 AI 医疗译著,它宛如一座桥梁,连接了人工智能与生物医学这两个看似独立却又紧密关联的领域。在当下智能医疗蓬勃发展但…...
SQL Server 2022常见问题解答
以下是SQL Server 2022的常见问题解答,按主题分类整理: 一、安装与升级 SQL Server 2022的系统要求是什么? 支持的操作系统:Windows Server 2016及以上、Linux(Ubuntu 20.04/22.04, RHEL 8/9等)。内存:至少4GB(建议8GB+)。磁盘空间:6GB以上,具体取决于安装组件。如何…...
SQLAlchemy关键词搜索技术深度解析:从基础过滤到全文检索
在数据驱动的应用开发中,基于关键词的模糊查询是常见的业务需求。SQLAlchemy作为Python生态中最流行的ORM框架,提供了多种实现关键词搜索的技术方案。本文将从性能、适用场景和技术复杂度三个维度,系统对比分析SQLAlchemy中关键词搜索的最佳实…...
react 15-16-17-18各版本的核心区别、底层原理及演进逻辑的深度解析
一、React 15(2016) 核心架构:Stack Reconciler(栈协调器) 工作原理: 同步递归渲染:采用深度优先遍历方式递归处理 Virtual DOM,形成不可中断的调用栈渲染流程:1. 触发 …...
[Windows] Edge浏览器_134.0.3124.83绿色便携增强版-集成官方Deepseek侧边栏
微软Edge浏览器 绿色便携增强版 长期更新 链接:https://pan.xunlei.com/s/VOMA-aVC_GPJiv-MzRS89lsVA1?pwdemxj# Edge浏览器_134.0.3124.83绿色便携增强版-集成官方Deepseek侧边栏...
STM32学习笔记之存储器映射(原理篇)
📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…...
探索PyMOL新插件NRGSuite-Qt:全面提升分子对接、结合位点预测与动力学模拟的研究效率
随着分子建模和计算生物学的快速发展,分子对接(Molecular Docking)、结合位点预测、相互作用分析以及动力学研究等领域的工具越来越重要。这些工具不仅帮助研究人员理解分子间的相互作用机制,还能加速药物设计和优化过程。NRGSuit…...
c#在work线程中怎样更新UI控件
最近笔者调试修改项目,碰到了c#在work线程中怎样更新UI控件中的场景,简单总结了下,主要有两个方法: 方法1:通过System.Windows.Application.Current.Dispatcher.Invoke来更新UI控件 System.Windows.Application.Curre…...
DeepSeek、Grok 与 ChatGPT 4.5:新一代大模型架构与推理能力深度解析
近年来,大语言模型(LLM)领域发展迅猛,DeepSeek、Grok 以及 OpenAI 最新发布的 ChatGPT 4.5 都是该领域的代表性产品。本文将从架构设计、推理能力、训练策略等方面,对三者进行技术对比,探讨其优势与潜在的应…...
从零基础到 Java 网站项目开发学习规划
在数字化时代,Java 凭借其卓越的跨平台性、强大的功能和丰富的类库,成为开发各类网站的主流编程语言。对于想要踏入 Java 网站开发领域的初学者而言,一份系统、科学的学习规划至关重要。它不仅能帮助我们有条不紊地掌握知识和技能,…...
Unity Shader 学习17:合批渲染
一、基础概念 合批主要是针对这三个概念进行优化减少: ① SetPass Call:一次渲染状态切换,也就是每次切换 材质/Pass 时,就会触发一次SetPass Call ② Draw Call:cpu 调用一次 gpu 绘制函数 ③ Batch:表示…...
【JavaSE】抽象类和接口
【JavaSE】抽象类和接口 前言:补充知识 —— 利用类和对象,交换两个数字 一、抽象类1.1 抽象类是什么?1.2 抽象类特点1.3 抽象类举例1.4 抽象类作用 二、接口2.1 接口是什么?2.2 接口的特性2.3 接口的使用规则2.4 类可以实现多个接…...
嵌入式单片机程序的映像文件解读
映像文件类型 单片机下载程序的映像文件是包含了可执行代码、数据等信息,用于将程序烧录到单片机中的文件。常见的映像文件种类如下: 十六进制文件(Hex 文件) 格式特点:Hex 文件是一种文本格式的文件,以 ASCII 字符形式存储数据。它由一系列的记录组成,每条记录包含一个…...
在 Linux(Ubuntu / CentOS 7)上快速搭建我的世界 MineCraft 服务器,并实现远程联机,详细教程
Linux 部署 MineCraft 服务器 详细教程(丐版,无需云服务器) 一、虚拟机 Ubuntu 部署二、下载 Minecraft 服务端三、安装 JRE 21四、安装 MCS manager 面板五、搭建服务器六、本地测试连接七、下载樱花,实现内网穿透,邀…...
STL之string
1.为什么学习string类 1.1 C语言中的字符串 C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且…...
cJSON-轻量级 C 语言 JSON 解析库的使用(一)
文章目录 cJSON:轻量级 C 语言 JSON 解析库的使用前言一、cJSON 简介核心特点: 二、核心数据结构解析三、深入解析 API 设计1. 解析 JSON2. 访问数据3. 构建 JSON 四、内存管理策略五、高级应用技巧1. 引用系统2. 批量操作3. 原地修改 六、性能优化技巧1…...
用Python和Stable Diffusion生成AI动画:从图像到视频的全流程指南
引言 本文将演示如何通过Python代码实现基于文本提示的AI动画生成。我们将使用Stable Diffusion生成连贯图像帧,结合OpenCV合成视频,最终实现一个可自定义的动画生成 pipeline。 一、环境准备 1. 依赖安装 # 安装核心库 pip install diffusers transformers torch numpy …...
C++ 继承:面向对象编程的核心概念(二)
文章目录 5. 继承与友元6. 继承与静态成员7. 多继承及其菱形继承问题7.1 不同的继承方式7.2 虚继承 8. 继承和组合9. 总结 书接上回:C 继承:面向对象编程的核心概念(一) 5. 继承与友元 友元关系不能继承,也就是说基类友元不能访问…...
Chaos Mesh 混沌工程平台介绍、安装及使用指南
Chaos Mesh 混沌工程平台介绍、安装及使用指南 一、Chaos Mesh 简介 Chaos Mesh 是 PingCAP 开源的云原生混沌工程平台,支持在 Kubernetes 环境中模拟各种故障场景,帮助提升系统的容错性和可恢复性。 核心特性 丰富的故障类型: 资源类&…...
每天五分钟深度学习框架PyTorch:梯度裁剪解决RNN梯度爆炸的问题
本文重点 在循环神经网络训练的过程中,有时候很容易出现梯度爆炸的情况,如果出现这种问题,我们应该怎么办?本文先来分析一下为什么会出现这种情况,然后我们在给出解决方案 梯度爆炸的原因 我们从RNN训练的反向传播算法入手,当我们使用BPTT算法训练RNN的时候,它的公式…...
批量删除 PDF 中的所有图片、所有二维码图片以及指定的某张图片
PDF 文档中我们可以插入图片、文字等多种类型的资源。在某些场景下,可能我们需要删除 PDF 文档中的图片,有可能是需要删除所有的图片,也有可能是删除固定的某些图片。那碰到这种情况,我们应该怎么处理呢?今天就给大家介…...
力扣HOT100之普通数组:53. 最大子数组和
这道题目我用贪心做的,感觉用贪心的思路比较简单,以后要是面试碰到这道题就直接用贪心好了,这道题用贪心的核心思想就是不断将数组元素i加入总和sum,如果sum比当前维护的最大值result更大,说明当前遍历到的i是正数&…...
【Qt】C++前向声明与Qt信号与槽的区别
相同点:二者都可以解决头文件相互包含的问题 一、C 前向声明 概念:前向声明是在代码里仅仅声明一个类、函数或者变量,而不给出其完整定义。例如class MyClass; 就是对 MyClass 类的前向声明。 作用:主要是为了降低编译依赖&…...
SQL-木马植入、报错注入及其他
一、读写权限确认 show global variables like %secure%; 查看mysql全局变量的配置,当输入以上命令时,结果 secure_file_priv 空的时候,任意读写 secure_file_priv 某个路径的时候,只能在规定的那个路径下读写 secure_file_pri…...
基于 PHP 内置类及函数的免杀 WebShell
前言 PHP 作为广泛使用的服务端语言,其灵活的内置类(如 DOMDocument)和文件操作机制(.ini、.inc 的自动加载),为攻击者提供了天然的隐蔽通道。通过 动态函数拼接、反射调用、加密混淆 和 伪命名空间 等手法…...
主键id设计
主键自增id 🌱 1. 自增 ID(Auto Increment ID) ✅ 特点: • 数据库自带(MySQL, PostgreSQL 都支持) • 简单易用,可读性强 • 一般作为主键自带聚簇索引(主键就是物理存储顺序&…...
文件上传绕过的小点总结(6)
14.文件上传(文件包含漏洞)二次渲染 很多服务器为了防止代码嵌入图片,通常会将上传的图片进行重新生成处理,包括文件格式转换等等,嵌入的恶意代码很容易被改掉。于是产生了二次渲染,二次渲染的原理就是找到…...
传统应用容器化迁移实践
背景介绍:从传统部署到容器化迁移的必要性 在过去的运维工作中,某企业一直依赖于传统的物理机和虚拟机部署方式。然而,随着业务的快速发展和应用规模的不断扩大,传统部署方式的局限性逐渐显现: 资源利用率低…...
混境之地1
问题描述 小蓝有一天误入了一个混境之地。 好消息是:他误打误撞拿到了一张地图,并从中获取到以下信息: 混境之地的大小为 n⋅mn⋅m,其中 # 表示这个位置很危险,无法通行,. 表示道路,可以通行。他…...
LLM 加速技术有哪些
LLM 加速技术有哪些 目录 LLM 加速技术有哪些量化(Quantization)基本原理举例剪枝(Pruning)基本原理举例动态Shape(Dynamic Shape)基本原理举例算子融合(Operator Fusion)基本原理举例量化(Quantization) 基本原理 量化是指将模型中连续取值(如32位浮点数)的参数…...
CPP从入门到入土之类和对象Ⅲ
拷贝构造函数 拷贝构造函数是一个已经存在的对象去初始化一个新的对象时,调用的函数 例如: 假设我有一个盒子,里面装了一个苹果 拷贝构造函数的特点 拷贝构造函数是构造函数的一个重载拷贝构造函数的第一个参数必须是类类型对象的引用,例如…...
安全上网沙箱:多方面解决政企私的上网问题
在数字化的浪潮中,网络已成为我们工作与生活不可或缺的一部分。然而,网络的便捷也伴随着诸多安全隐患,尤其是对于企业、个人以及政企机构而言,安全上外网成为了至关重要的课题。 隔离保护:构建安全堡垒 沙箱技术在内网…...
空转 | GetAssayData doesn‘t work for multiple layers in v5 assay.
问题分析 当我分析多个样本的时候,而我的seurat又是v5时,通常就会出现这样的报错。 错误的原因有两个: 一个是参数名有slot变成layer 一个是GetAssayData 不是自动合并多个layers,而是选择保留。 那么如果我们想合并多个样本&…...
26、web前端开发之CSS3(三)
5. 文本(Text) CSS3大大增强了对文本样式和排版的控制,使得网页设计更加灵活和多样化。本讲详细介绍CSS3中常用的文本相关属性,包括文本对齐、字体大小、行高、字母间距、单词拆分、溢出隐藏等,帮助开发者更好地控制和…...
第 8 章:使用更好的库_《C++性能优化指南》_notes
使用更好的库 第八章核心知识点解析编译与测试建议总结优化原则重点内容:第一部分:多选题(10题)第二部分:设计题答案与解析多选题答案:设计题答案示例(部分): 测试用例设…...
【面试八股】:常见的锁策略
常见的锁策略 synchronized (标准库的锁不够你用了)锁策略和 Java 不强相关,其他语言涉及到锁,也有这样的锁策略。 1. 悲观锁,乐观锁(描述的加锁时遇到的场景) 悲观锁:预测接下来…...
Apache Iceberg 解析,一文了解Iceberg定义、应用及未来发展
什么是 Iceberg? Apache Iceberg 是一种开源的 表格式(Table Format) ,专为超大规模数据分析场景设计,通过标准化数据存储规范与访问协议,解决了传统数据湖在元数据管理、事务控制、查询性能等方面的核心痛…...