AIHIFI 发表于 2009-7-27 23:57:05

关于WAV文件是否保存时钟信息的问题(7楼有更新)

先看一下wav文件格式分析详解
                                             
                                          
一、综述
    WAVE文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。
RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个
字节便是“RIFF”。
    WAVE文件是由若干个Chunk组成的。按照在文件中的出现位置包括:RIFF WAVE
Chunk, Format Chunk, Fact Chunk(可选), Data Chunk。具体见下图:
------------------------------------------------
|             RIFF WAVE Chunk                  |
|             ID= 'RIFF'                     |
|             RiffType = 'WAVE'                |
------------------------------------------------
|             Format Chunk                     |
|             ID = 'fmt '                      |
------------------------------------------------
|             Fact Chunk(optional)             |
|             ID = 'fact'                      |
------------------------------------------------
|             Data Chunk                     |
|             ID = 'data'                      |
------------------------------------------------
            图1   Wav格式包含Chunk示例
    其中除了Fact Chunk外,其他三个Chunk是必须的。每个Chunk有各自的ID,位
于Chunk最开始位置,作为标示,而且均为4个字节。并且紧跟在ID后面的是Chunk大
小(去除ID和Size所占的字节数后剩下的其他字节数目),4个字节表示,低字节
表示数值低位,高字节表示数值高位。下面具体介绍各个Chunk内容。
PS:
    所有数值表示均为低字节表示低位,高字节表示高位。
二、具体介绍
RIFF WAVE Chunk
    ==================================
    |       |所占字节数|具体内容   |
    ==================================
    | ID    |4 Bytes |   'RIFF'    |
    ----------------------------------
    | Size|4 Bytes |             |
    ----------------------------------
    | Type|4 Bytes |   'WAVE'    |
    ----------------------------------
            图2RIFF WAVE Chunk
    以'FIFF'作为标示,然后紧跟着为size字段,该size是整个wav文件大小减去ID
和Size所占用的字节数,即FileLen - 8 = Size。然后是Type字段,为'WAVE',表
示是wav文件。
    结构定义如下:
struct RIFF_HEADER
{
char szRiffID;// 'R','I','F','F'
DWORD dwRiffSize;
char szRiffFormat; // 'W','A','V','E'
};
Format Chunk
    ====================================================================
    |               |   字节数|            具体内容                |
    ====================================================================
    | ID            |4 Bytes|   'fmt '                           |
    --------------------------------------------------------------------
    | Size          |4 Bytes| 数值为16或18,18则最后又附加信息   |
    ------------------------------------------------------------------------
    | FormatTag   |2 Bytes| 编码方式,一般为0x0001               |   |
    --------------------------------------------------------------------   |
    | Channels      |2 Bytes| 声道数目,1--单声道;2--双声道       |   |
    --------------------------------------------------------------------   |
    | SamplesPerSec |4 Bytes| 采样频率                           |   |
    --------------------------------------------------------------------   |
    | AvgBytesPerSec|4 Bytes| 每秒所需字节数                     |   |===> WAVE_FORMAT
    --------------------------------------------------------------------   |
    | BlockAlign    |2 Bytes| 数据块对齐单位(每个采样需要的字节数) |   |
    --------------------------------------------------------------------   |
    | BitsPerSample |2 Bytes| 每个采样需要的bit数                  |   |
    --------------------------------------------------------------------   |
    |               |2 Bytes| 附加信息(可选,通过Size来判断有无) |   |
    ------------------------------------------------------------------------
                            图3Format Chunk
    以'fmt '作为标示。一般情况下Size为16,此时最后附加信息没有;如果为18
则最后多了2个字节的附加信息。主要由一些软件制成的wav格式中含有该2个字节的
附加信息。
    结构定义如下:
struct WAVE_FORMAT
{
WORD wFormatTag;
WORD wChannels;
DWORD dwSamplesPerSec;
DWORD dwAvgBytesPerSec;
WORD wBlockAlign;
WORD wBitsPerSample;
};
struct FMT_BLOCK
{
charszFmtID; // 'f','m','t',' '
DWORDdwFmtSize;
WAVE_FORMAT wavFormat;
};

