FLAC

FLAC(Free Lossless Audio Codec,自由无损音频压缩编码)

特点

  • 无损压缩:被编码的音频(PCM)数据没有任何信息损失,解码输出的音频与编码器的输入的每一个字节都是一样的

    每个数据帧都有一个当前帧的 16-bit CRC 校验码,用于监测数据传输错误。对整段音频数据,在文件头中还保存有一个针对原始未压缩音频数据的 MD5 标记,用于在解码和测试时对数据进行校验

  • 灵活的压缩策略:与 libflac 使用是“质量”的参数,该参数变化从 0(最快)至 8(最小)

    虽然在压缩过程(压缩文件总是完美的“无损”表示的原始数据)。涉及速度和容量之间的折衷,解码过程中始终是相当快的,而不是非常依赖于压缩

  • 快速:FLAC 更看重解码的速度

    解码只需要整数运算,并且相对于大多数编码方式而言,对计算速度要求很低。在很普通的硬件上就可以轻松实现实时解码

  • 硬件支持:由于 FLAC 提供了免费的解码范例,而且解码的复杂程度低,所以 FLAC 是目前少数获得硬件支持的无损压缩编码之一。(APE 格式也有少数硬件支持)

  • 可以流化:FLAC 的每个数据帧都包含了解码所需的全部信息

    解码当前帧无需参照它前面或后面的数据帧。FLAC 使用了同步代码和 CRC(类似于 MPEG 等编码格式),这样解码器在数据流中跳跃定位时可以有最小的时间延迟

  • 可以定位:FLAC 支持快速采样精确定位

    这不仅对于播放有益,更使得 FLAC 文件便于编辑

  • 富于弹性的 metadata:可以定义和实现新类型的 metadata 数据块,而不会影响旧的数据流和解码器的使用

    目前已有的 metadata 类型包括 tag,cue 表,和定位表。已经注册的应用程序可以定义自己专用的 metadata 类型(这一点与 MIDI 标准相似)

  • 非常适合于存档应用:FLAC 是一个开放的编码格式,并且没有任何数据的损失,你可以将它转换为你需要的任何其他格式

    除了每个数据帧的 CRC 和 MD5 标记对数据完整性的保障,flac(FLAC 项目提供的命令行方式编码工具)还提供了一个 verify(校验)选项,当使用该选项进行编码的时候,编码的同时就会立即对已编码数据进行解码并与原始输入数据进行比较,一旦发现不同就会退出并且报警提示

  • 便于对 CD 进行备份:FLAC 有一个 cue 表,表内的 metadata 数据块用于保存 CD 的内容列表和所有音轨的索引点

    你可以将一张 CD 保存到一个单一文件,并导入 CD 的 cue 表格,这样一个 FLAC 文件就可以完整地记录整张 CD 的全部信息。当你的原来的 CD 损坏的时候,你就可以用这个文件恢复出与原来一模一样的CD副本

  • 抗损伤:由于 FLAC 的帧结构,当数据流损坏时,数据损失会被限制在受损的数据帧之内

    一般只会丢失很短的一个片段。而很多其他无损音频压缩格式在遇到损坏时,一个损坏就会造成后面所有数据丢失

Struct

Flag

FLAC 比特流由流开头的 “fLaC” 标记组成,后跟强制性元数据块(STREAMINFO)、任意数量的其他元数据块,然后是音频帧

Metadata

