FLAC 音频格式标准

FLAC 音频格式标准

文件结构

总体结构

一个标准的 FLAC 音频文件应当包含以下三个结构:

文件头元数据块区域音频帧区域

上述三种结构在 FLAC 音频文件中顺次排序,一个结构结束后紧接下一个结构。 FLAC 中的所有数值,若无特别说明,都是无符号整型数值,占多个字节的数值按高位字节序(大端序)读取。

文件头

FLAC 文件的文件头仅包含一段由4个字节的 ASCII 码组成的标志“fLaC”,用16进制数据表示为:

66 4C 61 43

元数据块区域

元数据块区域包含 FLAC 音频流的基本信息以及一些附属的信息,其中的信息以不同类型的块(block)进行记录,称为“元数据块(metadata block)”,一个块结束后紧接着下一个块。 目前共有7种官方支持的元数据块类型:

流信息:包含音频流的整体信息,如采样率、通道数、采样总数等。填充块:此类块中的数据没有任何意义,通常用于修改元数据时快速填充空余的位置而无需调整整个文件的大小。应用程序数据:用于记录第三方程序的数据。定位表:保存快速定位点,用于在音频流中快速定位。标签信息:用于记录音频作品相关的信息,如:演唱者、专辑、发布日期等。索引表:记录音频分轨信息。图片:包含音频相关的图片,通常用于保存音频封面。

上述类型中,“流信息”类型是 FLAC 文件中必须拥有的元数据块,而且必须是元数据块区域中的第1个块。除“流信息”类型之外的其他类型元数据块都不是必需的。 一个元数据块的数据结构如下:

部分大小说明头部是否是最后一个块1字节1位 0:不是最后一个块 1:是最后一个块 块的类型7位 0:流信息 1:填充块 2:应用程序数据 3:定位表 4:标签信息 5:索引表 6:图片 数据的大小3字节(24位)头部后面所跟的数据的大小,不包括头部,单位是字节数据头部中“数据的大小”字段规定的大小与“块的类型”一项相符的数据,各类元数据块的数据结构会在之后说明

除表中列出的元数据块类型外,数值7~126所对应的类型都是保留类型,127 这个数值由于会产生和同步码相同的序列所以禁止使用,不应当在 FLAC 文件中使用这些类型的元数据块。 由于元数据块头部“数据的大小”字段只有24位,因此最大能容纳的数据大小为16777215字节,约15.9MB。 对于那些非必需的元数据块,解码器可以根据头部中指示的大小跳过元数据块的数据内容,而不必读取其数据,且不会影响到音频的解码。 解码器可以根据元数据块头部的“是否是最后一个块”部分来判断当前块是否最后一个元数据块,从而在处理完最后一个元数据块后进入下一个阶段。

流信息块数据格式

流信息块记录有音频流的基本信息,这些信息可以供程序在不解码音频流的情况下快速读取,某些情况下解码音频帧时也需要从流信息块读取信息。 流信息块的数据大小是固定的,大小为34字节(272位),其结构如下:

部分大小说明最小分块大小16位原始数据分块中最小分块的采样数,有效值:16~65535最大分块大小16位 原始数据分块中最大分块的采样数,有效值:16~65535 若该值和最小分块大小相等,代表对原始数据流进行分块的大小固定 最小音频帧大小24位数据流中最小音频帧的大小,单位是字节,0 表示未知最大音频帧大小24位数据流中最大音频帧的大小,单位是字节,0 表示未知采样率20位 采样率,单位是赫兹(Hz) 由于音频帧限制,实际最大值为 655350,此值不能为 0通道数3位 声道数量-1 FLAC 支持1~8个声道 采样深度5位 采样深度-1位 FLAC 支持4~32位采样深度 总采样数36位数据流中单个通道的总采样数,0 表示未知MD5签名128位未经编码的音频数据的MD5签名,用于校验音频数据中是否存在错误

填充块数据格式

填充块的数据大小必须与其头部中的“数据的大小”信息一致,单位是字节,可以是16777215字节以内的任意大小。填充块中的数据必须是全部为0的二进制序列。

应用程序数据块数据格式

