WAVE文件格式是微软RIFF规范的一个实例(用来存储多媒体文件),RIFF文件头由连续的chunk组成。WAVE文件是由一个大的"WAVE" chunk组成,这个大的chunk由一个”fmt”chunk和一个”data”chunk组成。
标准WAVE文件格式
这篇的目的是把多个WAVE文件合成为一个只有一个文件头,并把每个数据合并起来的文件。
WAVE的文件头符合标准的RIFF文件结构。头8字节由chunk ID为”RIFF”和chunk size组成。
所以我们需知道合成后文件的chunk size、numchannels、samplerate和bitspersample。
代码:
private void WaveHeaderIN(string spath)
{
FileStream fs = new FileStream(spath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
length = (int)fs.Length - 8;
fs.Position = 22;
channels = br.ReadInt16();
fs.Position = 24;
samplerate = br.ReadInt32();
fs.Position = 34;
BitsPerSample = br.ReadInt16();
DataLength = (int)fs.Length - 44;
br.Close ();
fs.Close();
}
numchannels位于 WAVE文件第22位开始,并且有2字节。所以我们可以在第22位使用br.ReadInt16()来读取到channels中。其它一样。
合成文件的头结构
代码:
private void WaveHeaderOUT(string sPath)
{
FileStream fs = new FileStream(sPath, FileMode.Create, FileAccess.Write );
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(new char[4] { 'R', 'I', 'F', 'F' });
bw.Write(length);
bw.Write(new char[8] {'W','A','V','E','f','m','t',' '});
bw.Write((int)16);
bw.Write((short)1);
bw.Write(channels);
bw.Write(samplerate );
bw.Write((int)(samplerate * ((BitsPerSample * channels) / 8)));
bw.Write((short )((BitsPerSample * channels) / 8));
bw.Write(BitsPerSample);
bw.Write(new char[4] {'d','a','t','a'});
bw.Write(DataLength);
bw.Close();
fs.Close();
}
注意写文件头时要小心些。如果有些差错,合成文件就没法运行了。所以这里我们用一组char类型来写“RIFF“,而不是string。使用int类型存储4个字节,使用short存储2字节。
把所有文件的数据写进合成文件中
public void Merge(string[] files, string outfile)
{
WaveIO wa_IN = new WaveIO();
WaveIO wa_out = new WaveIO();
wa_out.DataLength = 0;
wa_out.length = 0;
//Gather header data
foreach (string path in files)
{
wa_IN.WaveHeaderIN(@path);
wa_out.DataLength += wa_IN.DataLength;
wa_out.length += wa_IN.length;
}
//Reconstruct new header
wa_out.BitsPerSample = wa_IN.BitsPerSample;
wa_out.channels = wa_IN.channels;
wa_out.samplerate = wa_IN.samplerate;
wa_out.WaveHeaderOUT(@outfile);
foreach (string path in files)
{
FileStream fs = new FileStream(@path, FileMode.Open, FileAccess.Read);
byte[] arrfile = new byte[fs.Length - 44];
fs.Position = 44;
fs.Read(arrfile, 0, arrfile.Length);
fs.Close();
FileStream fo =
new FileStream(@outfile, FileMode.Append, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fo);
bw.Write(arrfile);
bw.Close();
fo.Close();
}
}
首先我们得先计算输出文件总长度和所有文件的数据长度,然后指定输出文件的channels、samplerate和bitspersample,最后一件事情就是读取所有文件的数据存储到合成文件的44位后
现在我们需要做的就是调用Merge方法,并指定输入和输出文件。
代码:
string[] files = new string[2] { @"C:/WINDOWS/Media/Windows XP Startup.wav",
@"C:/WINDOWS/Media/Windows XP Shutdown.wav" };
-->
- 该日志由 miri 于11年前发表在综合分类下,最后更新于 2013年07月11日.
- 转载请注明: 合并WAVE文件 | 学步园 +复制链接