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

【音视频】SDL播放PCM音频

相关API

打开音频设备

int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained); 
  • desired:期望的参数。
  • obtained:实际音频设备的参数,一般情况下设置为NULL即可。
SDL_AudioSpec
typedef struct SDL_AudioSpec {
int freq; // 音频采样率
SDL_AudioFormat format; // 音频数据格式
Uint8 channels; // 声道数: 1 单声道, 2 立体声
Uint8 silence; // 设置静音的值,因为声音采样是有符号的,所以0当然就是这个值
Uint16 samples; // 音频缓冲区中的采样个数,要求必须是2的n次
Uint16 padding; // 考虑到兼容性的一个参数
Uint32 size; // 音频缓冲区的大小,以字节为单位
SDL_AudioCallback callback; // 填充音频缓冲区的回调函数
void *userdata; // 用户自定义的数据
} SDL_AudioSpec;

播放音频

回调函数
SDL_AudioCallback
// userdata:SDL_AudioSpec结构中的用户自定义数据,一般情况下可以不用。
// stream:该指针指向需要填充的音频缓冲区。
// len:音频缓冲区的大小(以字节为单位)1024*2*2。
void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 *stream, int len);

播放音频数据

// 当pause_on设置为0的时候即可开始播放音频数据。设置为1的时候,将会播放静音的值
void SDLCALL SDL_PauseAudio(int pause_on)

实现流程

准备pcm文件

我们使用ffmpeg提取出pcm文件

ffmpeg -i input.mp4 -t 20 -codec:a pcm_s16le -ar 44100 -ac 2 -f s16le 44100_16bit_2ch.pcm

将文件放在在构建路径

在这里插入图片描述

初始化SDL音频模块

因为要用到SDL音频模块,所以这里要初始化一下

if(SDL_Init(SDL_INIT_AUDIO))    // 支持AUDIO
{fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());return ret;
}

读取文件

使用C语言以二进制方式读取音频文件

FILE *audio_fd = NULL; 
const char *path = "44100_16bit_2ch.pcm";
audio_fd = fopen(path, "rb");
if(!audio_fd)
{fprintf(stderr, "Failed to open pcm file!\n");goto _FAIL;
}

设置音频缓冲区

每次从音频文件中拿取一部分音频,读取后再去拿取,设置缓冲区大小为1024*2*2*2字节
计算逻辑如下:

  • 每帧采样点为1024
  • 音频通道数为2
  • 音频采样位深为16bit = 2byte,即2字节
  • 每次缓存2帧数据
    因此缓冲区大小为:1024*2*2*2 = 8196字节
#define PCM_BUFFER_SIZE (1024*2*2*2)
为音频缓冲区分配内存

这里使用的数据类型为uint8_t,即8位无符号整数

static uint8_t* s_audio_buf = NULL;
s_audio_buf = (uint8_t *)malloc(PCM_BUFFER_SIZE);

设置音频格式

设置SDL中音频相关接口的参数

  • 采样频率(sample rate)
  • 采样格式(format)
  • 通道数(channels)
  • 采样个数(samples)

设置其他字段:

  • 静音基准值
  • 对齐格式,不设置默认为0
  • 回调函数,用于数据读取完毕后的操作
  • 回调函数参数,如果是全局参数可以忽略
SDL_AudioSpec spec;
spec.freq = 44100;          // 采样频率
spec.format = AUDIO_S16SYS; // 采样点格式
spec.channels = 2;          // 2通道
spec.silence = 0;          //静音
spec.samples = 1024;       //采样点 
spec.callback = fill_audio_pcm; // 回调函数
spec.userdata = NULL; //回调函数参数

设置回调函数

SDL需要填充数据的时候,就会调用这个回调函数,因此我们需要在这个函数中填充数据。

  • udata之前设置为NULL,因此可以忽略不计
  • stream是需要被填充的地址
  • len是需要填充的大小