部分大小说明应用程序ID32位(4字节) 用于区分此块是哪一个应用程序的数据的标识符 该ID由 FLAC 开发组织 管理,若想使用某一个 ID 需要申请注册 可以访问 https://xiph.org/flac/id.html 查看目前有哪些 ID 已被注册使用 应用程序数据块数据大小-4字节第三方应用程序的数据

定位表块数据格式

部分大小说明定位点目标帧首个采样的序号64位(8字节) 目标帧中第一个采样的序号 0xFFFFFFFFFFFFFFFF 表示这是一个占位点 目标帧偏移量64位(8字节) 目标帧开头相对于第一帧开头的偏移量,单位是字节 占位点的这一部分可以随意填写 目标帧采样数16位(2字节) 目标帧包含的采样的数量 占位点的这一部分可以随意填写 更多定位点同上 定位点的数量没有限制 定位点不能重复,以采样序号来区分,占位点除外 定位点必须按采样序号升序排列 因上述原因,所有占位点必须排在定位表最后

标签信息块数据格式

标签信息块是 FLAC 用于存储音乐信息的标准方式,数据采用 Vorbis Comment 标准。 此数据块中的数值信息使用低位字节序(小端序)表示。

部分大小说明编码器标识编码器标识长度32位(4字节) 数值,表示其后编码器标识的长度 编码器标识是标签信息数据块里的第一个字段,也是必需的字段 编码器标识编码器标识长度字符串,表示编码器标识,可以随意填写,使用 UTF-8 编码标签数量32位(4字节)数值,表示其后总共有多少个标签自定义标签标签内容长度32位(4字节)数值,表示其后标签内容的长度标签内容标签内容长度 字符串,表示自定义标签,使用 UTF-8 编码,使用如下键值对格式: 标签名=标签值 自定义标签的个数没有限制 标签名不区分大小写,且不能含有 = 符号(0x3D),标签名中的字符应当在 0x20 至 0x7D 范围内 允许同一个标签名重复出现,在这种情况下,此标签名代表包含多个值的集合 更多自定义标签同上 标准的标签: TITLE:作品名/曲名 VERSION:版本,标识同一作品/歌曲的不同版本,例如歌曲的混音版本 ALBUM:专辑,歌曲所属的专辑的名称 TRACKNUMBER:轨道编号,歌曲在其所属的专辑的编号 ARTIST:艺术家,作品的创作者,如:歌手、作曲者、朗读者 PERFORMER:乐曲演奏者,如:指挥、乐团、电子音乐的作曲者 COPYRIGHT:音频的版权,例:Copyright 2021 BSPR0002 LICENSE:许可信息,如:“保留所有权利”、许可证的URL ORGANIZATION:制作该音频的团体(即录制公司) DESCRIPTION:对音频内容的简短描述 GENRE:流派,对音乐体裁的简短说明 DATE:音频录制日期 LOCATION:录制音频的地区 CONTACT:音频创作者的联系方式 ISRC:音频的 ISRC 编号(国际标准音像制品编码)

索引表块数据格式

当一个 FLAC 文件中包含多个音轨时,可以使用索引表创建快速定位到音轨的点。

部分大小说明媒体目录编号128字节 媒体目录编号,由 ASCII 码可打印字符(0x20~0x7E)组成 若不足128字节,应用空字符(0x00)在后方补足 引入轨道采样数64位(8字节) 音频第一个采样到第一个音轨的第一个索引的采样数 如果音频没有录入引入轨道,或者音频不是从 CD 提取的,则此项应为0 是否是标准 CD1位 1:表示此表对应一张标准 CD 0:表示此表不对应标准 CD 保留区域2071位(7位+258字节)保留区域,此区域所有数位必须为0音轨总数8位(1字节) 音频中音轨的数量,最小为 1 标准 CD 音频最大音轨数为 100 音轨音轨偏移量64位(8字节) 音轨第一个索引相对于音频开始处的偏移量,单位是采样 在标准 CD 音频中,此数必须能被 588 整除 音轨编号8位(1字节) 音轨的轨道编号 索引表中的最后一个轨道是引出轨道,该轨道的轨道编号必须是 170 或 255 音轨 ISRC96位(12字节) 音轨的 ISRC 编号,由12字节的 ASCII 码数字和字母字符组成 12字节全为空字符(0x00)表示此轨道没有 ISRC 编号 轨道类型1位 0:表示这是一个音频轨道 1:表示这是一个非音频轨道 预加重标记1位 0:表示不预加重 1:表示预加重 保留区域110位(6位+13字节)保留区域,此区域所有数位必须为0索引数量8位(1字节) 轨道包含的索引的数量 除引出轨道外,索引数量最少为 1 引出轨道不能有任何索引,即数量为 0 标准 CD 音频中,单轨索引数量最大为 100 索引索引偏移量64位(8字节) 索引相对于音轨开始处的偏移量,单位是采样 在标准 CD 音频中,此数必须能被588整除 索引编号8位(1字节) 索引在音轨中的编号,单个轨道中的索引编号不能重复 在标准 CD 音频中,轨道第一个索引的编号必须是 0 或 1,此后每个索引的编号必须+1 编号为 0 的索引表示该轨道前预留间隙的位置 保留区域24位(3字节)保留区域,此区域所有数位必须为 0更多索引同上更多音轨同上

