我正在用C#编写一个应用程序来记录音频文件(* .wav)并自动标记和命名它们。 Wave文件是RIFF文件(如AVI),除波形数据块外,还可以包含元数据块。所以现在我想弄清楚如何从记录的波形文件中读取和写入RIFF元数据。
我正在使用NAudio录制文件,并在their forums上询问well on SO有关读取和写入RIFF标记的方法。虽然我收到了很多好的答案,但没有一个解决方案能够像我希望的那样轻松地阅读和来编写RIFF块。
但更重要的是,我在字节级处理文件的经验很少,并认为这可能是一个学习的好机会。所以现在我想尝试编写我自己的类,它可以读入RIFF文件,并允许读取元数据,并从文件中写入。
我在C#中使用了流,但始终使用整个流。所以现在我很遗憾,我必须逐字节地考虑一个文件。具体来说,我将如何从文件中间删除或插入字节?我已经尝试通过FileStream将文件读入字节数组(byte []),如下面的代码所示。
System.IO.FileStream waveFileStream = System.IO.File.OpenRead(@"C:\sound.wav");
byte[] waveBytes = new byte[waveFileStream.Length];
waveFileStream.Read(waveBytes, 0, waveBytes.Length);
我可以通过Visual Studio调试器看到前四个字节是文件的RIFF头。
但是,在执行更改大小的操作(如插入或删除值)时,数组很难处理。所以我想我可以把byte []变成像这样的List。
List<byte> list = waveBytes.ToList<byte>();
这会使得逐字节操作文件变得更容易,但是我担心我可能会遗漏像System.IO名称空间中的类,这会让所有这些变得更容易。我是在正确的轨道上,还是有更好的方法来做到这一点?我还要提一下,我并不十分关心性能,也不愿意处理像this guy这样的指针或不安全的代码块。
如果它对RIFF / WAV文件格式a good article有帮助的话。
答案 0 :(得分:1)
我没有用C#编写,但可以指出一些从我的观点来看不好的地方:
1)不要在内存中读取整个WAV文件,除非这些文件是您自己的文件并且知道它们的尺寸很小。
2)无需在内存中插入数据。例如,您可以执行以下操作:分析源文件,存储块的偏移量,并在内存中读取元数据;在对话框中显示要编辑的元数据;保存写入RIFF-WAV标头,fmt chunk,从源文件传输音频数据(通过读写块),添加元数据;更新RIFF-WAV标题。
3)尝试在文件尾部保存元数据。这将导致交替只有标签不需要重写整个文件。
有关使用C#中的RIFF文件的一些消息来源似乎存在here。