因此,我们需要先清空stream内部数据,然后将文件中读取到的数据拷贝到stream

  • SDL_MixAudio用于拷贝数据到stream,并且设置SDL_MIX_MAXVOLUME宏用于设置音量大小

在回调函数中更新读取位置信息,触发主线程循环中的再次读取信息

// 目前读取的位置
static Uint8 *s_audio_pos = NULL;
// 缓存结束位置
static Uint8 *s_audio_end = NULL;void fill_audio_pcm(void *udata, Uint8 *stream, int len)
{SDL_memset(stream, 0, len);if(s_audio_pos >= s_audio_end) // 数据读取完毕{return;}// 数据够了就读预设长度,数据不够就只读部分(不够的时候剩多少就读取多少)int remain_buffer_len = s_audio_end - s_audio_pos;len = (len < remain_buffer_len) ? len : remain_buffer_len;// 拷贝数据到stream并调整音量SDL_MixAudio(stream, s_audio_pos, len, SDL_MIX_MAXVOLUME);printf("len = %d\n", len);s_audio_pos += len;  // 移动缓存指针
}

循环读取音频数据

设置SDL读取文件后直接开始读取数据,触发回调机制

SDL_PauseAudio(0);

循环读取文件片段,更新文件的起始位置和结束为止,直到文件读取完毕后退出循环