图片块数据格式

部分大小说明图片关系32位(4字节) 数值,描述图片与音频文件的关系 0:其他 1:32×32大小文件图标(仅支持PNG) 2:其他图标 3:媒体封面 4:媒体封底 5:宣传图 6:媒体图像(实体媒介照片) 7:艺术家照片 8:演唱者照片 9:指挥者照片 10:乐队、剧团照片 11:作曲家照片 12:作词者照片 13:录音场地照片 14:录音过程照片 15:表演过程照片 16:相关视频截图 17:艳鱼图(测试用途) 18:插画 19:艺术家、艺术团队 logo 20:发行商、工作室 logo MIME 类型字符串长度32位(4字节)数值,表示其后字符串的数据长度,单位是字节MIME 类型字符串MIME 类型字符串长度字符串,表示图片的 MIME 类型描述字符串长度32位(4字节)数值,表示其后字符串的数据长度,单位是字节描述字符串描述字符串长度字符串,对图片的描述,使用 UTF-8 编码宽度32位(4字节)图片的宽度,单位是像素高度32位(4字节)图片的高度,单位是像素色位深度32位(4字节)图片的色位深度,单个像素表示颜色使用的总位数索引图颜色数量32位(4字节) 使用的图片是索引图时,表示其使用的颜色数量 0 表示图片不是索引图 图片数据长度32位(4字节)数值,表示其后图片数据的长度,单位是字节图片数据图片数据长度图片数据

音频帧区域

音频帧区域是 FLAC 中真正存放音频编码数据的区域,此区域是 FLAC 中的最后一个区域,文件的末尾即是该区域的结束。 FLAC 将原始的音频数据分成一个个块(下文称“分块”),并单独压缩编码为一个个帧。FLAC 有多种编码方式,编码器通过合理的策略对不同的分块使用合适的编码方式来达到压缩的效果。 每一个帧都包含如下部分:

部分说明帧头记录帧的相关信息子帧帧中每个通道的数据,一个通道对应一个子帧对齐填充填充 0,以对齐到一个字节帧尾除去帧尾部分所有数据的 CRC-16 校验信息

帧头

