新闻详情

新闻详情

首页 / 资讯中心 / 详情

stb_vorbis.c 如何用 stb_vorbis_seek 与 stb_vorbis_seek_frame 定位解码位置

发布时间:2026/9/12 1:46:41来源:尧图网络
stb_vorbis.c 如何用 stb_vorbis_seek 与 stb_vorbis_seek_frame 定位解码位置
stb_vorbis.c 如何用 stb_vorbis_seek 与 stb_vorbis_seek_frame 定位解码位置【免费下载链接】stbstb single-file public domain libraries for C/C项目地址: https://gitcode.com/GitHub_Trending/st/stb在用 stb 的 stb_vorbis.c仓库当前版本 v1.22公共领域许可解码 Ogg Vorbis 音频时常见的任务不是从头解码整个文件而是跳到指定采样位置再继续解码——比如播放器跳转到某个时间点、只抽取文件的某一段。stb_vorbis 的 Pulling Input API 提供了两个 seek 入口stb_vorbis_seek定位到精确采样stb_vorbis_seek_frame定位到包含目标采样的那一帧。本文基于文件头部的 API 注释stb_vorbis.c 第 298–308 行和仓库自带的 tests/vorbseek/vorbseek.c 测试说明如何完成打开文件 → 计算目标采样 → seek → 解码并核对结果这条路径。两个 seek 函数的区别与选择API 注释给出的规则很明确int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number)把解码位置移到大约sample_number。调用成功后下一次stb_vorbis_get_frame_*()返回的帧会包含指定采样但帧起点可能略早于目标值。int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number)精确版本。调用成功后下一次stb_vorbis_get_samples_*()的输出从指定采样开始。注释原话如果你使用get_samples_*但不要求恰好定位到目标采样也可以直接用seek_frame()——即按帧对齐场景下seek_frame是更省事的调用。stb_vorbis_seek_start(f)等价于stb_vorbis_seek(f, 0)用于回到文件开头。因此选择依据是解码接口你按帧取数据stb_vorbis_get_frame_float等且能接受帧边界对齐就用stb_vorbis_seek_frame你用stb_vorbis_get_samples_short_interleaved、stb_vorbis_get_samples_float_interleaved这类按采样取数的接口并需要精确起点就用stb_vorbis_seek。两个函数都只在 Pulling API 下可用内部实现检测到 Pushdata 模式句柄时直接报VORBIS_invalid_api_mixing错误。Pushdata 模式下的seek是另一套机制seek 你的数据源后调用stb_vorbis_flush_pushdata()再靠stb_vorbis_get_sample_offset判断位置不属于本文的采样精确 seek 范畴。准备条件编译与打开文件stb_vorbis 是单文件库头文件部分和实现都在 stb_vorbis.c 一个文件里。仓库自己的构建方式见 tests/Makefile是把stb_vorbis.c直接作为编译单元加入$(CC) $(INCLUDES) $(CFLAGS) ../stb_vorbis.c test_c_compilation.c ... -lm多文件项目可以沿用仓库测试 tests/vorbseek/vorbseek.c 的写法在只需要声明的翻译单元中#define STB_VORBIS_HEADER_ONLY #include stb_vorbis.c打开 Vorbis 文件用 Pulling API 的任一入口参数alloc_buffer传NULL即使用默认malloc()/alloca()分配stb_vorbis *f stb_vorbis_open_filename(input.ogg, error, NULL);stb_vorbis_open_filename通过fopen()打开文件失败返回NULL并设置*error可能为VORBIS_file_open_failure。stb_vorbis_open_memory(data, len, error, NULL)从内存解码要求传入完整的数据流。stb_vorbis_open_file(FILE *f, ...)注意 stb_vorbis 会拥有这个流你在调用之间手动 seek 它会导致库状态错乱且文档说明它对 seek 操作的假设是从起始点之后拥有整个文件的剩余部分想限定范围应改用stb_vorbis_open_file_section。主路径计算目标采样、执行 seek、继续解码目标位置的单位是采样号不是字节、不是帧号。用stb_vorbis_get_info(f)拿到sample_rate和channels用stb_vorbis_stream_length_in_samples(f)/stb_vorbis_stream_length_in_seconds(f)拿总长然后按目标秒数 × sample_rate换算出sample_number该值必须是unsigned int可表示的范围见后文限制。完整最小示例单个 C 文件编译时与 stb_vorbis.c 同目录或加入编译#include stdio.h #include stb_vorbis.c int main(int argc, char **argv) { int error, channels, n; float **output; stb_vorbis_info info; unsigned int target; stb_vorbis *f; f stb_vorbis_open_filename(argv[1], error, NULL); if (f NULL) { fprintf(stderr, open failed, error %d\n, error); return 1; } info stb_vorbis_get_info(f); // 跳到 10 秒处换算成采样号 target (unsigned int)(10 * info.sample_rate); if (target stb_vorbis_stream_length_in_samples(f)) { stb_vorbis_close(f); return 1; // 超出总长会报 VORBIS_seek_invalid } // 需要精确采样起点且随后用 get_samples_* 取数 if (!stb_vorbis_seek(f, target)) { fprintf(stderr, seek failed, error %d\n, stb_vorbis_get_error(f)); stb_vorbis_close(f); return 1; } // 从 target 采样开始取 1024 帧短整型交织数据 n stb_vorbis_get_samples_short_interleaved(f, info.channels, output_buf, output_size); // ... 使用 n 帧数据 ... stb_vorbis_close(f); return 0; }output_buf/output_size是调用方提供的输出缓冲区及其容量以 short 或 float 个数计按各接口注释传入即可返回值是每通道写入的采样数文件尾部可能少于请求量无数据时返回 0。按帧解码的写法只需把两处换掉seek 换成stb_vorbis_seek_frame(f, target)取数换成stb_vorbis_get_frame_float(f, channels, output)——注意get_frame_*返回的缓冲区由 stb_vorbis 内部持有下次调用前会被覆盖需要及时取走数据。另有一条注释提醒不要混用get_frame_*()与get_samples_*()系列因为后者内部会调用前者。判断 seek 是否成功、失败时读什么错误码两个 seek 函数返回非 0 表示成功0 表示失败vorbseek.c 第 20 行的判法就是if (!stb_vorbis_seek(v, pos))记为一次失败。失败时用stb_vorbis_get_error(f)取出最后错误该函数取走后会清空。与 seek 直接相关的错误码定义在 stb_vorbis.c 的STBVorbisError枚举中VORBIS_seek_invalidseek 目标超过流总长实现中sample_number stream_length时返回该错误VORBIS_seek_without_length文件总长未知无法定位VORBIS_seek_failed页级定位或帧级定位过程失败seek 失败路径会把文件恢复到起点再报错;VORBIS_invalid_api_mixing句柄是 Pushdata 模式不能使用这两个 seekVORBIS_invalid_stream、VORBIS_unexpected_eof等文件本身损坏或被截断时出现。注意stb_vorbis_get_sample_offset(f)不能用来核对 seek 后的位置头文件注释明确标注它在 Pulling API 下 seek 之后 NOT WORKING YET。seek 后位置正确与否要用下一节的解码比对法验证。验证方式采样精确性比对仓库提供了专门的测试 tests/vorbseek/vorbseek.c其用法文档化的命令行是Usage: vorbseek {vorbisfile} [{vorbisfile]*] Tests various seek offsets to make sure theyre sample exact.它的验证思路可以照搬到自己项目里先用stb_vorbis_decode_filename(file, num_chan, samprate, output)把整个文件解一遍作为基准数据重新stb_vorbis_open_filename打开stb_vorbis_seek(v, pos)到目标位置解码一段测试用 3000 采样用memcmp与基准数据从pos*2偏移处开始比对同时检查解码数量不超出num_samples - pos防止越界解码。该测试还限制 Vorbis 文件必须是2 声道if (num_chan ! 2)直接报错退出。另外要说明当前仓库中vorbseek.c的main在整文件解码之后有一个break第 88 行seek 测试循环实际上未运行这份源码的价值在于给出完整可参考的try_seeking验证逻辑而不是拿来直接当回归工具。编译方式可参照 tests/Makefile 的做法$(CC)加-I..并把stb_vorbis.c作为编译单元一起加入。另一个更基础的首次使用验证在 tests/test_vorbis.cSTB_VORBIS_HEADER_ONLY 包含头stb_vorbis_decode_memory整文件解码后检查samples返回值可作为你接入 stb_vorbis 后先跑通的冒烟测试。边界与限制来自文件头部 Limitations 一节和 API 注释seek 时必须知道这些边界不支持 floor 02004 年以前的老 Ogg Vorbis 文件若使用 floor 0打开时即报VORBIS_feature_not_supported根本走不到 seek采样号是 32 位192 kHz 的可 seek 时长上限约 6 小时Ogg 本身支持 64 位文件开头忽略无损截断lossless sample-truncation at beginning ignoredseek 依赖流总长已知总长未知时报VORBIS_seek_without_length单个stb_vorbis*句柄不是线程安全的不能多线程同时从同一句柄解码需要并发时开多个句柄分别解码。需要精确到采样就用stb_vorbis_seekget_samples_*按帧取数且容忍帧边界就用stb_vorbis_seek_frameget_frame_*两条路径共用同一套错误码判定并用整文件解码基准 memcmp比对来确认 seek 后的解码起点确实对准了目标采样。【免费下载链接】stbstb single-file public domain libraries for C/C项目地址: https://gitcode.com/GitHub_Trending/st/stb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