// 目前读取的位置
static Uint8 *s_audio_pos = NULL;
// 缓存结束位置
static Uint8 *s_audio_end = NULL;while(1){// 从文件读取PCM数据read_buffer_len = fread(s_audio_buf, 1, PCM_BUFFER_SIZE, audio_fd);if(read_buffer_len == 0){break;}data_count += read_buffer_len; // 统计读取的数据总字节数printf("now playing %10d bytes data.\n",data_count);s_audio_end = s_audio_buf + read_buffer_len;    // 更新buffer的结束位置s_audio_pos = s_audio_buf;  // 更新buffer的起始位置//the main thread wait for a momentwhile(s_audio_pos < s_audio_end){SDL_Delay(10);  // 等待PCM数据消耗}}

需要计算每次回调的时间,目的是让出时间给CPU休眠,因为只有回调函数结束的时候,才会满足s_audio_pos < s_audio_end
得出的时间为:1024 / 44.1k = 0.23ms,可以设置短一点,这里就设置为10ms,休眠后检查是否需要再次读取文件数据即可。

关闭设备和清空内存

播放结束后,需要关闭SDL音频设备和音频文件,并且退出SDL子系统

SDL_CloseAudio();if(s_audio_buf)free(s_audio_buf);if(audio_fd)fclose(audio_fd);SDL_Quit();

完整代码

main.c

/*** SDL2播放PCM** Darren 326873713* 326873713@qq.com* 腾讯课堂-零声学院:https://ke.qq.com/course/468797** 本程序使用SDL2播放PCM音频采样数据。SDL实际上是对底层绘图* API(Direct3D,OpenGL)的封装,使用起来明显简单于直接调用底层* API。* 测试的PCM数据采用采样率44.1k, 采用精度S16SYS, 通道数2** 函数调用步骤如下:** [初始化]* SDL_Init(): 初始化SDL。* SDL_OpenAudio(): 根据参数(存储于SDL_AudioSpec)打开音频设备。* SDL_PauseAudio(): 播放音频数据。** [循环播放数据]* SDL_Delay(): 延时等待播放完成。**/#include <stdio.h>
#include <SDL.h>
#include<stdlib.h>
#include <unistd.h>// 每次读取2帧数据, 以1024个采样点一帧 2通道 16bit(2字节)采样点为例
#define PCM_BUFFER_SIZE (1024*2*2*2)// 音频PCM数据缓存
static Uint8 *s_audio_buf = NULL;
// 目前读取的位置
static Uint8 *s_audio_pos = NULL;
// 缓存结束位置
static Uint8 *s_audio_end = NULL;//音频设备回调函数
void fill_audio_pcm(void *udata, Uint8 *stream, int len)
{SDL_memset(stream, 0, len);if(s_audio_pos >= s_audio_end) // 数据读取完毕{return;}// 数据够了就读预设长度,数据不够就只读部分(不够的时候剩多少就读取多少)int remain_buffer_len = s_audio_end - s_audio_pos;len = (len < remain_buffer_len) ? len : remain_buffer_len;// 拷贝数据到stream并调整音量SDL_MixAudio(stream, s_audio_pos, len, SDL_MIX_MAXVOLUME);printf("len = %d\n", len);s_audio_pos += len;  // 移动缓存指针
}// 提取PCM文件
// ffmpeg -i input.mp4 -t 20 -codec:a pcm_s16le -ar 44100 -ac 2 -f s16le 44100_16bit_2ch.pcm
// 测试PCM文件
// ffplay -ar 44100 -ac 2 -f s16le 44100_16bit_2ch.pcm
#undef main
int main(int argc, char *argv[])
{int ret = -1;FILE *audio_fd = NULL;SDL_AudioSpec spec;const char *path = "44100_16bit_2ch.pcm";// 每次缓存的长度size_t read_buffer_len = 0;//SDL initializeif(SDL_Init(SDL_INIT_AUDIO))    // 支持AUDIO{fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());return ret;}//打开PCM文件audio_fd = fopen(path, "rb");if(!audio_fd){fprintf(stderr, "Failed to open pcm file!\n");goto _FAIL;}s_audio_buf = (uint8_t *)malloc(PCM_BUFFER_SIZE);// 音频参数设置SDL_AudioSpecspec.freq = 44100;          // 采样频率spec.format = AUDIO_S16SYS; // 采样点格式spec.channels = 2;          // 2通道spec.silence = 0;spec.samples = 1024;       // 23.2ms -> 46.4ms 每次读取的采样数量,多久产生一次回调和 samplesspec.callback = fill_audio_pcm; // 回调函数spec.userdata = NULL;//打开音频设备if(SDL_OpenAudio(&spec, NULL)){fprintf(stderr, "Failed to open audio device, %s\n", SDL_GetError());goto _FAIL;}//play audioSDL_PauseAudio(0);int data_count = 0;while(1){// 从文件读取PCM数据read_buffer_len = fread(s_audio_buf, 1, PCM_BUFFER_SIZE, audio_fd);if(read_buffer_len == 0){break;}data_count += read_buffer_len; // 统计读取的数据总字节数printf("now playing %10d bytes data.\n",data_count);s_audio_end = s_audio_buf + read_buffer_len;    // 更新buffer的结束位置s_audio_pos = s_audio_buf;  // 更新buffer的起始位置//the main thread wait for a momentwhile(s_audio_pos < s_audio_end){SDL_Delay(10);  // 等待PCM数据消耗}}printf("play PCM finish\n");// 关闭音频设备SDL_CloseAudio();_FAIL://release some resourcesif(s_audio_buf)free(s_audio_buf);if(audio_fd)fclose(audio_fd);//quit SDLSDL_Quit();return 0;
}

更多资料

更多资料参考:https://github.com/0voice

相关文章:

【音视频】SDL播放PCM音频

相关API 打开音频设备 int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained); desired&#xff1a;期望的参数。obtained&#xff1a;实际音频设备的参数&#xff0c;一般情况下设置为NULL即可。 SDL_AudioSpec typedef struct SDL_AudioSpec { i…...

FATFS文件系统配置

1、FatFs模块功能配置选项参考ffconf.h函数配置链接&#xff1a;FatFs模块功能配置选项 2、FATFS配置 FATFS 支持长文件名链接: FATFS&#xff1a;配置 FATFS 支持长文件名 3、 FATFS移植链接1 4、 FATFS移植链接2 5、FAT32 和 FATFS 是两个不同层次的概念&#xff0c;分别属于…...