部分大小说明同步码15位固定二进制序列 111111111111100,表示帧的开始分块策略1位 数值,表示对原始音频进行分块的方式 0:固定分块大小 1:可变分块大小 此项会对之后的字段产生影响 此项在所有的帧中必须相同 分块大小4位 此帧对应音频分块的单个通道内的采样数,此项并非直接表示采样数 0:保留值 1:192个采样 2~5:可用表达式 576×2x-2 算得采样数(576,1152,2304,4608) 6:从帧头“自定义分块大小”部分取8位二进制数作为采样数 7:从帧头“自定义分块大小”部分取16位二进制数作为采样数 8~15:可用表达式 256×2x-8 算得采样数(256,512,1024,2048,4096,8192,16384,32768) 此项会对之后的字段产生影响 采样率4位 此帧的采样率,此项并非直接表示采样率 0:从流信息元数据块获取 1:88.2kHz 2:176.4kHz 3:192kHz 4:8kHz 5:16kHz 6:22.05kHz 7:24kHz 8:32kHz 9:44.1kHz 10:48kHz 11:96kHz 12:从帧头“自定义采样率”部分取8位二进制数,以 kHz 为单位作为采样率 13:从帧头“自定义采样率”部分取16位二进制数,以 Hz 为单位作为采样率 14:从帧头“自定义采样率”部分取16位二进制数,乘 10 后以 Hz 为单位作为采样率 15:无效值 此项会对之后的字段产生影响 通道分配4位 通道的数量以及通道对应哪个声道,以下列表会在每一项后方注明声道的顺序 0:1通道(单声道) 1:2通道(左右立体声);左,右 2:3通道(3声道);左,右,中 3:4通道(4声道);前左,前右,后左,后右 4:5通道(5声道);前左,前右,前中,后左,后右 5:6通道(5.1声道);前左,前右,前中,低音,后左,后右 6:7通道(6.1声道);前左,前右,前中,低音,后中,环绕左,环绕右 7:8通道(7.1声道);前左,前右,前中,低音,后左,后右,环绕左,环绕右 8:2通道(左侧立体声);左声道,副声道 9:2通道(右侧立体声);副声道,右声道 10:2通道(中部立体声);中声道,副声道 其他:保留 8~10 类型的通道分配方式会对后续的解码产生影响 采样深度3位 每个采样的位数,此项并非直接表示采样深度 0:从流信息元数据块获取 1:8位 2:12位 3:保留值 4:16位 5:20位 6:24位 7:32位 保留1位固定值 0,无实际用途帧编号8~56位(1~7字节) 按 UTF-8 规范编码的数字 该项的内容与长度取决于分块策略 当分块策略为 0 时,该项表示这是第几个帧,最多使用6字节,转换后的数字最多有31个二进制位 当分块策略为 1 时,该项表示该帧第一个采样的序号,最多使用7字节,转换后的数字最多有36个二进制位 自定义分块大小0~16位(0~2字节) 此帧对应音频分块的单个通道内的采样数-1 该项的长度取决于分块大小字段的数值 当分块大小字段为不为 6 或 7 时,该项长度为 0,即没有该字段 当分块大小字段为 6 时,该项长度为8位 当分块大小字段为 7 时,该项长度为16位 自定义采样率0~16位(0~2字节) 此帧的采样率 该项的长度取决于采样率字段的数值 当采样率字段不在 12~14 范围内时,该项长度为 0,即没有该字段 当采样率字段为 12 时,该项长度为8位 当采样率字段为 13 或 14 时,该项长度为16位 CRC-88位(1字节) 帧头部分除此字段外所有内容的CRC-8校验信息

子帧

子帧部分会包含多个子帧,子帧的数量需要通过帧头部分的“通道分配”字段判断,有多少个通道就有多少个子帧,一个子帧紧接下一个子帧。 每个子帧都包含如下部分:

部分说明子帧头记录子帧的相关信息数据 子帧的数据目前有四种类型,对应 flac 中不同的编码方式 每个子帧会在其中选择一个进行编码 所有子帧的类型:

CONSTANTVERBATIMFIXEDLPC 各种子帧会在之后说明

子帧头

部分大小说明填充位1位固定值 0,避免出现与同步码相同的序列子帧类型6位 数值,表示该子帧属于哪种类型 0:CONSTANT 1:VERBATIM 8~12:FIXED,值需要满足表达式(8+预测器阶数) 32~63:LPC,值需要满足表达式(31+预测器阶数) 其他:保留 省略采样位数(1+x)位 子帧每个采样中有多少位被省略掉了,省略的位数需要在子帧被解码完成后通过左移还原 该字段第1位为 0 时,表示没有省略的采样位,x=0 该字段第1位为 1 时,表示有省略的采样位,x=省略的采样位数, 第1位后方要跟一段由(x-1)个 0 和1个 1 组成的二进制序列, 该序列的长度即是省略的采样位数 例: 无省略位;1位;0 省略1位;2位;11 省略2位;3位;101 省略3位;4位;1001 省略4位;5位;10001

CONSTANT 子帧

CONSTANT 子帧只包含一个未编码的采样,表示子帧中所有的采样都是相同的。

部分大小说明采样固定值子帧实际采样深度 原始子分块中采样的固定值,其长度为子帧的实际采样深度 例如子帧的实际采样深度是16位,则此项的长度也是16位

VERBATIM 子帧