Fact Chunk
    ==================================
    |       |所占字节数|具体内容   |
    ==================================
    | ID    |4 Bytes |   'fact'    |
    ----------------------------------
    | Size|4 Bytes |   数值为4   |
    ----------------------------------
    | data|4 Bytes |             |
    ----------------------------------
            图4Fact Chunk
    Fact Chunk是可选字段,一般当wav文件由某些软件转化而成,则包含该Chunk。
    结构定义如下:
struct FACT_BLOCK
{
charszFactID; // 'f','a','c','t'
DWORDdwFactSize;
};
Data Chunk
    ==================================
    |       |所占字节数|具体内容   |
    ==================================
    | ID    |4 Bytes |   'data'    |
    ----------------------------------
    | Size|4 Bytes |             |
    ----------------------------------
    | data|          |             |
    ----------------------------------
             图5 Data Chunk
    Data Chunk是真正保存wav数据的地方,以'data'作为该Chunk的标示。然后是
数据的大小。紧接着就是wav数据。根据Format Chunk中的声道数以及采样bit数,
wav数据的bit位置可以分成以下几种形式:
    ---------------------------------------------------------------------
    |   单声道|    取样1    |    取样2    |    取样3    |    取样4    |
    |         |--------------------------------------------------------
    |8bit量化 |    声道0    |    声道0    |    声道0    |    声道0    |
    ---------------------------------------------------------------------
    |   双声道|          取样1            |         取样2         |
    |         |--------------------------------------------------------
    |8bit量化 |声道0(左)|声道1(右)|声道0(左)|声道1(右)|
    ---------------------------------------------------------------------
    |         |          取样1            |         取样2         |
    |   单声道|--------------------------------------------------------
    | 16bit量化 |    声道0    |声道0      |    声道0    |声道0      |
    |         | (低位字节)| (高位字节)| (低位字节)| (高位字节)|
    ---------------------------------------------------------------------
    |         |                         取样1                         |
    |   双声道|--------------------------------------------------------
    | 16bit量化 |声道0(左)|声道0(左)|声道1(右)|声道1(右)|
    |         | (低位字节)| (高位字节)| (低位字节)| (高位字节)|
    ---------------------------------------------------------------------
                         图6 wav数据bit位置安排方式
    Data Chunk头结构定义如下:
    struct DATA_BLOCK
{
char szDataID; // 'd','a','t','a'
DWORD dwDataSize;
};

以CD音频格式为例,16bit/44.1k取样:16bit取样即表示每个取样需要两个16bit(左右各一个),也就是4BYTE(4个字节),即4BYTE/sample。
44100Hz代表每秒取样44100次,所以在Data Chunk部分,每秒保存44100x4BYTE的数据(注意,这些数据是按照时间顺序保存的)。
由于有了文件头对 编码方式、声道数目、采样频率等必要信息的约定,播放器就可以对WAV文件的Data Chunk部分进行正确的播放了,因此WAV文件是不带时钟信息的。

[ 本帖最后由 AIHIFI 于 2009-7-28 16:49 编辑 ]

stephen0831 发表于 2009-7-28 10:27:16

技术贴,支持

emmanuelle 发表于 2009-7-28 10:31:42

说到底,wav与jitter无关。

eudemon7 发表于 2009-7-28 10:58:14

技术贴,占个位子学习

小白 发表于 2009-7-28 13:30:48

wav文件本身肯定不储存,不保存,不包含任何时钟信息. 这个是无须讨论的. 我们需要讨论的,是为什么main body部分数据完全相同的两个wav文件,在实际播放中会出现音质的微小差异.


其实很容易理解,我上次说了: CD碟难道就包含,储存了时钟信息了? 它只是表面上一个个坑而已,不包含任何时钟信息! 但完全可以出现两张包含数据相同,但听感不同的cd碟. 比如原版cd碟和它的刻录复制版,包含的data就完全相同,但听感有细微差异.

[ 本帖最后由 小白 于 2009-7-28 13:32 编辑 ]

pig2man 发表于 2009-7-28 13:59:33

这要看你怎么理解了

每个sample都有固定时间的,比如44.1k的音频每sample就是1/44.1k秒,称为word clock。很多专业卡有word clock同步,就是指的这个。

不过,技术上讲,wav文件无法被用于同步,一般是经由处理加工为具备self-clocking的编码形式,不过这是具体的技术原因,理论上是可以实现self-clocking的PCM解码的,这完全取决于解码器的设计。