JVM 字节码是如何存储信息的?

JVM 字节码是 Java 虚拟机 (JVM) 执行的指令集&#xff0c;它是一种与平台无关的二进制格式&#xff0c;在任何支持 JVM 的平台上都可运行的Java 程序。 字节码存储信息的方式&#xff0c;主要通过以下几个关键组成部分和机制来实现&#xff1a; 1. 指令 (Opcodes) 和 操作数 …...

Linux:多路转接(上)——select

目录 一、select接口 1.认识select系统调用 2.对各个参数的认识 二、编写select服务器 一、select接口 1.认识select系统调用 int select(int nfds, fd_set readfds, fd_set writefds, fd_set exceptfds, struct timeval* timeout); 头文件&#xff1a;sys/time.h、sys/ty…...

如何解决DDoS攻击问题 ?—专业解决方案深度分析

本文深入解析DDoS攻击面临的挑战与解决策略&#xff0c;提供了一系列防御技术和实践建议&#xff0c;帮助企业加强其网络安全架构&#xff0c;有效防御DDoS攻击。从攻击的识别、防范措施到应急响应&#xff0c;为网络安全工作者提供了详细的操作指引。 DDoS攻击概览&#xff1a…...

机器学习Python实战-第三章-分类问题-3.决策树算法

目录 3.3.1 原理简介 3.3.2 算法步骤 3.3.3 实战 3.3.4 实验 前半部分是理论介绍&#xff0c;后半部分是代码实践&#xff0c;可以选择性阅读。 决策树&#xff08;decision tree&#xff09;是功能强大而且相当受欢迎的分类和预估方法&…...

Spring三级缓存学习

Spring的三级缓存机制主要用于解决单例Bean的循环依赖问题。其核心在于提前暴露Bean的引用&#xff0c;允许未完全初始化的对象被其他Bean引用。以下是三级缓存的详细说明及其解决循环依赖的原理&#xff1a; 三级缓存结构 一级缓存&#xff08;singletonObjects&#xff09; 存…...

欧拉函数φ

函数作用 计算 1 1 1 ~ n n n中有多少个与 n n n互质的数。 函数公式 φ ( n ) n p 1 − 1 p 1 p 2 − 1 p 2 … … p m − 1 p m φ(n)n\times\frac{p_1-1}{p_1}\times\frac{p_2-1}{p_2}\times……\times\frac{p_m-1}{p_m} φ(n)np1​p1​−1​p2​p2​−1​……pm​p…...

蓝桥杯刷题指南

蓝桥杯是中国普及性最好的计算机程序设计竞赛之一&#xff0c;参加者包括大学生、高中生和草根程序员等各个群体。通过刷题来提升自己的编程能力是参加蓝桥杯比赛的常见做法。下面是一些蓝桥杯常见的题型和刷题技巧&#xff0c;希望对大家有所帮助。 基础入门题目&#xff1a;…...

ctfshow WEB web12

发现只有这样一句话&#xff0c;应该是要看页面源代码的&#xff0c;右键查看页面源代码 发现可能存在代码执行漏洞&#xff0c;拼接一个?cmdphpinfo(); 成功显示出php信息, 说明存在代码执行漏洞 接下来遍历目录&#xff0c;我们要用到一个函数 glob() glob() 函数可以查找…...

ChromeOS 135 版本更新

ChromeOS 135 版本更新 一、ChromeOS 135 更新内容 1. ChromeOS 电池寿命优化策略 为了延长 Chromebook 的使用寿命&#xff0c;ChromeOS 135 引入了一项全新的电池充电限制策略 —— DevicePowerBatteryChargingOptimization&#xff0c;可提供更多充电优化选项&#xff0c…...

redis的缓存