FLAC 最多可以支持到 128 种 metadata,已定义的如下:

  1. STREAMINFO

    此块包含有关整个流的信息,例如:采样率、声道数、样本总数等。它必须作为流中的第一个元数据块出现。 其他元数据块可能紧随其后,而解码器不理解的元数据块将被跳过

    此块包含有关整个流的信息,例如:采样率、声道数、样本总数等。它必须作为流中的第一个元数据块出现。 其他元数据块可能紧随其后,而解码器不理解的元数据块将被跳过。

    比较有价值的信息是那 36bits 表示的 Total samples in stream 即流的总采样数,有了这个关键信息,再结合采样率就能用公式:duration = totalsample / samplerate 就能得到总播放时间,
    然后再根据公式 bitrate = (filelength - data_start) * 8 / duration 就可以得出比特率。公式中的量比较好理解,filelength 是文件总大小,data_start 是首帧起始位置

    有了比特率就可以用公式:pos = seektime * bitrate / 8 + data_start 得到 seek 时间点对应的码流偏移量 pos,再从这个偏移位置开始读数据找下一帧的同步头,找到下一帧就可以开始解码播放完成一次 seek 操作

  2. APPLICATION

    此块供第三方应用程序使用。 唯一的必填字段是 32 位标识符。 这个 ID 需要进行申请, 块的其余部分由注册的应用程序定义

  3. PADDING

    预留空间,主要预留给后期需要编辑元数据的情况使用的,可以直接将要添加的元数据添加在这个区域而不用修改整个文件

  4. SEEKTABLE

    用于存储搜索点的可选块,每个搜索点占用 18字节,一个流中只能有一个 SEEKTABLE,但该表可以有任意数量的搜索点。还有一个特殊的“占位符”搜索点,它会被解码器忽略,但是可用于为将来的搜索点插入保留空间

  5. VORBIS_COMMENT

    用于存储键值对列表。值使用 UTF-8 编码。这是 FLAC 中唯一官方支持的标记机制。一个流中只能有一个 VORBIS_COMMENT 块

  6. CUESHEET

    提示表:此块用于存储可在提示表中使用的各种信息。它支持曲目和索引点,与 Red BOOK CD 数字音频光盘邮寄其他的 CD-DA 元数据兼容。CUESHEET 对于备份 CD-DA 光盘特别有用,但它可以用作播放的通用提示机制

  7. PICTURE

    保存相关图片,图片格式类似于 ID3v2 中的 APIC 帧,支持 URL(但是不推荐)。FLAC PICTURE 块还包括分辨率、颜色深度和调色板大小,以便客户无需全部扫描即可搜索合适的图片

Audio Data

音频数据由一个或多个音频帧组成,每个帧包含一个帧头,其中包含一个 sync code、有关帧的信息,如:块大小、采样率、声道数等,以及一个 8位的 CRC。帧头还包含帧中第一个样本的样本编号(对于可变块大小的流),或者帧号(对于固定块大小的流),用于精确定位。在帧头之后的是编码的子帧,每个通道一个。最后,是一些由 0 填充的边界。每个子帧都有自己的帧头,用于指定子帧的编码方式

为了实现在流中的任意帧开始解码,每个帧头都必须包含一些关于流的基本信息,因为解码器可能还没拿到 STREAMINFO 元数据块。

Struct Info

Stream

长度(bit) 说明
FLAC 文件标识 32 “fLaC”,0x4C 0x61 0x43
METADATA_BLOCK 304 必须包含 STREAMINFO
METADATA_BLOCK* - 可以有任意数量的 METADATA BLOCK
FRAME+ - 至少包含一个音频帧

METADATA_BLOCK

说明
METADATA_BLOCK_HEADER 指定元素块数据类型和大小的头
METADATA_BLOCK_DATA
METADATA_BLOCK_HEADER
长度(bit) 说明
is_last 1 最后元数据块标志:如果此块是音频块之前的最后一个元数据块,则为 “1”,否则为 “0”
block_type 7 块类型
0: STREAMINFO
1: PADDING
2: APPLICATION
3: SEEKTABLE
4: VORBID_COMMENT
5: CUESHEET
6: PICTURE
7-126: reserved
127: 无效,避免与帧同步码混淆
data_length 24 METADATA_BLOCK_DATA 数据长度(byte)
METADATA_BLOCK_DATA

