专栏首页QQ音乐技术团队的专栏理解 iOS Core Audio 音频概念

理解 iOS Core Audio 音频概念

在了解 iOS Core Audio 相关技术的时候,会遇到 bitrate、sample、frame 和 packet 等概念。由于业界在不同场合下使用 packet 和 frame 等词语会代表不同的含义,一不小心,很容易被绕进去。

本文讲述了 iOS Core Audio 中常用的音频概念定义,然后介绍一些容易造成概念混淆的场景以及一个实践 demo 案例,最后解答一些常见的问题。

(一) iOS Core Audio 音频概念定义

讨论 iOS Core Audio,就要按照苹果的定义对音频相关概念进行理解。

首先,重点理解 sample, frame 和 packet 三个概念。在 API 文档中中苹果明确定义了 audio stream, channel, sample, frame, packet 和 sample rate 这些概念:

  • A sample is single numerical value for a single audio channel in an audio stream.
  • A frame is a collection of time-coincident samples. For instance, a linear PCM stereo sound file has two samples per frame, one for the left channel and one for the right channel.
  • A packet is a collection of one or more contiguous frames. A packet defines the smallest meaningful set of frames for a given audio data format, and is the smallest data unit for which time can be measured. In linear PCM audio, a packet holds a single frame. In compressed formats, it typically holds more; in some formats, the number of frames per packet varies.

从上面文档定义,简单来说,可以这样理解:

  • sample 是一个声道的一个采样。
  • frame 是最小单位时间点包含的一个或多个声音采样,最小单位时间点取决于声音采样设备,是一个时间点多个采样的集合。譬如,双声道的音频文件,一个时间点有两个声道,一个frame就包括两个采样。
  • packet 是一个或多个 frame 的集合,一个 packet 包含多少个 frame,是由声音文件格式决定的。譬如 PCM 文件格式中一个 packet 包含 1 个frame。而 MP3 文件格式中一个 packet 包含 1152 个frames。

从上面定义来看这三个概念互相独立,定义清晰。

(二)这些概念为什么容易搞混?

然而在日常讨论中,会在多种场合下使用 framepacket 两个词,但是各种场合下它们代表的含义是不同的,所以比较容易搞混。

举下面不同场景的例子来说明:

  1. 在讨论 MPEG 格式的时候,如网上常见的MPEG文件格式介绍,把 MPEG 一个 header + payload (帧头 + 数据内容)的数据结构叫做一个 frame (MPEG数据帧),一个 MPEG 数据帧包含了多个音频帧。事实上这个东东在上述 iOS Core Audio 定义中,却又被称为一个 packet。所以两份文档中,分别使用了 packet 和 frame 两个词指代同一个概念
  2. 网络传输音频的时候,会把音频数据进行打包发送,这个时候也用到 packet 的概念,他有自己独立的 packet header 定义,又跟 iOS Core Audio 定义的 packet 不是同一个了。
  3. 在讨论计算机网络时,硬件数据帧称为 frame,而数据链路层将 frame 打包成 packet 之后提供给上层网络层使用。 这里 frame 和 packet 的概念又跟音频讨论中的含义不一样了。
  4. FFmpeg是一个音/视频编码解码及转换的开源软件。它定义了两个结构体,AVPacket 一份代表经过压缩的音频/视频数据,AVFrame 代表一份解压后的一个音频/视频数据。视频一个 AVPacket 通常只包含一个 AVFrame,经过压缩的音频 AVPacket 通常包括多个 AVFrame。可以看到 FFmpeg 在处理音频和视频时,对 packet 和 frame 概念的使用跟 iOS Core Audio 基本一致。

从上面例子可以看到,不同场景下都使用了 frame 和 packet 两个词语会代表不一样的含义。更糟糕的是,如果使用了中文“帧”,在某些语境下,到底是代表数据帧、音频帧、packet 还是 frame 呢,就更容易分不清楚了。

(三)DEMO:QQ音乐一首歌的音频数据帧

从上面的概念定义,我们搞清楚了 iOS Core Audio 中对 sample, frame 和 packet 的定义,其中 frame 和 packet 又很容易搞混。

下面我们通过分析QQ音乐一首歌的例子,在实践中理解 iOS Core Audio 中对 packet 的定义。

iOS Core Audio 在使用 AudioFileStreamOpen 解码音频文件时候,会要求我们注册 AudioFileStream_PropertyListenerProc 和 AudioFileStream_PacketsProc 两个回调,用于文件读取到属性和包的时候回调。

以QQ音乐中,《最长的电影》这首歌的MP3文件为例,我们每次传入 1000 个字节调用 AudioFileStreamParseBytes 方法,可以得到下面结果(已知音频帧从第 496 个字节开始)。

第1次传入 1000 个字节: 首先回调多次 AudioFileStream_PropertyListenerProc,证明文件前面496个字节是属性。 之后回调一次 AudioFileStream_PacketsProc,回调方法有1个packet,417个字节;二进制内容就是音频数据帧 fffb9044 0008024e…(文件位置:496),没有任何跟文件不一样的多余信息。 然后就没回调了,这时候处理了 496+417 = 913 个字节。传进去的1000个字节,剩下 1000 - 913 = 87 个没处理,因为不能构成一个完整的音频数据帧。

