How to Read and Write Wav Files

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Hey guys. First time poster, long time lurker.

Over on my computer music blog, I just posted an article that explains how to read and write wav files. It goes over the file specification, and provides source code for wav file IO in both C++ and VB.Net. I thought that some programmers here might be interested in the article and the source code.

Here is the link:
http://www.thisisnotalabel.com/How-to-R ... and-VB.php

I hope that helps somebody, although I know most of you are more dedicated to plugins than to stand-alone audio apps. :)
my computer music blog is here: www.thisisnotalabel.com

Post

PaulMorel wrote:Hey guys. First time poster, long time lurker.

Over on my computer music blog, I just posted an article that explains how to read and write wav files. It goes over the file specification, and provides source code for wav file IO in both C++ and VB.Net. I thought that some programmers here might be interested in the article and the source code.

Here is the link:
http://www.thisisnotalabel.com/How-to-R ... and-VB.php

I hope that helps somebody, although I know most of you are more dedicated to plugins than to stand-alone audio apps. :)
Cool, I've got some comments on you r code though.

1. It seems you don't care about the endian-issue (c-style casting stuff to char*), so your code will probably not work on big-endian platforms like PPC macs.

2. The code doesn't free memory it allocates. I count seven "new" and zero "delete".

Post

Right, I ignored the endian issue, because this is just supposed to be an introduction. I find that whenever I use the word "endian" around non-programmers, they tend to get that glazed, half-asleep look on their faces! :D But you're absolutely right. Advanced users need to be aware of the systems they are targeting, as endian-ness can really bite you in the butt!

As per the missing deletes ... well, that's what happens when you translate code from VB to C at 3 in the morning ... heh. Thanks for pointing that out!

Also, thanks for the additional link. I'm going to take a look at your code as soon as I get home.
my computer music blog is here: www.thisisnotalabel.com

Post

PaulMorel wrote:As per the missing deletes ... well, that's what happens when you translate code from VB to C at 3 in the morning ... heh. Thanks for pointing that out!

Also, thanks for the additional link. I'm going to take a look at your code as soon as I get home.
As I hit "submit" I looked through my code and noticed I didn't take proper care of endianess either, so edited away the link :)

Post

I put the forgotten deletes in that C code.
my computer music blog is here: www.thisisnotalabel.com

Post

I only gave a quick look to the C version.

To be honest, this is the way you should *NOT* read a wave file.
I'm sorry, I don't want to sound like a jerk, and I really appreciate your effort and the time you spent on that, but it is very important to *NOT* make any assumptions about the absolute offset of the information in a wave file.

The wave file is a chunk-based format. The chunks can have variable sizes (yes, even the "fmt " chunk) and appear in different order. Some chunks you don't support could appear between the "fmt " and "data" etc..., so you should check for them and ignore them if necessary.

Your code should also check that you are really reading a "RIFF" file and that the format is "WAVE" and return false if it's not. As it is right now, it is not checking anything and is always returning true. Obviously you should also check that it's really PCM data if you just support that etc...

Post

NickSonic wrote:The wave file is a chunk-based format. The chunks can have variable sizes (yes, even the "fmt " chunk) and appear in different order. Some chunks you don't support could appear between the "fmt " and "data" etc..., so you should check for them and ignore them if necessary.

Your code should also check that you are really reading a "RIFF" file and that the format is "WAVE" and return false if it's not. As it is right now, it is not checking anything and is always returning true. Obviously you should also check that it's really PCM data if you just support that etc...
I wrote a generic "chuck" framework in C#. So its probably not usable "as is" for you C++ guys and its not testen for a wide range of applications (just midi files). But if anyone's interested in the code just contact me at obiwanjacobi at hotmail dot com.

The initial version of the framework parses FourCC codes and tries to find a handler for that FourCC code. That handler knows how to read and write that specific chunk of data. So reading and writing a wave file is just a matter of implementing the handlers for the chunks you want to handle.

I've begun to extend the framework with a schema but it is not finished yet. This schema will tell the framework the layout of the chunks to expect and can validate the structure when writing a file, for instance.

The framework uses a service container to hold services that can read numbers and strings (in big and little endian). Chunk handlers can also add services other chunk handlers can use. There are several that the framework uses and that should be initialized by the root chunk, but the mechanism is extensible.

The framework should be compatible with all chunky file formats (bitmaps, midi files, wave files etc).
Grtx, Marc Jacobi.
VST.NET | MIDI.NET

