⾳频重采样在 audio_decode_frame() 中实现, audio_decode_frame() 就是从⾳频frame队列中取出⼀个frame,按指定格式经过重采样后输出(解码不是在该函数进⾏)。
重采样的细节很琐碎,直接看注释:
static int audio_decode_frame(VideoState *is)
{
int data_size, resampled_data_size;
int64_t dec_channel_layout;
av_unused double audio_clock0;
int wanted_nb_samples;
Frame *af;
if (is->paused)
return -1;
do {
#if defined(_WIN32)
while (frame_queue_nb_remaining(&is->sampq) == 0) {
if ((av_gettime_relative() - audio_callback_time) >
1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
return -1;
av_usleep (1000);
}
#endif
// 若队列头部可读,则由af指向可读帧
if (!(af = frame_queue_peek_readable(&is->sampq)))
return -1;
frame_queue_next(&is->sampq);
} while (af->serial != is->audioq.serial);
// 根据farme中指定的音频参数获取缓冲区的大小
data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
af->frame->nb_samples,
af->frame->format, 1);
// 获取声道布局
dec_channel_layout =
(af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
if (af->frame->format != is->audio_src.fmt ||
dec_channel_layout != is->audio_src.channel_layout ||
af->frame->sample_rate != is->audio_src.freq ||
(wanted_nb_samples != af->frame->nb_samples &&
!is->swr_ctx)) {
swr_free(&is->swr_ctx);
is->swr_ctx = swr_alloc_set_opts(NULL,
is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
dec_channel_layout, af->frame->format, af->frame->sample_rate,
0, NULL);
if (!is->swr_ctx || swr_init(is->swr_ctx) <
0) {
av_log(NULL, AV_LOG_ERROR,
"Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
swr_free(&is->swr_ctx);
return -1;
}
is->audio_src.channel_layout = dec_channel_layout;
is->audio_src.channels = af->frame->channels;
is->audio_src.freq = af->frame->sample_rate;
is->audio_src.fmt = af->frame->format;
}
if (is->swr_ctx) {
const uint8_t **in = (const uint8_t **)af->frame->extended_data;
uint8_t **out = &is->audio_buf1;
int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
int len2;
if (out_size <
0) {
av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
return -1;
}
if (wanted_nb_samples != af->frame->nb_samples) {
if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) <
0) {
av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
return -1;
}
}
av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
if (!is->audio_buf1)
return AVERROR(ENOMEM);
len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
if (len2 <
0) {
av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
return -1;
}
if (len2 == out_count) {
av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
if (swr_init(is->swr_ctx) <
0)
swr_free(&is->swr_ctx);
}
// 重采样返回的⼀帧⾳频数据⼤⼩(以字节为单位)
is->audio_buf = is->audio_buf1;
resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
} else {
// 未经过重采样,则将指针指向frame中的音频数据
is->audio_buf = af->frame->data[0];
resampled_data_size = data_size;
}
audio_clock0 = is->audio_clock;
/* update the audio clock with the pts */
if (!isnan(af->pts))
is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
else
is->audio_clock = NAN;
is->audio_clock_serial = af->serial;
#ifdef DEBUG
{
static double last_clock;
printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
is->audio_clock - last_clock,
is->audio_clock, audio_clock0);
last_clock = is->audio_clock;
}
#endif
return resampled_data_size;
}
样本补偿
swr_set_compensation说明
/**
* @}
*
* @name Low-level option setting functions
* These functons provide a means to set low-level options that is not possible
* with the AVOption API.
* @{
*/
/**
* Activate resampling compensation ("soft" compensation). This function is
* internally called when needed in swr_next_pts().
*
* @param[in,out] s allocated Swr context. If it is not initialized,
* or SWR_FLAG_RESAMPLE is not set, swr_init() is
* called with the flag set.
每个样本增量,单位pts
* @param[in] sample_delta delta in PTS per sample
要补偿的样本数
* @param[in] compensation_distance number of samples to compensate for
* @return >= 0 on success, AVERROR error codes if:
* @li @c s is NULL,
* @li @c compensation_distance is less than 0,
* @li @c compensation_distance is 0 but sample_delta is not,
* @li compensation unsupported by resampler, or
* @li swr_init() fails when called.
*/
int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance);
参考资料:https://github.com/0voice
相关文章:
ffplay音频重采样 - 教程
ffplay音频重采样 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-size:…...
devexpress gridcontrol表格知识
过滤 高亮显示 ,不过滤非匹配行行选择,单行编辑 活动行着色 保存...
深入解析:Qt串口通信学习
深入解析:Qt串口通信学习pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-size…...
字符串算法笔记
记号约定:\(|s|\):字符串 \(s\) 的长度。 \(\mathbb{S}\):字符串集。 \(\Sigma\):字符集。一些约定:下标从 \(0\) 开始。1. 哈希 1.1 定义 我们想要快速求出字符串 \(s\) 是否等于 \(t\)。 如果 \(|s| \neq |t|\),那么一定不相等,所以令 \(|s| = |t| = n\)。那么有 \(O(…...
【光照】Unity[经验模型]和[物理模型]
Unity URP(Universal Render Pipeline)中的光照模型BRDF(双向反射分布函数)是PBR(基于物理的渲染)的核心组成部分,用于模拟真实世界的光照交互。【从UnityURP开始探索游戏渲染】专栏-直达一、BRDF发展历史(时间线)1971年:Bouknight提出首个光反射模型,引入Lambe…...
实用指南:浅聊一下Redisson分布式锁
实用指南:浅聊一下Redisson分布式锁pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important;…...
JavaScript起源
为什么学习 JavaScript? JavaScript 是 web 开发人员必须学习的 3 门语言中的一门:HTML 定义了网页的内容 CSS 描述了网页的布局 JavaScript 控制了网页的行为本教程是关于 JavaScript 及介绍 JavaScript 如何与 HTML 和 CSS 一起工作。谁适合阅读本教程? 1. 如果您想学习 J…...
9.14做题随记
OI学习,宁可不学不可逆向,要么知道题目怎么做后学习代码写法,要么知道代码基础学习题目怎么做,要么两种都会学习另外一种解法,万万不可逆向学习,费心费力。P1678 烦恼的高考志愿 题目背景 计算机竞赛小组的神牛 V 神终于结束了高考,然而作为班长的他还不能闲下来,班主任…...
树-学习笔记
定义:一个树是由n个元素组成的有限集合。其中,每个元素叫结点(node) 性质:有一个特殊的结点叫根节点(root node) 从图论的角度,一个树有n-1条边,所以它是无环的。同时,它是连通的,因为可以直接或间接地从一个结点走到另一个结点 除了根结点以外,其余的结点可以分成m(m&…...
centos 安装 postgresql 数据库
* 安装必要的工具yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm* 移除可能冲突的默认 PostgreSQL 模块(如有)yum remove -y postgresql** 查看 postgresql 版本yum list postgresql** 按 y 一直安…...
个人问题反省--致命问题(急需解决)
目前尝试投了几家距离较远的公司,但是沟通均未深入,所以停止盲目投递,跳脱出来反思个人问题。...
STM32 HAL学习笔记:EC11的使用和定时器中编码器模式的中断
本文使用STM32Cube软件包提供的驱动对EC11进行读取,包含部分电路原理图和代码。背景 之前买了一个EC11,想要拿来实现音量调节之类的功能,现在终于有时间研究了。 原理图 一开始R1、R2、R3选择的是100k,测试发现下降沿只有几百纳秒,但上升沿过于平缓,如下图,旋转较快时容…...
题解:P12546 [UOI 2025] Convex Array
目前暂无修正。 % 你赛出了这题,赛后补题参照FFTotoro的题解详细化了一下具体转移过程及思路,在此感谢原作者(怎么套娃了)。 不难得出题意等价于找出两个不同的序列使得相邻两数差单调不降,两个序列的并集为原序列集合(可重集),两个序列的交集为升序排序后的 \(\{a_1\}…...
Java并发编程(1)
基础 1、并行跟并发的区别 并行:同一时刻,多个线程都在执行,这就要求有多个CPU分别执行多个线程。 并发:在同一时刻,只有一个线程执行,但在一个时间段内,两个线程都执行了。其实现依赖于CPU切换线程,因为切换时间很短,所以基本对于用户是无感知的。2、什么是进程和线程…...
玩转 hostnamectl set-hostname:Linux 主机名管理的优雅方式 - 实践
玩转 hostnamectl set-hostname:Linux 主机名管理的优雅方式 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier Ne…...
DES原理与举例说明
DES原理与举例说明一、DES 核心原理:6 大关键步骤 DES 的加密过程可拆解为 “初始置换→密钥扩展→16 轮迭代→逆初始置换” 四大阶段,其中 16 轮迭代是加密的核心,每轮又包含 “扩展置换、异或、S 盒替换、P 盒置换”4 个步骤。整体流程如下: 1. 预处理:明文初始置换(IP…...
Spring八股文 - 实践
Spring八股文 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-size: 14p…...
Morpheus 审计报告分享2:ChianLink 数据源有着不同的“心跳”
漏洞信息 漏洞报告https://code4rena.com/audits/2025-08-morpheus/submissions/S-709漏洞代码https://github.com/code-423n4/2025-08-morpheus/blob/a65c254e4c3133c32c05b80bf2bd6ff9eced68e2/contracts/capital-protocol/ChainLinkDataConsumer.sol#L78-L107漏洞背景 Heart…...
「嘶吼」第一章:吃饭睡觉打豆豆
标准的鹅蛋脸圆圆的,瞪着一双大眼,大双眼皮显得格外精神,小肚子微微隆起,头发及腰,常常梳着高马尾。因为从小营养过剩,她个子在幼儿园里偏高,跑得快,力气大,小胳膊小腿扑腾起来可折腾人了,用不完的精力都用在调皮捣蛋上了。小胖妞?这无疑是对李鹤然最好的形容。一岁…...
Clion 基础设置
切换中英文切换老 UI 在 CLion 2024.2 及更高版本中,旧版 UI 已不再作为内置选项,而是通过插件提供。...
《Vuejs设计与实现》第 16 章(解析器) 上 - 教程
《Vuejs设计与实现》第 16 章(解析器) 上 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospac…...
go代码(1)
package main import "fmt" func main() { fmt.Println("hello world") } 运行: $ go run hello-world.go hello world $ go build hello-world.go $ ls hello-world hello-world.go $ ./hello-world hello world本文来自博客园,作者:gosamuel,转载…...
7种常见的入侵检测系统规避技术解析
本文详细解析了攻击者常用的7种入侵检测系统(IDS)规避技术,包括文件恶意软件、混淆技术、IP分片、源路由等,并提供了相应的缓解措施,帮助企业安全团队加强网络防护。7种常见的入侵检测系统规避技术 恶意攻击者使用各种规避策略渗透网络,而入侵检测系统(IDS)却未能察觉。了解…...
js的引用
js代码 JavaScript又称ECMAScript,常用的版本通常有es5以及es6 元素中的代码 a元素除了能定义链接地址,同样可以定义js <a href="javascript:window.alert(hello)">Hello</a>我们可以通过按钮的单击事件实现上面相同的效果,其中事件也就是什么情况下执…...
P3957 [NOIP 2017 普及组] 跳房子
题目描述 给出 \(n\) 个点的坐标 \(a_i\) 和权值 \(s_i\),每次向右移动正距离 \(p\),满足 \(d-x \le p \le d+x\) 且落在给定的点上,求使经过点值的最大和不小于 \(k\) 的最小 \(x\)。 思路 step1-二分答案 这道题我们要求的是最小的 \(x\),可显然我们无法将 \(x\) 设计到状…...
C++中常用的STL容器
C++中常用的STL容器: Vector:变长数组:数组长度是可以动态变化的,倍增 Pair<X,Y>:二元组:前后两个元素类型可以不同 string:字符串:常见的函数:substr()截取一段字串,c_str()返回字符串的头指针 queue:队列:先进先出,push()插入,pop() 弹出,front() 返回…...
我的数据科学探索之旅:从兴趣到公考与学习计划
一.关于我:不止于代码的多面手我的兴趣:在热爱里收获成长 生活中的我,总喜欢在艺术相关的领域折腾。从初中开始,我就爱上了跳舞,第一次跟着视频练基础动作时,肢体僵硬得像 “机器人”,连简单的 wave 都做不流畅,反复练习后还总跟不上节奏。但我没放弃,每周坚持练 3 …...
MySQL 核心记录解析:从配置到存储的 “说明书 + 记录仪” 系统
MySQL 核心记录解析:从配置到存储的 “说明书 + 记录仪” 系统pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New&quo…...
JavaScript Array 对象
JavaScript 中的 Array 对象是用于存储多个值的特殊类型的对象。 Array 是按顺序存储元素的,可以根据索引(从 0 开始)来访问它们。 创建数组 可以通过几种方式创建数组: 使用 Array 构造函数: let arr1 = new Array(3); // 创建一个长度为 3 的空数组 let arr2 = new Arr…...
代码规范
C++ 编码规范 一 版式 1.程序块缩进 4 个空格,只能使用空格键,不能使用 TAB 键。 2.相对独立的程序块之间、变量说明之后必须加空行,函数之间也用空行分开。 3.一行只写一条语句,if、for、do、while 等语句自占一行,且执行语句部分无论多少都要加括号 {}。 4.代码行之内应…...
mac远程连接windows
安装 Windows App 在app store 中安装windows app添加pcip可以在windows 电脑的终端上键入ipconfig查看ipv4地址。 双击连接 凭据是windows电脑的账户跟密码,例如Administrator,password 要求是在同一局域网内! 在mac终端上ping一下windows的ip看能否ping的通就知道了。...
子类不依赖泛型,重写父类方法,通过强制类型转换父类方法参数出现的问题。——— 一个例子引发的思考
使用泛型(推荐)public interface FlowHandlerGateway<P extends FlowApprovalPageCondition> {Page<FlowApprovalPage> pageQuery(P condition); }//父类 @Slf4j @Component @RequiredArgsConstructor public class FlowHandlerGatewayImpl<P extends FlowApp…...
WebStorm代码一键美化
还在手动调整代码格式?还在为团队代码风格不统一而头疼? 相信很多朋友都遇到过这样的痛苦场景:写完代码一团糟,看着就难受 团队成员代码风格千差万别,维护起来要命 每次提交代码前都要手动整理格式,费时费力上一篇《10分钟搞定Vue3项目》已经搭建好了项目基础架构,脚手架…...
3分钟搞定Vue组件库
还在为写前端页面发愁?还在为设计按钮、表格这些基础组件浪费时间? 经过上一篇《WebStorm代码一键美化》的学习,相信你已经掌握了 Prettier、ESLint、TypeScript 这三大开发神器。 今天,我要教你一个更厉害的招式:3分钟搞定高颜值UI组件库!学会这一招,你的前端开发效率将…...
Golang中设置HTTP请求代理的策略
在Golang中设置HTTP请求代理涉及 net/http包中的 http.Transport结构体,它控制着HTTP请求的细节。要定义代理,可以使用 http.ProxyURL函数配合 url.Parse函数来创建一个 url.URL对象,然后将该对象赋值给 Transport结构体的 Proxy字段。 以下是配置HTTP代理的典型步骤:引入必…...
[开源免费] iGTTS(Gemini TTS) 文本转语音(TTS)的命令行工具。
iGTTS(Gemini TTS) iGTTS(Gemini TTS) 开源免费的文本转语音(TTS)的命令行工具。 iGTTS(Gemini TTS) 是通过调用 Gemini TTS 的接口,实现文本转语音(TTS)的命令行工具。 添加 API key # 编辑 .zshrc: vim ~/.zshrc# 添加信息(导入环境变量): export GEMINI_API_KEY=&l…...
结合Spring和MyBatis实现DAO层操作综述
在Java企业级开发中,Spring框架和MyBatis持久层框架的结合使用已成为常见模式。下面进行详细介绍如何结合这两个框架实现DAO层(数据访问层)操作。 首先,我们需要明确Spring框架和MyBatis的角色定位。Spring是一个全方位的企业级开发框架,提供了包括但不限于依赖注入、事务…...
202205_CHIMA_follow
流量分析,CHIMA,应急响应,文件拼接Tags:流量分析,CHIMA,应急响应 0x00. 题目 附件路径:https://pan.baidu.com/s/1GyH7kitkMYywGC9YJeQLJA?pwd=Zmxh#list/path=/CTF附件 附件名称:202205_CHIMA_follow.zip发起攻击的IP地址受到攻击的资产的IP+Port上传的木马完整路径上传的文…...
Lua脚本协助Redis分布式锁实现命令的原子性
在实现Redis分布式锁的过程中,Lua脚本的使用可以确保命令的原子性,这是因为Redis会将整个Lua脚本执行作为一个不可分割的整体,从而在多客户端环境中保证数据的一致性和安全性。 分布式锁通常是为了在不同进程或服务器间同步访问共享资源。在Redis中,SETNX命令可以用来实现锁…...
快读快写 学习笔记
在OI中,经常有输入输出量巨大的题,这一类题一般需要非常快速的输入输出方式,于是便有了快读快写 下面是模板(原理无需理解,用的时候直接复制上就行): #include <cstdio> #include <cctype> using namespace std; int precision=-1; char buf[100000],*p1=bu…...
Ubuntu 安装 CLion
下载网址:https://www.jetbrains.com/clion/download/?section=linux 安装在 /opt/clion: sudo mkdir /opt/clion 将安装包解压到 /opt/clion: sudo tar -zxvf CLion-2025.2.1.tar.gz -C /opt/clion ls /opt/clion/clion-2025.2.1这样就安装好了。 启动: sh /opt/clion/cl…...
AI编程实战
不久前我用trace体验了一把AI编程,完成了一个股票交易记录软件的开发,这次有个紧急项目,有了上次的AI编程实践,我决定让AI编程帮我一把 工具选择 上次说千问没有IDE,但阿里云出了一个Qoder,在这个紧急项目之前,我刚好开始使用Qoder,接到紧急项目的时候,是时候让AI真正…...
25/9/13(补)
做了下20年csps的单选,错了两道,后边随机跳题了个之前wa的题(p7777 shelter),数学标签,有编号1~n的石子,用两种抓取方式吧石子抓完,第一种抓法是选一个数i把第i堆石子抓走,代价为ip。第二种是选两个数i,j,把第i,j堆石子抓走,代价为|i-j|q。 发现性质: 第一,二种方…...
面向对象编程(OOP)的原则
面向对象编程(OOP)的原则面向对象编程有一系列核心原则,这些原则指导着我们如何设计高质量、可维护和可扩展的软件系统。这些原则可以分为两大类:基本特性和设计原则。 一、面向对象编程的四大基本特性(基石) 1. 封装 (Encapsulation) 核心思想:将数据和对数据的操作捆绑…...
【龙智Atlassian插件】Confluence周报插件上线AI智能总结,一键生成专业报告 - 实践
【龙智Atlassian插件】Confluence周报插件上线AI智能总结,一键生成专业报告 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &q…...
数字化(管理)系统的工具化思考
一、引言:数字化转型的背景与逻辑 进入 21 世纪,信息技术、互联网、大数据、人工智能与物联网的迅速发展,使得企业与组织的运作方式发生了深刻变革。管理学界普遍认为,传统的经验管理与制度管理正逐步向 数字化管理系统 过渡。这不仅是工具更迭的问题,更是认知范式、管理模…...
详细介绍:传统神经网络实现-----手写数字识别(MNIST)项目
详细介绍:传统神经网络实现-----手写数字识别(MNIST)项目pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New",…...
C#语言中使用using关键字
在 C# 语言中,“using”关键字被用于不同的上下文和目的,它的用法大体上可以被分为三类:导入命名空间、简化资源管理和提供别名。 首先,"using"关键字最常见的用途是导入命名空间。这在 C# 程序中非常普遍,因为它可以允许程序员引用命名空间中定义的类型,而不需…...
中育新版本OSS Token获取API分析
中育新版本OSS Token获取API分析 在8/28更新中(或更早),中育彻底停用了旧版本的GenerateTokenAsyncAPI,转而使用GenerateTokenV2AsyncAPI,新的API使用了签名和一些不明所以的参数,并可能限制了可以上传的路径。 为了尽快迁移旧的工具、程序,我对web端的OSS逻辑进行了分析。…...
25/9/12(补,上一篇是9/11的)
把昨天没改完的码积木改完了,最终解法先发现一个性质是往上堆一个就算和下一个高度重叠也对下一个没有影响,所升序排完后设变量m(m初始等于a[1]),如果m比当前遍历到的a[i]大代表这个a[i]有重叠,更新答案,如果比a[i]小就让m=a[i]保持同频。 改完这题后又去改暑假的T3,就是…...