作为学习C#的借口,我一直在尝试编写一个简单的项目:创建音频文件.首先,我想确保我可以编写符合WAVE格式的文件.我已经在线研究了格式(例如,这里),但每当我尝试播放文件时,它都无法正确打开.这是我的代码.缺少什么或不正确?
uint numsamples = 44100;
ushort numchannels = 1;
ushort samplelength = 1; // in bytes
uint samplerate = 22050;
FileStream f = new FileStream("a.wav", FileMode.Create);
BinaryWriter wr = new BinaryWriter(f);
wr.Write("RIFF");
wr.Write(36 + numsamples * numchannels * samplelength);
wr.Write("WAVEfmt ");
wr.Write(16);
wr.Write((ushort)1);
wr.Write(numchannels);
wr.Write(samplerate);
wr.Write(samplerate * samplelength * numchannels);
wr.Write(samplelength * numchannels);
wr.Write((ushort)(8 * samplelength));
wr.Write("data");
wr.Write(numsamples * samplelength);
// for now, just a square wave
Waveform a = new Waveform(440, 50);
double t = 0.0;
for (int i = 0; i < numsamples; i++, t += 1.0 / samplerate)
{
wr.Write((byte)((a.sample(t) + (samplelength == 1 ? 128 : 0)) & 0xff));
}
Run Code Online (Sandbox Code Playgroud)
主要问题是:
BinaryWriter.Write(string)写一个带有前缀的字符串,以便BinaryReader将其读回.它不打算像你的情况一样使用.您需要直接写入字节而不是使用BinaryWriter.Write(string).
你应该做什么:
将字符串转换为字节,然后直接写入字节.
byte[] data = System.Text.Encoding.ASCII.GetBytes("RIFF");
binaryWriter.Write(data);
Run Code Online (Sandbox Code Playgroud)
或使它成为一行:
binaryWriter.Write(System.Text.Encoding.ASCII.GetBytes("RIFF"));
Run Code Online (Sandbox Code Playgroud)
可能还有其他问题,例如您编写的整数可能与所需的大小不同.你应该仔细检查它们.
至于endianess,你说的链接表明数据是little-endian并BinaryWriter使用little-endian,所以这应该不是问题.