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

PCM 参数深度解析:采样率、帧、缓存大小与多通道关系

将下面的 PCM 配置作为例子:

config.channels    = 2;                  // 立体声(2 个通道)
config.rate        = 48000;              // 采样率 48000 Hz,即每秒 48000 帧
config.period_size = 1024;               // 每个周期包含 1024 帧
config.period_count= 4;                  // 总周期数 4 → 整个缓冲区包含 1024 * 4 = 4096 帧
config.format      = PCM_FORMAT_S16_LE;   // 16 位小端格式,即每个采样占 16 位(2 字节)

1. 单帧的构成

  • 定义帧
    在 PCM 数据中,每一帧包含了所有通道对应的一个采样数据。

    • 例如对于立体声(2 通道),每帧包含 2 个采样。
  • 采样大小与每帧字节数

    • 格式 PCM_FORMAT_S16_LE 表示每个采样为 16 位(2 字节)。
    • 因此,每帧字节数 = 通道数 × 每样本字节数
      = 2 × 2 = 4 字节

2. 采样率与帧率

  • 采样率定义
    采样率 48000 Hz 表示每秒钟采集 48000 帧数据。
    • 不论是 2 个通道还是 4 个通道,每秒始终采集 48000 帧。
    • 这意味着:
      • 在 2 通道下,每个通道的采样频率同样为 48000 Hz,总采样点数为 48000 × 2 = 96000 个。
      • 在 4 通道下,每个通道也是 48000 Hz,总采样点数为 48000 × 4 = 192000 个。

注意:采样率表示的是整体帧率,并不会因通道数改变而“分摊”到每个通道。

3. 周期(Period)和缓冲区

  • Period Size(1024 帧):
    代表每次数据读写时处理的最小单位。

    • 时间长度 = period_size / 采样率
      = 1024 / 48000 ≈ 0.02133 秒 ≈ 21.33 毫秒
  • Period Count(4 个周期):
    有助于形成一个环形缓冲区,整个缓冲区的帧数为

    • 总帧数 = period_size × period_count = 1024 × 4 = 4096 帧.
    • 总缓冲区字节数 = 总帧数 × 每帧字节数 = 4096 × 4 = 16384 字节.

4. 音频时长的计算

假设只处理(或读取)一个周期的数据(1024 帧),则其时长为:
在这里插入图片描述
换算成毫秒即为:
在这里插入图片描述
如果处理整个缓冲区(4096 帧),时长则是:
在这里插入图片描述

5. 多通道情况下的解释

  • 统一的采样率
    采样率表示的是每秒钟采集的帧数,与通道数无关。

    • 无论配置 2 个通道还是 4 个通道,每秒都采集 48000 帧,只不过每帧内包含 2 或 4 个采样数据。
    • 因此,每个通道的采样频率始终为 48000 Hz,而不会因为通道数不同而分别变成 24000 Hz 或 12000 Hz。
  • 总采样点数

    • 2 通道配置:总采样点数 = 48000 × 2 = 96000
    • 4 通道配置:总采样点数 = 48000 × 4 = 192000

总结

  • 采样率(rate):定义每秒处理的帧数(48000 Hz),与通道数无关。
  • 帧(Frame):是一个包含所有通道采样的最小数据单位,每帧字节数由 channel 数×(每个采样的字节数)决定。
  • Period Size:单次数据传输的帧数(1024 帧),也意味着单个周期的时长为 1024/48000 秒(约 21.33 毫秒)。
  • Period Count:缓冲区中周期的总数(4),影响整个缓冲区的大小和抗系统调度抖动的能力(总帧数 4096)。
  • 数据大小:通过 pcm_frames_to_bytes() 可把帧数转换为字节数,方便内存分配和数据传输;反之 pcm_bytes_to_frames() 则可将读取或写入的字节数转换回帧数以便计算时长等。
http://www.xdnf.cn/news/247.html

相关文章:

  • 【C到Java的深度跃迁:从指针到对象,从过程到生态】第二模块·语法迁移篇 —— 第六章 函数革命:从过程到方法的重生
  • Yarn的安装及环境配置
  • PS中制作一张扣洞贴图
  • transient关键字深度解析
  • FA-YOLO:基于FMDS与AGMF的高效目标检测算法解析
  • 社保文档智能处理 python实现 谷歌 Gemini回答
  • 物联网分层架构全解析:从感知到应用的智能生态构建
  • Java漏洞原理与实战
  • 单调队列模板cpp
  • servlet-HTTP协议
  • 每日一题(小白)暴力娱乐篇32
  • 数据类型相关问题导致的索引失效 | OceanBase SQL 优化实践
  • 计算机视觉---相机标定
  • Android device PCO (protocol configuration options) intro
  • Node.js 异步调用淘宝 API 实践:高吞吐商品详情数据采集方案
  • 查看matlab函数帮助文档的方法
  • 深入理解synchronized
  • 【Spring JDBC】PreparedStatementCreatorFactory使用流程
  • 生态篇|多总线融合与网关设计
  • 59. 螺旋矩阵 II
  • 【字节跳动AI论文】海姆达尔:生成验证的测试时间扩展
  • 基于Redis的4种延时队列实现方式
  • This article is for Unreal Authorized Indicator Application
  • Zookeeper 概述
  • 自学新标日第十九课复习版本
  • 游戏引擎学习第232天
  • 解锁古籍中的气候密码,探索GPT/BERT在历史灾害研究中的前沿应用;气候史 文本挖掘 防灾减灾;台风案例、干旱案例、暴雨案例
  • linux服务器命令行获取nvidia显卡SN的方法
  • 第六章:6.6输入以下的杨辉三角形,要求输出10行
  • Linux学习——守护进程编程