views:

545

answers:

1

I'm writing an an application in C# that will record audio files (*.wav) and automatically tag and name them. Wave files are RIFF files (like AVI) which can contain meta data chunks in addition to the waveform data chunks. So now I'm trying to figure out how to read and write the RIFF meta data to and from recorded wave files.

I'm using NAudio for recording the files, and asked on their forums as well on SO for way to read and write RIFF tags. While I received a number of good answers, none of the solutions allowed for reading and writing RIFF chunks as easily as I would like.

But more importantly I have very little experience dealing with files at a byte level, and think this could be a good opportunity to learn. So now I want to try writing my own class(es) that can read in a RIFF file and allow meta data to be read, and written from the file.

I've used streams in C#, but always with the entire stream at once. So now I'm little lost that I have to consider a file byte by byte. Specifically how would I go about removing or inserting bytes to and from the middle of a file? I've tried reading a file through a FileStream into a byte array (byte[]) as shown in the code below.

System.IO.FileStream waveFileStream = System.IO.File.OpenRead(@"C:\sound.wav");
byte[] waveBytes = new byte[waveFileStream.Length];
waveFileStream.Read(waveBytes, 0, waveBytes.Length);

And I could see through the Visual Studio debugger that the first four byte are the RIFF header of the file. alt text

But arrays are a pain to deal with when performing actions that change their size like inserting or removing values. So I was thinking I could then to the byte[] into a List like this.

List<byte> list = waveBytes.ToList<byte>();

Which would make any manipulation of the file byte by byte a whole lot easier, but I'm worried I might be missing something like a class in the System.IO name-space that would make all this even easier. Am I on the right track, or is there a better way to do this? I should also mention that I'm not hugely concerned with performance, and would prefer not to deal with pointers or unsafe code blocks like this guy.

If it helps at all here is a good article on the RIFF/WAV file format.

+1  A: 

I did not write in C#, but can point on some places which are bad from my point of view:

1) Do not read whole WAV files in memory unless the files are your own files and knowingly have small size.

2) There is no need to insert a data in memory. You can simply for example do about the following: Analyze source file, store offsets of chunks, and read metadata in memory; present the metadata for editing in a dialog; while saving write RIFF-WAV header, fmt chunk, transfer audio data from source file (by reading and writing blocks), add metadata; update RIFF-WAV header.

3) Try save metadata in the tail of file. This will results in alternating only tag will not require re-writing of whole file.

It seems some sources regarding working with RIFF files in C# are present here.

VitalyVal
Good points thanks. The wave files I'm trying to tag are rather large as they are CD quality recordings of songs so they are around 50-100 mb each. So far the example files I've found have add the meta data (INFO:LIST) at the end of the file, but I'd definitely like to write my class to account for the chunks being in any order.
Eric Anastas
Of cause you should be capable to read anylocated matadata, but writing metadata to the end of file would be preferable. As you noted, most of tagged files you found have tags at the end of file. Moreover, I think, majority of WAV files you will found will not contain metadata at all (in destinct from MP3 files). So tagging WAV files without rewriting them will be possible in majority of cases.
VitalyVal