VERBATIM 子帧即原样子帧,其中的数据没有经过编码。使用这种子帧通常是因为没有找到对原始子分块有效的压缩方式,故而保持原样。

部分大小说明原样数据子帧实际采样深度×帧分块大小原始子分块的原样数据,没有经过编码

LPC 子帧

线性预测子帧,使用一些由外部提供的系数组成多项式,将已知的样本代入其中可得到下一个样本的近似值,最后通过残差补足差值。

部分大小说明参考样本子帧实际采样深度×预测器阶数供预测器参考的前导样本,样本的数量为预测器阶数预测器系数位数4位预测器系数位数-1预测器系数移位5位使用多项式求和后结果需要移位的位数,此值为有符号补码形式预测器系数预测器阶数×预测器系数位数预测器的系数,每个系数都是有符号补码形式残差不确定预测器的预测结果与实际采样的偏差值,具体结构请参阅残差小节

FIXED 子帧

恒定系数预测子帧,本质上属于线性预测子帧,但是其每个阶级的系数是固定的,不由外部提供,且求和结果不需要移位。

部分大小说明参考样本子帧实际采样深度×预测器阶数供预测器参考的前导样本,样本的数量为预测器阶数残差不确定预测器的预测结果与实际采样的偏差值,具体结构请参阅残差小节

对齐填充

部分大小说明填充0~7位 对整个帧末尾不足一个字节的数据进行填充以实现字节对齐 若前方刚好满一个字节则不需要对齐

帧尾

部分大小说明CRC-1616位 除去帧尾部分所有数据的 CRC-16 校验信息 包括帧头、子帧、对齐填充

注解

残差

FLAC 依靠预测器与残差来压缩音频,FLAC 用每个子帧开头的少量采样来预测此后的采样,并用残差补足预测的采样与实际采样的差值。现代音频一个完整的采样通常有16位以上,而残差中一个采样的差值通常在8位以下。通过记录子分块开头的少量采样与其余采样的残差,FLAC 得以将音频高度压缩。

FLAC 的残差分为多个分区,每个分区使用哥伦布(Golomb)编码的独有变种进行编码。

部分大小说明编码方式2位 0:使用 4 位二进制参数进行编码 1:使用 5 位二进制参数进行编码 其他:保留 分区阶数4位残差分区的阶数,指示分区的个数,x = 分区阶数,共有 2x 个分区第一个分区编码参数编码方式指示的位数 如果编码参数的所有二进制位都是 1,则表示此分区没有编码而是使用 n 位的原始值表示残差,n 跟在此字段后以5位二进制数表示 此项会对之后的字段产生影响 残差采样位数0位 | 5位分区中每个残差采样的位数如果编码参数不是所有二进制位都为 1,则此字段长度为 0,即没有此字段残差编码 残差采样个数: 分块大小÷分区个数-预测器阶数 如果编码参数不是所有二进制位都是 1,每个残差采样的二进制表示方法为: n 个 0,1 个 1,k 位二进制数 其中, n 不事先指定,在读取时统计,k 为编码参数,设 r 为最后的 k 位二进制数 残差采样值的计算公式为:n×2k+r 得到的值需要进一步转换,参见残差折叠值 如果编码参数的所有二进制位都是 1,则每个残差采样用 x 位的二进制数表示,x = 残差采样位数 得到的值按照有符号补码形式读取 后续分区编码参数同上同上残差采样位数残差编码 残差采样个数: 分块大小÷分区个数

残差的值被限定在 32 位有符号整数范围,因此解码出的残差值只需要 32 位有符号整数类型即可存储。

数值形式

FLAC 中的数值有三种存储形式:

无符号整数:默认的数值形式,长度可在几位到数个字节不等。多个字节的数据一般按照大端序(高位字节序)读取,当前官方规范中只在标签元数据中使用过小端序(低位字节序)读取。有符号补码:最高位为符号位,最高位为 0 时表示正数,与原码表示相同数值;最高位为 1 时表示负数。此种数值对应 64 位有符号整数,只是在 FLAC 中,出于节省空间的原则,会缩减这些数值的长度。读取这些数值时首先要获得这些数值的长度,先以指定长度读取原码,如果检查发现是负数,则将符号位之上的更高位全部变为 1 即可得到真实值。方法有:左移 64-数值长度位再有符号右移相同位数;与 -1 左移数值长度位的结果按位或。残差折叠值:只在残差中使用,残差分区经过第一轮解码后得到的便是此种类型的值。处理方法为:获取最低位,将数值右移1位,如果最低位(右移前)为 1,则在 32 位有符号整数类型下将所有位翻转,得到一个负数。