查看对应类型块数据的定义

  1. METADATA_BLOCK_STREAMINFO

    长度(bit) 说明
    minimum_block_size 16 流中使用的最小块大小(以样本为单位)
    maximum_block_size 16 流中使用的最大块大小(以样本为单位)。固定块大小的 最小块大小 == 最大块大小
    minimum_frame size 24 流中使用的最小帧大小(以字节为单位)。可能为 0 标识该值未知
    maximum_frame_size 24 流中使用的最大帧大小(以字节为单位)。可能为 0 标识该值未知
    sample_rate 20 采样率,单位:Hz。尽管有 20 位可用,但最大采样率受帧头结构的限制,为 655350Hz。此外,值 0 无效
    channels 3 声道数 - 1。FLAC 支持 1~8 声道
    bits_per_sample 5 采样位数 - 1。FLAC 支持每个样本 4 ~ 32 bit。目前,参考编码器和解码器最多支持到每个样本 24 bit
    total_samples 36 流中样本总数。若值为 0,则表示样本总数未知
    md5_signature 128 音频数据编码前的 MD5 签名。这允许解码器确定音频数据中是否存在错误,即使该错误不会导致无效的比特流

    FLAC 规定最小块大小为 16,最大块大小为 65535,这意味着最大块大小和最小块大小为 0~15 时是无效的

  2. METADATA_BLOCK_PADDING

    长度(bit) 说明
    n n ‘0’ 位(n 必须是 8 的倍数)
  3. METADATA_BLOCK_APPLICATION

    长度(bit) 说明
    32 已注册的应用程序 ID
    n 应用程序数据(n 必须是 8 的倍数)
  4. METADATA_BLOCK_SEEKTABLE

    长度(bit) 说明
    SEEKPOINT+ 一个或多个搜索点

    搜索点的个数可以通过源信息头中的源信息数据大小来计算,搜索点个数 = 源信息数据大小 / 18

    SEEKPOINT

    长度(bit) 说明
    sample_number 64 目标帧中第一个采样点的序号,或 0xFFFFFFFFFFFFFFFF 用于占位符点
    offset 64 从第一个帧头的第一字节到目标帧头的第一字节的偏移量(单位:字节)
    samples 16 目标帧中的样本数
    • 对于占位符点,第二个和第三个字段值未定义

    • 表中的搜索点必须按照样本编号升序排列

    • 除了占位符点之外,表格中的搜索点必须按照样本编号唯一

    • 可以有任意数量的占位符点,但是都必须在搜索表的末尾

  5. METADATA_BLOCK_VORBIS_COMMENT

    文档:https://xiph.org/vorbis/doc/v-comment.html,不包含 framing bit

    字段 长度(bit) 说明
    vendor_length 32 vendor_string 长度,小端模式
    vendor_string n
    user_comment_list_length 32 comment 个数,小端模式
    comment+ n n 个 comment

    comment

    字段 长度(bit) 说明
    length 32 comment 长度,小端模式
    comment n
  6. METADATA_BLOCK_CUESHEET

    长度(bit) 说明
    128 * 8 媒体目录编号,ASCII 码可打印字符 0x20-0x7e。通常,媒体目录号的长度可能位 0 到 128 个字节。任何未使用的字符都应该用 NUL 字符右填充。对于 CD-DA,这是一个 13 位的数字,后跟 115 个 NUL 字节
    64 导入样本的数量。 该字段仅对 CD-DA 提示表有意义; 对于其他用途,它应该是 0。对于 CD-DA,导入是存放目录的 TRACK 00 区域; 更准确地说,它是从媒体的第一个样本到第一个轨道的第一个索引点的第一个样本的样本数。 根据红皮书,导入必须是静音,CD 抓取软件通常不会存储它; 此外,导入时间必须至少为 2 秒,但也可以更长。 由于这些原因,导入长度存储在这里,以便可以计算第一条轨道的绝对位置。 注意,这里存储的导入是到第一个轨道的第一个索引点为止的样本数,不一定是第一个轨道的 INDEX 01; 甚至第一首曲目也可能有 INDEX 00 数据
    1 如果 CUESHEET 对应于光盘则为 1,否则为 0
    7 + 258 * 8 保留。所有位都必须设置为零
    8 曲目数量。至少为 1。对于 CD-DA,此数量不得超过 100(99 条常规曲目和 1 条引出曲目)
    CUESHEET TRACK+ 一首或多首曲目。CUESHEET 块需要有一个引出轨道。它始终是 CUESHEET 中的最后一首曲目。对于 CD-DA,引出曲目编号必须是红皮书规定的 170,否则必须是 255

    CUESHEET_TRACK

    长度(bit) 说明
    64 轨道偏移量(单位是采样数)
    8 轨道编号
    12 * 8 轨道 ISRC
    1 轨道类型:0 音乐 1 非音乐
    1 pre-emphasis 标记:0 no pre-emphasis, 1 pre-emphasis.。 这对应于 CD-DA Q 通道控制位 5
    6 + 13 * 8 保留。所有位都必须设置为零
    8 轨道的索引数目。 CUESHEET 中的每个轨道必须至少有一个索引,但引出轨道除外,它必须为零。 对于 CD-DA,这个数字可能不超过 100
    CUESHEET_TRACK_INDEX+ 引出轨道之外的所有轨道都有一个或多个轨道索引点

    CUESHEET_TRACK_INDEX+

    长度(bit) 说明
    64 索引点相对于轨道偏移的样本偏移。对于 CD-DA,偏移量必须能被 588 个样本整除(588 个样本 = 44100 个样本/秒 * 1/75 秒),偏移量是从轨道开始的,而不是从音频数据开始
    8 索引点编号。对于 CD-DA,所以号 0 对应于轨道 pre-gap。轨道中的第一个索引的编号必须为 0 或 1。随后,索引点编号必须增加 1。索引编号在轨道内必须是唯一的
    3 * 8 保留。所有位都必须设置为零
  7. METADATA_BLOCK_PICTURE

    长度(bit) 说明
    picture_type 32 图片类型按 ID3v2 APIC 帧:
    0 - Other
    1 - 32x32 pixels ‘file icon’ (PNG only)
    2 - Other file icon
    3 - Cover (front)
    4 - Cover (back)
    5 - Leaflet page
    6 - Media (e.g. label side of CD)
    7 - Lead artist/lead performer/soloist
    8 - Artist/performer
    9 - Conductor
    10 - Band/Orchestra
    11 - Composer
    12 - Lyricist/text writer
    13 - Recording Location
    14 - During recording
    15 - During performance
    16 - Movie/video screen capture
    17 - A bright coloured fish
    18 - Illustration
    19 - Band/artist logotype
    20 - Publisher/Studio logotype
    其他是保留的,不应使用。一个文件中的图片类型 1 和图片类型 2 只能有一个
    mime_type_length 32 MIME 类型字符串的长度(单位字节)
    mime_type n * 8 MIME 类型字符串,ASCII 字符。MIME 类型也可能是 –> 表示数据部分是图片的 URL,而不是图片数据本身
    description_length 32 图片描述字符串长度(单位字节)
    description n * 8 图片描述,UTF-8 格式
    width 32 图片宽度
    height 32 图片高度
    color_depth 32 图片颜色深度
    colors 32 用于索引图片(例如:GIF),所使用的颜色数量。对于非索引图片为 0
    data_length 32 图片数据长度(单位字节)
    data n * 8 二进制图像数据