(任何数字系统都必须要时钟才能工作,所以我们说“时钟同步”比较合适)

[ 本帖最后由 pig2man 于 2009-7-28 14:25 编辑 ]

AIHIFI 发表于 2009-7-28 16:47:56

内容相同的两个文件为什么会出现不同的听感呢?wav文件格式现在我们已经了解了。
系统在播放声音时必须加入时钟信号,因为文件内容一样,那么导致放出声音的差别只会是加入时钟信号的时候出现了微小的偏差,而造成这种“偏差”的原因有两种可能:一、可能是时钟本身劣质,二、就可能是微小的数据断流。
一块使用时间较长的硬盘会有很多扇区碎片,导致读取保存在碎片中的文件需要更多的时间和更大的耗电量(磁头频繁寻道导致的磁头电机运转量增加),从而导致微小瞬时的数据断流,从而产生了听感差异。
如果排除了碎片问题,即文件是保存在一串连续的扇区中的,那么文件的存储位置对听感的影响应该会消失(除非放音的电脑配置过低导致从不同设备上读取信息的速度达不到正常放音所需的标准流量)。
因此,建议对比试听内容相同的两个文件时,最好准备两个空白分区,进行格式化,只拷试听的文件,每个分区拷一个。

内容相同的文件的放音差异不一定仅取决于文件体存储的扇区位置,还应考虑另外的方面:播放时的时钟及CPU、内存状态等。
因此进行测试的电脑必须为新装干净的操作系统的电脑,从而避免其他软件占用系统资源造成的微小瞬时的数据断流(用得较久的电脑时不时地会发生CPU 100%被占用的情况而且往往莫名其妙地发生,相信大家都有体会)。
对于电脑,如果不是计算机方面的专业人士或高手,要注意尽量避免使用轻薄型的笔记本,因为这种笔记本电脑都有些特殊的功能,如节能设置,说不定什么时候就降频节能了,此外有些笔记本还有一些特殊的功能,比如IBM笔记本有一个保护硬盘的功能,当检测到电脑发生震动超过安全限制的时候,就会强制把硬盘的磁头移动到停机时的位置以保护硬盘,但却导致此时的硬盘处于一种“假死”的状态,而且此时硬盘是无法提供数据的。另外笔记本硬盘的速度尤其是寻道时间比台式机慢很多,且预装windows系统的笔记本大多只有一个C盘,碎片问题难以根除。这些都可能导致放音时产生不可预知的“数据瞬时断流”现象。

此外我认为仅比较两个相同文件的听感且仅一个人自我测试是不够的,更好的方法是进行由第二者辅助的纯盲听AB测试。
进行AB试听时,某一次辅助者在不告知受试者的前提下只放同一文件(不是内容相同的两个文件,而是始终就放这一个文件),这种测试必须在100%受试者无心理准备的情况下进行。
毕竟仅进行“两位数”数量级的测试即得出的结论不符合科学严谨性,但是同一音乐让人听几百次又太过残忍、很不现实,那么最好的方式是:多次进行试验(假设为16次),即进行16次听音测试(每次听音可以听不同风格的音乐)每次试听16遍
那么16x16=256次。
由于不能让受试者知道这次听的到底是两个文件还是一个文件,这16次也就只能有8,9次试验的是同一文件的听感,而另7,8次试验的是两个文件的听感。

pcear 发表于 2009-7-28 16:52:13

ls属于残忍得有理 :)

pig2man 发表于 2009-7-28 17:31:44

如果用cplay或者saw studio之类的完全载入内存播放呢?:)

狂天方 发表于 2009-7-28 20:04:14

不是说了么
造成声音不同的原因不是因为JITTER么?
在硬盘中的数据在进行播放之前早预读进内存了,内存释放数据的稳定性应该直接影响声音的听感吧

bbblucky 发表于 2009-7-28 20:26:37

我有个想法,小白说两个文件开头不同,而中间数据部分相同,倘若将两段wav的开头部分进行对掉,然后再听,听感是否同未对掉之前一致呢?
页: [1]
查看完整版本: 关于WAV文件是否保存时钟信息的问题(7楼有更新)

耳机俱乐部微信
耳机俱乐部微信