redis的缓存 一.缓存简介1.缓存2.redis作为数据库&#xff08;MySQL&#xff09;缓存的原因 二.缓存更新策略1.定期生成2.实时生成3.内存淘汰策略1&#xff09;FIFO(First In First Out) 先进先出2&#xff09;LRU(Least Recently Used)淘汰最久未使用的3&#xff09;LFU(Least…...

字符串与相应函数(上)

字符串处理函数分类 求字符串长度&#xff1a;strlen长度不受限制的字符串函数&#xff1a;strcpy,strcat,strcmp长度受限制的字符串函数:strncpy,strncat,strncmp字符串查找&#xff1a;strstr,strtok错误信息报告&#xff1a;strerror字符操作&#xff0c;内存操作函数&…...

【微知】Mellanox网卡网线插入后驱动的几个日志?(Cable plugged;IPv6 ... link becomes ready)

概要 本文是一个简单的信息记录。记录的是当服务器网卡的光模块插入后内核的日志打印。通过这种日志打印&#xff0c;可以在定位分析问题的时候&#xff0c;知道进行过一次模块插拔。 日志 截图版&#xff1a; 文字版&#xff1a; [32704.121294] mlx5_core 0000:01:00.0…...

spring security oauth2.0的四种模式

OAuth 2.0 定义了 4 种授权模式&#xff08;Grant Type&#xff09;&#xff0c;用于不同场景下的令牌获取。以下是每种模式的详细说明、适用场景和对比&#xff1a; 一、授权码模式&#xff08;Authorization Code Grant&#xff09; 适用场景 • Web 应用&#xff08;有后端…...

MyBatis-Plus 核心功能

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、条件构造器1、核心 Wrapper 类型基础查询示例SQL 查询使用 QueryWrapper 实现查询 更新操作示例场景一&#xff1a;基础更新SQL 查询使用 QueryWrapper 实现更新…...

阿里云实时计算Flink版产品体验测评

阿里云实时计算Flink版产品体验测评 什么是阿里云实时计算Flink应用场景实时计算Flink&自建Flink集群性价比开发效率运维管理企业安全 场景落地 什么是阿里云实时计算Flink 实时计算Flink大家可能并不陌生&#xff0c;在实时数据处理上&#xff0c;可能会有所接触&#xf…...

少儿编程 scratch四级真题 2025年3月电子学会图形化编程等级考试Scratch四级真题解析(判断题)

2025年3月scratch编程等级考试四级真题 判断题&#xff08;共10题&#xff0c;每题2分&#xff0c;共20分&#xff09; 11、小圆点角色的程序如下左图所示&#xff0c;程序运行后的效果如下右图所示&#xff0c;自制积木中又调用了自己&#xff0c;这种算法叫做递归。 答案&a…...

【连载3】基础智能体的进展与挑战综述

基础智能体的进展与挑战综述 从类脑智能到具备可进化性、协作性和安全性的系统 【翻译团队】刘军(liujunbupt.edu.cn) 钱雨欣玥 冯梓哲 李正博 李冠谕 朱宇晗 张霄天 孙大壮 黄若溪 2. 认知 人类认知是一种复杂的信息处理系统&#xff0c;它通过多个专门的神经回路协调运行…...

Schaefer 400图谱

图谱下载&#xff1a; https://github.com/ThomasYeoLab/CBIG/tree/master/stable_projects/brain_parcellation/Schaefer2018_LocalGlobal/Parcellations/MNI 图 &#xff08;第一行&#xff09;显示了 Yeo et al. &#xff08;2011&#xff09; 的 7 网络和 17 网络分包。图…...

通过uri获取文件路径手机适配