Frame

长度(bit) 说明
FRAME_HEADER
SUBFRAME+ 每个声道一个 SUBFRAME
填充 0 用于对齐
FRAME_FOOTER CRC-16
FRAME_HEADER
长度(bit) 说明
sync_code 14 同步码 ‘11111111111110’
reserved 1 保留
0:必选
1:保留将来使用
blocking_strategy 1 分块策略:
0:固定块大小,帧头包含帧的序号
1:可变块大小,帧头包含采样点序号
block_size 4 块内采样数:
0000 : 保留
0001 : 192 samples
0010-0101 : 576 * (2^(n-2)) samples, i.e. 576/1152/2304/4608
0110 : get 8 bit (blocksize-1) from end of header
0111 : get 16 bit (blocksize-1) from end of header
1000-1111 : 256 * (2^(n-8)) samples, i.e. 256/512/1024/2048/4096/8192/16384/32768
sample_rate 4 采样率:
0000 : get from STREAMINFO metadata block
0001 : 88.2kHz
0010 : 176.4kHz
0011 : 192kHz
0100 : 8kHz
0101 : 16kHz
0110 : 22.05kHz
0111 : 24kHz
1000 : 32kHz
1001 : 44.1kHz
1010 : 48kHz
1011 : 96kHz
1100 : get 8 bit sample rate (in kHz) from end of header
1101 : get 16 bit sample rate (in Hz) from end of header
1110 : get 16 bit sample rate (in tens of Hz) from end of header
1111 : invalid, to prevent sync-fooling string of 1s
channel_assignment 4 声道分配:
0000-0111 : 独立声道-1。定义如下:
1 channel: mono
2 channels: left, right
3 channels: left, right, center
4 channels: front left, front right, back left, back right
5 channels: front left, front right, front center, back/surround left, back/surround right
6 channels: front left, front right, front center, LFE, back/surround left, back/surround right
7 channels: front left, front right, front center, LFE, back center, side left, side right
8 channels: front left, front right, front center, LFE, back left, back right, side left, side right
1000 : left/side stereo: channel 0 is the left channel, channel 1 is the side(difference) channel
1001 : right/side stereo: channel 0 is the side(difference) channel, channel 1 is the right channel
1010 : mid/side stereo: channel 0 is the mid(average) channel, channel 1 is the side(difference) channel
1011-1111 : reserved
bits_per_sample 3 采样位数:
000 : get from STREAMINFO metadata block
001 : 8 bits per sample
010 : 12 bits per sample
011 : reserved
100 : 16 bits per sample
101 : 20 bits per sample
110 : 24 bits per sample
111 : reserved
reserved 1 保留
0:必选
1:保留将来使用
coded_sample_number or coded_frame_number if(variable blocksize)
<8-56>:”UTF-8” coded sample number (decoded number is 36 bits)
else
<8-48>:”UTF-8” coded frame number (decoded number is 31 bits)
if (blocksize bits == 011x)
8/16 bit (blocksize-1)
if (sample rate bits == 11xx)
8/16 bit sample rate
crc 8 CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0) of everything before the crc, including the sync code
长度(bit) 说明
16 CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with 0) of everything before the crc, back to and including the frame header sync code

Reference

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×