Post

http://xhip.cjb.net/temp/public/riff.cpp
http://xhip.cjb.net/temp/public/riff.h

this is how you should read a riff file - although this implementation is terrible and intended only for my personal use. feel free to write your own improved version based upon it. pay special attention to the lack of strict checking of the chunk sizes, that should be fixed in a quality implementation.

Post

aciddose wrote:http://xhip.cjb.net/temp/public/riff.cpp
http://xhip.cjb.net/temp/public/riff.h

this is how you should read a riff file
It seems like (unless I'm mistaken) the endianness issue is not handled for the sample data. So if you're trying to use this on a PPC beware.

Post

if you're trying to load a riff file on a ppc you should already know the endianness is reversed, really. anyway the sample data isnt important as you can fix that externally: if you use this on a ppc the important issue will be that all the information words will be reversed. (samples for example will be huge and cause all kinds of problems.) i've only included this check because certain compilers use big or little endianness with multi-byte chars. since i'm using strings in the current code it isnt even necessary.

like i said though - this is my personal code. nobody may use this without my express permission. you may use it in order to learn to write your own if you wish.

Post

This article is supposed to be a "How-To", not a programming practices article.

Yes, I left out a lot of the intricacies of the format. The article is supposed to give people a practical introduction to WAV IO, not school them in format minutiae. The truth is, it's aimed more at musicians who want to be programmers than at programmers who are also musicians.

I DID leave out almost ALL data checks. I never really confirm that the data is good at all. I also left out anything having to do with endian-ness, and I even left in some classic code vulnerabilities. I didn't want to confuse the audience with details that they didn't absolutely need. I wanted to get them started.

Anyway, I updated the article to make this more explicit. Thanks for the feedback, but please keep in mind that the article is an introduction, not a textbook. :wink: I understand that it won't help you pros.
my computer music blog is here: www.thisisnotalabel.com

Post

the main issue though isnt error handling or anything of that nature - it's that you need to use chunk based input with definitions of the structs. in your code you simply assume certain words are located in certain places and you are not reading the format correctly. for example, although the "standard" riff file is called .wav and contains RIFF, WAVE, fmt , and DATA, avi files are also RIFF. the chunks fmt , and DATA do not need to be the first in the file - there may be lots of other chunks first. there may also be multiple fmt , and DATA chunks each containing information about seperate sections of some audio data linked up in a cue-list.

it's very simple to read in the chunks, that is why i posted my code. you should modify yours to use simple c-style functions for locating the chunks as i do in mine.

Post

I don't want to beat a dead horse, but like I said, it's an introduction.

Adding in the code you want to add in would confuse the audience I am aiming at.

Obviously, the files could be different. Yes, I am aware that other types of data can be stored in RIFF files. I'm kind of assuming that the musician-programmer knows he is reading audio files ... And yes, like I said, I know that the specification is more complex, but in my experience, 99% of wav files can be read with these hardcoded offsets ...

Like I say in the article, advanced users who are writing commercial applications will need to dig more in depth, but for musicians who want to record a wav file in Audacity, and play with it in their own program, this will work most of the time. If it doesn't work, it will at least help them understand the basics of the format ...

I guess next time, I will keep this beginners level information out of this forum? ... or something ... I guess this isn't as useful as I thought (to you guys) ... oy
my computer music blog is here: www.thisisnotalabel.com

Post

well, it's just that if you have read my code you may see that it's actually quite a lot simpler and easier to understand. remove the bits that you dont use in your code (you dont use the saving, loop points, and a lot of other extra information) and suddenly the whole bit fits in a very short bit of code.

you're making it out as if doing things correctly takes a whole lot of extra effort, but really it is at worst an equal amount of effort and in my opinion it is actually less effort.

Post

PaulMorel wrote:Hey guys. First time poster, long time lurker.

Over on my computer music blog, I just posted an article that explains how to read and write wav files. It goes over the file specification, and provides source code for wav file IO in both C++ and VB.Net. I thought that some programmers here might be interested in the article and the source code.

Here is the link:
http://www.thisisnotalabel.com/How-to-R ... and-VB.php

I hope that helps somebody, although I know most of you are more dedicated to plugins than to stand-alone audio apps. :)
thanks :) this seems like the thing no one wants to teach you. :hihi:
A pointer points to an.....OK, you know what...I quit....
Laserbeak43

Post Reply

Return to “DSP and Plugin Development”