非独立通道分配模式

FLAC 中有3种非独立通道分配模式:左侧立体声、右侧立体声、中部立体声。这些模式中的某些通道依赖其他通道的数据,不能独自完整地表示一个通道的数据,因而称其为“非独立”的。这些通道分配模式利用了左右立体声通道间的关联性,使得 FLAC 在压缩左右立体声音频时能够获得优良的压缩率。

这 3 种模式最终需要被还原为左右立体声,计算方法为:

左侧立体声:左声道的值保持不变,右声道的值为左声道减去副声道右侧立体声:右声道的值保持不变,左声道的值为右声道加上副声道中部立体声:中声道为左右声道的平均值,副声道为左右声道的差值,右声道的值为平均值减去右移1位的副声道值,左声道的值为右声道值加上副声道值

子帧的实际采样深度

FLAC 的音频流最高支持 32 位采样深度,但由于存在左侧立体声、右侧立体声、中部立体声这些非独立通道分配模式,FLAC 中的子帧实际可以达到 33 位采样深度,用于容纳 32 位整数最小值与最大值的差。因此,解码过程中子帧的数据需要使用 64 位整数类型存储。子帧的实际采样深度并不等于帧头中标明的采样深度,计算方法为:

帧采样深度-子帧省略采样位数如果子帧对应的通道是副声道,将子帧的采样深度再+1

如果子帧省略采样位数不为 0,则子帧在解码完成后,需要将每个采样的值左移相应位数。

预测器

FLAC 中的 LPC 和 Fixed 子帧通过预测器来计算前导采样之后的采样。计算方法为: 设

n

n

n 为待预测采样的编号,

a

a

a 为采样的数列,

c

c

c 为预测器系数的数列,

r

r

r 为残差样本的数列,

s

s

s 为右移位数,预测器阶数为

o

o

o,初始时,已知采样(前导采样)的个数等于预测器的阶数,

n

=

o

n=o

n=o,有如下公式:

a

n

=

(

(

i

=

1

o

a

n

i

c

i

)

s

)

+

r

n

o

a_{n}=((\sum\limits_{i=1}^oa_{n-i}{c}_{i})\gg{s})+r_{n-o}

an​=((i=1∑o​an−i​ci​)≫s)+rn−o​ 编程实现(TypeScript):

function predictor(

samples: BigInt64Array, // 采样

coefficients: bigint[], // 系数

residuals: BigInt64Array, // 残差

shift: bigint // 右移位数

)

{

const length = samples.length, // 子帧采样个数

order = coefficients.length; // 预测器阶数、系数个数

for (let n = order; n < length; ++n) {

let sum = 0n; // 总和

for (let i = 0; i < order; ++i)

sum += samples[n - i - 1] * coefficients[i]; // 已知采样与系数相乘

samples[n] = (sum >> shift) + residuals[n - order]; // 结果右移并与残差相加

}

}

在 Fixed 子帧中,各阶级的系数如下:

0 阶:没有系数,也没有前导采样,预测结果恒定为 01 阶:[ 1 ] 相当于直接取上一个采样作为预测结果2 阶:[ 2, -1 ]3 阶:[ 3, -3, 1 ]4 阶:[ 4, -6, 4, -1 ]

所有阶级的右移位数均为 0。

相关文章

2025年严查网贷平台名单揭秘:这些违规机构被清退
365bet体育在线投

2025年严查网贷平台名单揭秘:这些违规机构被清退

📅 08-28 👁️ 2286
关于给予黄丹君等462名团员停止团籍的公示
365bet体育在线投

关于给予黄丹君等462名团员停止团籍的公示

📅 09-16 👁️ 8039
每天赚点怎么样靠谱吗?一天可以赚多少钱
beat365官方网站登录

每天赚点怎么样靠谱吗?一天可以赚多少钱

📅 09-06 👁️ 3985