SpringBoot+Vue3+MyBatis构建美食推荐系统实践 2026/9/12 2:31:47

SpringBoot+Vue3+MyBatis构建美食推荐系统实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
修复 Actual Budget 中重命名后右键菜单失效问题:React 事件监听与 DOM 节点生命周期的实战剖析 2026/9/12 2:31:47

修复 Actual Budget 中重命名后右键菜单失效问题:React 事件监听与 DOM 节点生命周期的实战剖析

修复 Actual Budget 中重命名后右键菜单失效问题:React 事件监听与 DOM 节点生命周期的实战剖析 【免费下载链接】actual A local-first personal finance app 项目地址: https://gitcode.com/GitHub_Trending/ac/actual 导读 本文以 Actual Budget&#xf…

阅读更多 →
校园奶茶店微信小程序毕业设计:从登录支付到订单管理的全流程实践 2026/9/12 2:31:47

校园奶茶店微信小程序毕业设计:从登录支付到订单管理的全流程实践

校园奶茶店这种选题,在计算机毕业设计里属于典型的“小切口、全流程”项目。小程序端要处理点单、购物车、订单状态,管理端要维护商品库存、统计销量,中间还夹着微信登录、支付回调、消息通知这类绕不开的第三方对接。很多同学做完这个项目&a…

阅读更多 →
系统运维核心指南:从基础设施到自动化工具生态 2026/9/12 2:31:47

系统运维核心指南:从基础设施到自动化工具生态

1. 系统运维到底是什么:先把这个概念掰开揉碎 很多人第一次听到"系统运维"四个字,脑子里浮现的画面往往是:一个程序员坐在电脑前,屏幕上一堆命令行在跑,偶尔敲两下回车,然后对着监控面板发呆。这…

阅读更多 →
等保三级数据库合规选型:ECS自建 vs 瑶池RDS核心差异 2026/9/12 2:31:47

等保三级数据库合规选型:ECS自建 vs 瑶池RDS核心差异

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
论文初稿查AI率完全没必要花钱:2026写作、调研、检测工具搭配直接抄 2026/9/12 2:28:47

论文初稿查AI率完全没必要花钱:2026写作、调研、检测工具搭配直接抄

又到开题和赶稿季,后台被问爆的问题永远是那几个:“用DeepSeek写的论文能查出来吗?”“哪个AIGC检测免费又准?”“ChatGPT写完怎么降AI率?” 这两年工具迭代太快,很多人手里用着大模型,却对检测…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