然后传入第2次 1000 个字节: 首先回调 AudioFileStream_PacketsProc,回调418个字节,1个 packet,二进制内容是 fffb9264 29000153…(文件位置913)。 之后第二次继续回调 AudioFileStream_PacketsProc,回调418个字节,1个 packet,二进制内容是 fffb9264 510d0260…(文件位置 913+418=1331)。

可以验证到,AudioStreamPacketDescription 说的 packet ,是指传入数据之后,分离出来的MP3 音频数据帧。注意的链接说这是 MPEG Audio Layer I/II/III frame header,而 iOS Core Audio 使用了 AudioStreamPacketDescription,这里就很容易把 frame 和 packet 的概念搞混。事实上他们是指同一样东西。

看一下 AudioStreamPacketDescription 的代码定义,可以看到它就是一个数据帧 packet,包含了多个音频帧 frame。

(四)答疑

因此,在讨论 iOS Core Audio 相关概念的时候,遇到过的下列疑问都可以解答:

Q: iOS Core Audio 对于 packet 的明确定义是什么? A: 见上述讨论第(一)点。

Q: 为什么经常搞不清楚 packet 和 frame 的区别? A: 见上述讨论第(二)点、(三)实验,因为这两个概念在不同场景下代表不同的含义。

Q: 一个 packet 可以包含半个 frame 吗? A: 从上述(三)实验可以看到,iOS Core Audio 的 packet 至少包含一个 frame,譬如 PCM 就是一个 packet 一个 frame;数据传输的时候的 packet 跟 iOS Core Audio 讨论的概念不一样,有多种不同的协议,相信有些协议可以自己定义传输大小,传送半个帧然后组装成一个帧。

Q: AudioFileStreamParseBytes 每次解析多少个数据帧?可以控制吗? A: 可以控制,对于 CBR 音频格式,基本上你传入多少个字节的数据,就会回调分离多少个数据帧,除非是最后一个不包含完整的 frame;对于 VBR 音频格式,传入一次数据,可能会回调多次分类帧回调。相关说明见AudioFileStream_PacketsProc API 文档最下方。

文中链接 1: https://developer.apple.com/reference/coreaudio/audiostreambasicdescription “苹果 AudioStreamBasicDescription API 文档” 2: http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm “MPEG文件格式介绍” 3: https://en.wikipedia.org/wiki/MPEG_transport_stream “MPEG transport stream” 4: http://ffmpeg.org/ “FFmpeg官网” 5: http://www.ffmpeg.org/doxygen/2.7/structAVPacket.html “FFmpeg AVPacket 文档” 6: http://www.ffmpeg.org/doxygen/2.7/structAVFrame.html “FFmpeg AVFrame 文档” 7: https://developer.apple.com/reference/audiotoolbox/audiofilestream_packetsproc “AudioFileStream_PacketsProc API 文档”

(全文完)

本文分享自微信公众号 - QQ音乐技术团队(gh_287053a877e6),作者:jakehao

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-05-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • web实时长图实践

    本文将介绍几种浏览器端和服务器端 web 实时生成图片的方案,欲知详情请看文章详情。

    QQ音乐技术团队
  • 谁创建谁销毁,谁分配谁释放——JNI调用时的内存管理

    在QQ音乐AndroidTV端的Cocos版本的开发过程中,我们希望尽量多的复用现有的业务逻辑,避免重复制造轮子。因此,我们使用了大量的JNI调用,来实现Jav...

    QQ音乐技术团队
  • K歌礼物视频动画 web 端实践及性能优化回顾

    K 歌移动客户端19年在直播间中上线了视频礼物资源动画能力,使用特制的视频资源加通道导出和混合 (基于企鹅电竞vapx方案),支持了细腻的视频动画素材播放渲染...

    QQ音乐技术团队
  • Excel - 统计每周连续出现次数

    今天遇到一个问题,需要统计每个问题小区在当周的连续出现次数,连续次数大于等于4次,则定义为质差小区。 刚接手时感觉比较简单,实际做发现不是那么回事,统计出来的是...

    披头
  • OpenCV 摄像头与视频读取并显示

    [比较opencv2、opencv3关于读取视频文件、摄像头的编程风格]https://blog.csdn.net/qq_34917736/article/de...

    AI异构
  • python源码阅读笔记之GC

    哒呵呵
  • 深入Weex系列(六)Weex渲染流程分析

    在前两篇文章中我们结合源码学习了Module、Component的注册、调用、回调等流程,相信大家一定收获颇多,对Weex的理解也一定愈加深入。

    用户2898788
  • 神经架构搜索在视频理解中研究进展的综述

    作者 | Michael S. Ryoo 研究员与 AJ Piergiovanni 学生研究员(Google 机器人团队)

    AI科技大本营
  • 产品即文档?PM只是差一款全新的PRD利器

    产品行业的从业者千千万,但为什么有些人就能以野蛮生长的方式快速上升,有些人看似忙碌到不可开交却始终原地踏步?我想,在过完了又一天的朝八晚十后,很多产品经理也会向...

    奔跑的小鹿
  • 软件架构发展历程分享

    架构的形式与特点 设计文档和代码 我们一般说的架构既包括架构的设计过程,也包括设计的产出物,一般可以包括各类设计文档、设计图,也可以包括一些技术验证代码、De...

    CSDN技术头条

扫码关注云+社区

领取腾讯云代金券