串联波文件使用CSharp 2005

来源:百度文库 编辑:神马文学网 时间:2024/06/13 06:31:53
RIFF file starts out with a file header followed by a sequence of data chunks. A WAVE file is often just a RIFF file with a single "WAVE" chunk which consists of two sub-chunks -- a "fmt" chunk specifying the data format and a "data" chunk containing the actual sample data. Call this form the "Canonical form".
该WAVE文件格式是微软的多媒体文件的存储釜山国际电影节规范的子集。阿RIFF格式的文件开始进行,由一组数据块序列后一个文件头。波形文件通常只是一个单一的“浪潮”一块它由两个分块-一个“禁产条约”块指定数据格式和“数据”块包含实际示例数据RIFF格式文件。称这种形式的“典型”的形式。
The main idea is to create only one header for all WAV files that you want to concatenate and then write data of each file in a single file.
其主要思想是只能创建一个WAV文件头的所有文件,您要连接,然后写在每一个文件文件中的数据。
Wave file headers follow the standard RIFF file format structure. The first 8 bytes in the file are the standard RIFF chunk header which have a chunk ID of "RIFF" and a chunk size equal to the file size minus the 8 bytes used by the header.
波形文件头遵循标准RIFF格式的文件格式结构。前8个字节的文件是标准的釜山国际电影节块头有一大块的“釜山国际电影节ID”和1块的大小等于文件大小减去八日头使用的字节。
So we need to know the total length of all files to define ChunkSize and read NumChannels, SampleRate and BitsPerSample.
因此,我们需要知道的所有文件的总长度来定义ChunkSize和阅读NumChannels,采样频率和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();
}

As we know channels are stored in the WAV header in byte number 22, we move the current position of the file to this location and the size of it is 2 bytes so we use br.ReadInt16() to read only 2 bytes and so on....
我们知道渠道均是在字节数22 WAV文件头存储,我们将文件的当前位置,这个位置和它的大小为2字节,因此我们使用br.ReadInt16()为只读2字节等....
Construct the Header of Merged File
构建页眉合并的文件
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();
}
We must be careful when wrriting the header. If there is any small mistake, the merged file doesn't work, so we write "RIFF" as an array of char, not as string and use int type for storing 4 bytes and short type for storing 2 bytes.
我们必须小心写头。如果有任何小小的失误,合并后的文件不工作,所以我们写“釜山国际电影节”作为一个char数组,而不是字符串,用于存储4字节,存放2字节短型int类型。
Write Data of all Files in the Merged File
写入数据合并的文件中的所有文件
  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();
}
}

First we need to calculate the total length and data length of all files and then specify the channels, SampleRate and BitsPerSample of the output file.The last thing is to start reading data that is stored after byte number 44 and append it to the merged file.
首先,我们需要计算的总长度和数据长度的所有文件,然后指定的渠道,采样频率和输出file.The bitspersample的最后一件事是开始读取存储的字节数后44和追加到文件中的数据合并。
All we need to do is call the Merge method and specify the input files and output file.
所有我们需要做的就是调用合并方法,并指定输入文件和输出文件。
string[] files = new string[2] { @"C:\WINDOWS\Media\Windows XP Startup.wav",
@"C:\WINDOWS\Media\Windows XP Shutdown.wav" };
WaveIO wa = new WaveIO();
wa.Merge(files,@"c:\oou.wav");

Play the Merged File
合并文件播放
Visual Studio 2005 provides a new class to play sound. Therefore, we don't need an API or anything else.
Visual Studio 2005提供一个新类播放声音。因此,我们并不需要一个API或任何东西。
FileStream fs = new FileStream(@"c:\oou.wav", FileMode.Open,FileAccess.Read);
System.Media.SoundPlayer sp = new System.Media.SoundPlayer(fs);
sp.Play();
fs.Close();