青铜版本 return contentResolver.query(this, arrayOf(MediaStore.MediaColumns.DATA), null, null).let {if (it?.moveToFirst() true) {val columnIndex it.getColumnIndex(MediaStore.MediaColumns.DATA)val path it.getString(columnIndex)it.close()return path}&quo…...

Ubuntu 22.04 完美安装 ABAQUS 教程:从零到上手,解决兼容问题

教程概述与安装准备 本教程详细介绍了在 Ubuntu 22.04 系统上安装 ABAQUS 2023 及 ifort 2021 的步骤,并实现用户子程序的链接。教程同样适用于 ABAQUS 2021(需相应调整文件名和路径)以及 Ubuntu 18.04 至 22.04 系统,尽管未在所有版本上测试。需要注意的是,Intel 的 One…...

雷池WAF防火墙如何构筑DDoS防护矩阵?——解读智能语义解析对抗新型流量攻击

本文深度解析雷池WAF防火墙在DDoS攻防中的技术突破&#xff0c;通过智能语义解析、动态基线建模、协同防护体系三大核心技术&#xff0c;实现从流量特征识别到攻击意图预判的进化。结合2023年金融行业混合攻击防御案例&#xff0c;揭示新一代WAF如何通过协议级漏洞预判与AI行为…...

Linux权限理解

1.shell命令以及运行原理 下面来介绍一个话题&#xff0c;关于指令的运行原理&#xff0c;这里先简单理解就可以。当我们登上Linux后&#xff1a; yxx这里称之为用户名&#xff0c;VM-8-2-centos是主机名&#xff0c;~是当前目录&#xff0c;$是命令行提示符。 其中我们把上面的…...

使用labelme进行实例分割标注

前言 最近在学习实例分割算法&#xff0c;参考b站视频课教程&#xff0c;使用labelme标注数据集&#xff0c;在csdn找到相关教程进行数据集格式转换&#xff0c;按照相关目标检测网络对数据集格式的训练要求划分数据集。 1.使用labelme标注图片 在网上随便找了几张蘑菇图片&am…...

策略模式实现 Bean 注入时怎么知道具体注入的是哪个 Bean?

Autowire Resource 的区别 1.来源不同&#xff1a;其中 Autowire 是 Spring2.5 定义的注解&#xff0c;而 Resource 是 Java 定义的注解 2.依赖查找的顺序不同&#xff1a; 依赖注入的功能&#xff0c;是通过先在 Spring IoC 容器中查找对象&#xff0c;再将对象注入引入到当…...

PromptUp 网站介绍:AI助力,轻松创作

1. 网站定位与核心功能 promptup.net 可能是一个面向 创作者、设计师、营销人员及艺术爱好者 的AI辅助创作平台,主打 零门槛、智能化的内容生成与优化。其核心功能可能包括: AI艺术创作:通过输入关键词、选择主题或拖放模板,快速生成风格多样的数字艺术作品(如插画、海报…...

软件架构评估利器:质量效用树全解析

质量效用树是软件架构评估中的一种重要工具&#xff0c;它有助于系统地分析和评估软件架构在满足各种质量属性方面的表现。以下是关于质量效用树的详细介绍&#xff1a; 一、定义与作用 质量效用树是一种以树形结构来表示软件质量属性及其相关效用的模型。它将软件的质量目标…...

XILINX DDR3专题---(1)IP核时钟框架介绍

1.什么是Reference Clock&#xff0c;这个时钟一定是200MHz吗&#xff1f; 2.为什么APP_DATA是128bit&#xff0c;怎么算出来的&#xff1f; 3.APP &#xff1a;MEM的比值一定是1:4吗&#xff1f; 4.NO BUFFER是什么意思&#xff1f; 5.什么情况下Reference Clock的时钟源可…...

ubuntu 2204 安装 vcs 2018

安装评估 系统 : Ubuntu 22.04.1 LTS 磁盘 : ubuntu 自身占用了 9.9G , 按照如下步骤 安装后 , 安装后的软件 占用 13.1G 仓库 : 由于安装 libpng12-0 , 添加了一个仓库 安装包 : 安装了多个包(lsb及其依赖包 libpng12-0)安装步骤 参考 ubuntu2018 安装 vcs2018 安装该…...

Python与去中心化存储:从理论到实战的全景指南【无标题】

Python与去中心化存储:从理论到实战的全景指南 随着区块链技术和Web3理念的兴起,去中心化存储逐渐成为构建新型互联网的核心模块之一。传统中心化存储的模式存在易被攻击、单点故障和高昂成本等问题,而去中心化存储通过分布式架构实现了更高的安全性、可靠性和数据透明度。…...

C++语言程序设计——01 C++程序基本结构

目录 编程语言一、C程序执行过程二、C基础框架三、输出语句cout换行 四、注释方法 编程语言 我们知道c是一门编程语言&#xff0c;它是在c语言的基础上发展而来&#xff0c;添加了类、对象、继承、多态等概念&#xff0c;我们可以称为它是一种面向对象编程的语言。 不过在学习…...

Unity UI中的Pixels Per Unit

Pixels Per Unit在图片导入到Unity的时候&#xff0c;将图片格式设置为Sprite的情况下会出现&#xff0c;其意思是精灵中的多少像素对应世界中的一个单位&#xff0c;默认是100 1. 对于在世界坐标中 在世界坐标中&#xff0c;一般对于Sprite的应用是Sprite Renderer组件 使…...

(十八)安卓开发中的后端接口调用详讲解

在安卓开发中&#xff0c;后端接口调用是连接移动应用与服务器的重要环节&#xff0c;用于实现数据的获取、提交和处理。本文将详细讲解安卓开发中后端接口调用的步骤&#xff0c;结合代码示例和具体的使用场景&#xff0c;帮助你全面理解这一过程。 什么是后端接口&#xff1f…...

使用freebsd-update 升级FreeBSD从FreeBSD 14.1-RELEASE-p5到FreeBSD 14.2-RELEASE

使用freebsd-update 升级FreeBSD从FreeBSD 14.1-RELEASE-p5到FreeBSD 14.2-RELEASE 先升级小版本 准备升级前&#xff0c;先把当前的小版本升级到顶&#xff0c;比如现在是FreeBSD 14.1-RELEASE-p5&#xff0c;先升级到最新的14.1版本&#xff0c;使用命令&#xff1a; # fr…...

基础排序算法(三傻排序)

1. 选择排序 原理&#xff1a;每次从未排序部分选出最小&#xff08;或最大&#xff09;元素&#xff0c;放到已排序部分的末尾。时间复杂度&#xff1a;O(n)&#xff0c;效率低但实现简单&#xff0c;适合小规模数据。 //选择排序public static void selectSort(int[] arr){i…...

五分钟了解智能体

在2025年人工智能技术全面渗透社会的背景下&#xff0c;“智能体”&#xff08;Agent&#xff09;已成为推动第四次工业革命的核心概念之一。从自动驾驶汽车到医疗诊断系统&#xff0c;从智能家居中枢到金融量化交易平台&#xff0c;智能体正在重构人类与技术交互的方式。本文将…...

【机器学习】笔记| 通俗易懂讲解:生成模型和判别模型|01

博主简介&#xff1a;努力学习的22级计算机科学与技术本科生一枚&#x1f338;博主主页&#xff1a; Yaoyao2024往期回顾&#xff1a;【科研小白系列】这些基础linux命令&#xff0c;你都掌握了嘛&#xff1f;每日一言&#x1f33c;: “脑袋想不明白的&#xff0c;就用脚想”—…...

Jieba分词的原理及应用(三)

前言 “结巴”中文分词&#xff1a;做最好的 Python 中文分词组件 上一篇文章讲了使用TF-IDF分类器范式进行企业级文本分类的案例。其中提到了中文场景不比英文场景&#xff0c;在喂给模型之前需要进行分词操作。 分词的手段有很多&#xff0c;其中最常用的手段还是Jieba库进行…...

神经网络背后的数学原理

神经网络背后的数学原理 数学建模神经网络数学原理 数学建模 标题民科味道满满。其实这篇小短文就是自我娱乐。 物理世界是物种多样&#xff0c;千姿百态。可以从不同的看待眼中的世界&#xff0c;包括音乐、绘画、舞蹈、雕塑等各种艺术形式。但这些主观的呈现虽然在各人眼中…...

常用图像滤波及色彩调节操作(Opencv)

1. 常用滤波/模糊操作 import cv2 import numpy as np import matplotlib.pyplot as plotimg cv2.imread("tmp.jpg") img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_g cv2.GaussianBlur(img, (7,7), 0) img_mb cv2.medianBlur(img, ksize7) #中指滤波 img_bm …...

FFMPEG和opencv的编译

首先 sudo apt-get update -qq && sudo apt-get -y install autoconf automake build-essential cmake git-core libass-dev libfreetype6-dev libgnutls28-dev libmp3lame-dev libsdl2-dev libtool libva-dev libvdpau-dev libvorbis-de…...

用户登录不上linux服务器

一般出现这种问题&#xff0c;重新用root用户修改lsy用户的密码即可登录&#xff0c;但是当修改了还是登录不了的时候&#xff0c;去修改一个文件用root才能修改&#xff0c; 然后在最后添加上改用户的名字&#xff0c;例如 原本是只有user的&#xff0c;现在我加上了lsy了&a…...

【项目管理】第11章 项目成本管理-- 知识点整理

相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 (一)知识总览 项目管理知识域 知识点: (项目管理概论、立项管理、十大知识域、配置与变更管理、绩效域) 对应:第6章-第19章 ​ ​ (二)知识笔记​ 第11章 项目成本管理 ​ 1.管理基础…...

Python中的strip()

文章目录 基本语法&#xff1a;示例&#xff1a;1. 默认移除空白字符&#xff1a;2. 移除指定字符&#xff1a;3. 不修改原字符串&#xff1a; 相关方法&#xff1a;示例&#xff1a; 注意事项&#xff1a; 在 Python 中&#xff0c; strip() 是一个字符串方法&#xff0c;用于…...

设计模式 Day 9:命令模式(Command Pattern)完整讲解与实战应用

&#x1f504; 回顾 Day 8&#xff1a;策略模式 在 Day 8 中我们讲解了策略模式&#xff1a; 用于封装多个可切换的算法逻辑&#xff0c;让调用者在运行时选择合适的策略。它强调的是“行为选择”&#xff0c;是针对“算法或行为差异”而设计。通过 PaymentStrategy、路径规划…...

【正点原子】STM32MP257 同构多核架构下的 ADC 电压采集与处理应用开发实战

在嵌入式系统中&#xff0c;ADC模拟电压的读取是常见的需求。如何高效、并发、且可控地完成数据采集与处理&#xff1f;本篇文章通过双线程分别绑定在 Linux 系统的不同 CPU 核心上&#xff0c;采集 /sys/bus/iio 接口的 ADC 原始值与缩放系数 scale&#xff0c;并在另一个核上…...

区块链从专家到小白

文章目录 含义应用场景典型特征 含义 以非对称加密算法为基础。 每个**区块&#xff08;Block&#xff09;**包含&#xff1a; ​交易数据​&#xff08;如转账记录、合约内容&#xff09;。 ​时间戳​&#xff08;记录生成时间&#xff09;。 ​哈希值​&#xff08;当前区…...

记录centos8安装宝塔过程(两个脚本)

1、切换系统源&#xff08;方便使用宝塔安装脚本下载&#xff09; bash <(curl -sSL https://linuxmirrors.cn/main.sh) 2、宝塔安装脚本在宝塔的官网 宝塔面板下载&#xff0c;免费全能的服务器运维软件 根据自己的系统选择相应的脚本 urlhttps://download.bt.cn/insta…...

DAY 42 leetcode 151--哈希表.反转字符串中的单词

题号151 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 我的解法 暴力解法&#xff0c;先将String转为字…...