篇一:WAV文件格式
WAVE文件格式
一、综述
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' | ------------------------------------------------ 图1Wav格式包含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' |
---------------------------------- 图2 RIFF WAVE Chunk
以'FIFF'作为标示,然后紧跟着为size字段,该size是整个wav文件大小减去ID 和Size所占用的字节数,即FileLen - 8 = Size。然后是Type字段,为'WAVE',表 示是wav文件。 结构定义如下: struct RIFF_HEADER {
char szRiffID[4]; // 'R','I','F','F'DWORD dwRiffSize;
char szRiffFormat[4]; // '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来判断有无) | | -------------------------------------------------------------------- ---- 图3 Format 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 {
char szFmtID[4]; // 'f','m','t',' 'DWORD dwFmtSize;WAVE_FORMAT wavFormat; };
Fact Chunk
================================== | |所占字节数| 具体内容|
================================== | ID | 4 Bytes |'fact' | ---------------------------------- | Size | 4 Bytes |数值为4| ---------------------------------- | data | 4 Bytes | | ---------------------------------- 图4 Fact Chunk
Fact Chunk是可选字段,一般当wav文件由某些软件转化而成,则包含该Chunk。 结构定义如下: struct FACT_BLOCK {
char szFactID[4]; // 'f','a','c','t'DWORD dwFactSize; };
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[4]; // 'd','a','t','a'DWORD dwDataSize; };
/***************************************************************/ /***************************************************************/ WAVE文件格式说明表
PCM数据的存放方式: WAVE文件的每个样本值包含在一个整数i中,i的长度为容纳指定样本长度所需的最小字节数。首先存储低有效字节,表示样本幅度的位放在i的高有效位上,剩下的位置为0,这样8位和16位的PCM波形样本的数据格式如下所示。
篇二:wav文件的创建
WaveData(0) = &H52
WaveData(1) = &H49
WaveData(2) = &H46
WaveData(3) = &H46 'RIFF
WaveData(4) = &HC4
WaveData(5) = &HF
WaveData(6) = &H0
WaveData(7) = &H0 '整个文件的长度
WaveData(8) = &H57
WaveData(9) = &H41
WaveData(10) = &H56
WaveData(11) = &H45'wave
WaveData(12) = &H66
WaveData(13) = &H6D
WaveData(14) = &H74
WaveData(15) = &H20'fmt
WaveData(16) = &H10
WaveData(17) = &H0
WaveData(18) = &H0
WaveData(19) = &H0'FMT块的长度=0000 0010H
WaveData(20) = &H1
WaveData(21) = &H0'PCM编码
WaveData(22) = &H1'单声道
WaveData(23) = &H0
WaveData(24) = &HE8 '采样频率=1000Hz
WaveData(25) = &H3
WaveData(26) = &H0
WaveData(27) = &H0
WaveData(28) = &HD0
WaveData(29) = &H7
WaveData(30) = &H0
WaveData(31) = &H0'每秒钟的字节数=fs*每个采样数据占用的字节数
WaveData(32) = &H2
WaveData(33) = &H0'每个采样数据所占用的字节数
WaveData(35) = &H0'每个采样数据所占用的比特位数=8*每个采样数据占用的字节数
WaveData(36) = &H64
WaveData(37) = &H61
WaveData(38) = &H74
WaveData(39) = &H61'data
WaveData(40) = &HA0
WaveData(41) = &HF
WaveData(42) = &H0
WaveData(43) = &H0'Length(data)
For ii = 1 To 2000
Select Case dataID
Case 1
y(ii) = Sin(2# * 3.141592 * (ii + rdVar) / 1000#)
Case 2
y(ii) = (ii + rdVar) Mod 768
Case 3
If (-1) ^ ((ii + rdVar) \ 500) = 1 Then
y(ii) = (ii + rdVar) Mod 500
Else
y(ii) = 500 - (ii + rdVar) Mod 500
End If
Case 4
y(ii) = Rnd(ii)
End Select
Next ii
yMax = y(1)
yMin = y(1)
For ii = 2 To 2000
If y(ii) > yMax Then
yMax = y(ii)
End If
If y(ii) < yMin Then
yMin = y(ii)
End If
Next ii
LengthOfData = 2000
ReDim Preserve WaveData(LengthOfHead + LengthOfData * 2) As Integer
For ii = 1 To LengthOfData
If y(ii) >= 0 Then
temp = 32767 * y(ii) / yMax
Else
temp = 65536 - 32768 * y(ii) / yMin
End If
dataH = temp \ 256
dataL = temp Mod 256
WaveData(LengthOfHead + 2 * (ii - 1)) = dataL
WaveData(LengthOfHead + 2 * ii - 1) = dataH
Next ii
fileNum = FreeFile
Open strFileName For Binary As #fileNum Len = (LengthOfHead + LengthOfData)
For jj = 1 To LengthOfHead + LengthOfData * 2
Seek #fileNum, jj
Put #fileNum, jj, WaveData(jj - 1)
Next jj
Close #fileNum
////////////////////////////////////////////////////////////
Dim fname1 As String '声音文件的目录及文件名
Dim filenum1 As Integer '打开文件时的文件序号
Dim HeadOfFile(1 To 58) As Byte 'WAV文件的文件头
Dim nBit1 As Integer '声音文件数据的宽度
Dim Length1 As Long '声音数据的长度
Dim LenVal(1 To 4) As Byte '采样频率的4个字节数据
Dim nSamplePerSec1 As Long '采样频率
Dim Y1() As Single'声音数据
Dim ymax As Single
Dim ymin As Single
filenum1 = FreeFile
Open fname1 For Binary As #filenum1
For i = 1 To 58
Seek #filenum1, i
Get #filenum1, , HeadOfFile(i)
Next i
'判断是否是WAV文件
If HeadOfFile(9) <> 87 Or HeadOfFile(10) <> 65 Or HeadOfFile(11) <> 86 Or HeadOfFile(12) <> 69 Then
MsgBox ("Invalid WAVE FILE!")
Else
'求取采样频率
nSamplePerSec1 = HeadOfFile(28) * 65536 * 256 + HeadOfFile(27) * 65536 + HeadOfFile(26) * 256 + HeadOfFile(25) '寻找WAV文件中的DATA数据的位置
i = 16
While HeadOfFile(i) <> 100 Or HeadOfFile(i + 1) <> 97 Or HeadOfFile(i + 2) <> 116 Or HeadOfFile(i + 3) <> 97 i = i + 1
Wend '循环结束时i指向data标识符的起始位置,即‘d’的位置
读取数据体的长度
For j = 1 To 4
Seek #filenum1, i + 3 + j
Get #filenum1, , LenVal(j)
Next j
Length1 = CLng(LenVal(4)) * 16777216 + CLng(LenVal(3)) * 65536 + CLng(LenVal(2)) * 256 + CLng(LenVal(1))
ReDim DataBody1(1 To Length1) As Byte
For j = 1 To Length1
Seek #1, i + 7 + j
Get #1, , DataBody1(j)
Next j
'数据处理
If HeadOfFile(33) = 2 Then '16位采样数据
Length1 = Length1 / 2
nBit1 = 16
ReDim dispY(1 To Length1) As Single
ReDim dispX(1 To Length1) As Single
ReDim Y1(1 To Length1) As Single
For i = 1 To Length1
YTemp = DataBody1(2 * i - 1) + DataBody1(2 * i) * 256# If YTemp > 32767 Then
YTemp = YTemp - 65536
End If
dispY(i) = (32768 - YTemp) / 32768#
Y1(i) = YTemp / 32768#
Next i
ElseIf HeadOfFile(33) = 1 Then
MsgBox ("Ueceivable File")
nBit1 = 8
End If
ymax = dispY(1)
ymin = dispY(1)
For i = 2 To
Length1If ymax < dispY(i) Then
ymax = dispY(i)
End If
If ymin > dispY(i) Then
ymin = dispY(i)
End If
Next i
篇三:WAV的音频沙沙的噪音或没有声音解决方法
WAV音频文件沙沙的噪音或没有声音的解决方法
有些后缀名是WAV的音频文件其实并不真是WAV文件,它只是一些抓轨软件在抓轨时自动添加的后缀名,而其实本质上还是DTS格式的,因为Nero等刻录软件不支持DTS格式,所以刻录出来的光盘在DVD上无法读取,表现出是沙沙的噪音或没有声音,解决方法如下:
1.下载一个叫Foobar2000的播放软件,最新的有1.33中文版,带DTS解码。
2.把不能刻录的那些后缀名为WAV的分轨音频文件的后缀名改为.dts。如:“我是一只鱼.wav”改为“我是一只鱼.dts”
3.把这些改好后缀名的分轨音频文件导入Foobar2000,然后全部选中,右键单击选择转换,软件会按照默认的转换为wav格式,存放路径你自己决定,这回是真正的wav格式了。
4.启动Nero Express刻录软件,选择音乐-音乐光盘-添加-文件,把转换好的文件导入,然后再点击播放,是不是可以正常播放了?好了,点下一步,把刻录机速度调整为最低〔这样刻录质量好,成功率高〕,开始刻录,直到刻录完成。您就得到了一张可以在DVD上播放的光盘,音响效果非常好,我在家里的音响上听,效果美极了,完全可以媲美原盘。
另外,有的由Nero做的光盘镜像文件,就是后缀名是g的文件,如果是dts的格式,复制成光盘也是不成的,同样不能播放,解决的方法是:
把镜像文件载入虚拟光驱,然后用光盘抓轨软件进行抓轨,得到后缀名为.wav的分轨文件后,改为.dts格式,然后按照上面所说的方法进行转换,刻录就可以了。