How to Read and Write Wav Files
-
- KVRian
- 940 posts since 11 Mar, 2001 from nyc
i'm sorry i meant to say the code posted from the thread starter's tutorial page. yeah there were questions that i wanted to ask about the code before i compiled it after looking through it but i didn't cause i thought it was just something you could overlook(the different chunks not of the wavefile "seeming"(from a newbs point of veiw) to not be implemented).
-edit-
and i was just trying to do what the tutorial sets out to do. read and write a wav file. i figured that once i got that working, then i'd start tearing it apart and putting new things together.
-edit-
and i was just trying to do what the tutorial sets out to do. read and write a wav file. i figured that once i got that working, then i'd start tearing it apart and putting new things together.
-
- KVRian
- 940 posts since 11 Mar, 2001 from nyc
ok i've read about the spec in more places than one, where do i go to learn after i've gotten started?PaulMorel wrote: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.I understand that it won't help you pros.
- KVRAF
- 12615 posts since 7 Dec, 2004
read my code 
you can find a lot of useful information via google as well, although it is hard to pick out those bits, 1 in 100 where the other 99 are useless.
you can ask me any questions that you have, and there are others on this board of course. as for the spec itself, if you're really wanting to be accurate you might want to get an official copy.. i'm not sure where you'd do that since as far as i know nobody does that. unless you really need extra functionality, the stuff implemented in my code should be great.
(read page #2 in this thread...)
you can find a lot of useful information via google as well, although it is hard to pick out those bits, 1 in 100 where the other 99 are useless.
you can ask me any questions that you have, and there are others on this board of course. as for the spec itself, if you're really wanting to be accurate you might want to get an official copy.. i'm not sure where you'd do that since as far as i know nobody does that. unless you really need extra functionality, the stuff implemented in my code should be great.
(read page #2 in this thread...)
-
- KVRian
- 940 posts since 11 Mar, 2001 from nyc
hehe cool thanks
i'll do that. i think i need a notepad and take notes of the structure of everything. maybe that would help me understand things better. yay a new use for the notepad i bought.
-
- KVRer
- 17 posts since 23 Mar, 2005
Hi aciddose,aciddose wrote:Code: Select all
template<class T, class FT> T hermite(const T &A, const T &B, const T &C, const T &D, const FT &X) { T E = (((B - C) * (FT)3.0 - A) + D) * (FT)0.5; T F = ((C * (FT)2.0) + A) - ((((B * (FT)4.0) + B) + D) * (FT)0.5); T G = (C - A) * (FT)0.5; return B + (((E * X) + F) * X + G) * X; }
OUCH! That is some harsh code - Am I just being picky or are the constants just a tad too anonymous (A, B, C, D, X)?
How is anyone able to decifre what you just wrote when you don't explain at least what the variables in play are?
I'm not even gonna comment on the other template helpers in the second code block...
Don't get me wrong - you are helping greatly and it is really appreciated, but when you look at code like this I don't blame anyone for saying that the learning curve is extremely steep!
But still thank you - it IS appreciated.
ooO Off to look up the hermite and others - there must be references to them as design patterns or something..
/Dennis P
- KVRAF
- 12615 posts since 7 Dec, 2004
hermite is a type of spline, which is a linear matrix transformation applied to vectors constructed from sampled points A,B,C,D.
A = s[-1]
B = s[0]
C = s[1]
D = s[2]
so you want to pass these to the function in that manner,
hermite<float>(myfloats[index-1], myfloats[index], myfloats[index+1], myfloats[index+2], fraction);
the purpose of a spline is to approximate the value of the sample at [index + fraction] based upon the values two samples before and two after that mid-point.
linear interpolation, also called 'lerp' is used to do the same thing, but only using two samples rather than four, and by merely drawing a straight line between those two samples.
i cant really explain this any further than i have at this point unless you want to learn a whole lot about vectors, linear algebra and so on. here is a bad, yet simple way to look at it: the calculations find vectors in three dimensions based upon those four sample points, and they are then put into a matrix which is multiplied with the vector formed by simply those four samples V(A,B,C,D) * M(lots of constants in 4x4 matrix), and the normal is taken and used directly as our output sample.
basically, the hermite function i've given you is a much simplified version of the whole function using matrices. we've taken all the equations out of the matrix and applied them directly, eliminating any ones or zeros and redundant calculations.
reading up about splines/cubic/hermite/etc on wikipedia is a great idea.
A = s[-1]
B = s[0]
C = s[1]
D = s[2]
so you want to pass these to the function in that manner,
hermite<float>(myfloats[index-1], myfloats[index], myfloats[index+1], myfloats[index+2], fraction);
the purpose of a spline is to approximate the value of the sample at [index + fraction] based upon the values two samples before and two after that mid-point.
linear interpolation, also called 'lerp' is used to do the same thing, but only using two samples rather than four, and by merely drawing a straight line between those two samples.
i cant really explain this any further than i have at this point unless you want to learn a whole lot about vectors, linear algebra and so on. here is a bad, yet simple way to look at it: the calculations find vectors in three dimensions based upon those four sample points, and they are then put into a matrix which is multiplied with the vector formed by simply those four samples V(A,B,C,D) * M(lots of constants in 4x4 matrix), and the normal is taken and used directly as our output sample.
basically, the hermite function i've given you is a much simplified version of the whole function using matrices. we've taken all the equations out of the matrix and applied them directly, eliminating any ones or zeros and redundant calculations.
reading up about splines/cubic/hermite/etc on wikipedia is a great idea.
-
- KVRer
- 17 posts since 23 Mar, 2005
Thank you aciddose,aciddose wrote:hermite is a type of spline, which is a linear matrix transformation applied to vectors constructed from sampled points A,B,C,D.
A = s[-1]
B = s[0]
C = s[1]
D = s[2]
so you want to pass these to the function in that manner,
hermite<float>(myfloats[index-1], myfloats[index], myfloats[index+1], myfloats[index+2], fraction);
This was exactly what I needed to know how to proceed in the right (or left?
And by knowing that the template is actually a "practically best guess" and by knowing what to feed into it, the template actually makes a lot more sense
So thank you very much for providing this info!
/Dennis P
-
- KVRian
- 940 posts since 11 Mar, 2001 from nyc
hey there aciddose,
I was gonna just PM you, but for some reason that i might sooner or later find rediculous, i've decided to post it in the thread. Hey, maybe someone will learn from it
As i continue my life-long quest to load a (frikkin)wavefile, i've decided to give your code a deeper look and pick your brain a bit(no disrespect to the thread starter, PaulMorel. you're code and tutorial was greatly appreciated
) I don't understand all of it but i figured that i could only do further examination of it through trial and error with experimentation.
I'm trying to use the LoadRIFFWAVE() function from main(). I've tried all kinds of things, one or two methods actually got the program to load, but i got this runtime error that says that the char* filename argument isn't initialized. here's a code snippet (yeah, i know you were waiting for that
)
hmm.. i got a stupid error with that one. i'll leave it as an example of things i've been trying and rewrite the code to the way i had it when it ran.
ok that's what i did. and when i run it, with with an argument like ADRIFF "C:\loadmydamn.wav" it get the error i mentioned earlier. 
P.S.
I am looking at a few different books right now, trying to find some info on pointers and functions. but nothing i've found so far is helping much. i'll keep searching.
I was gonna just PM you, but for some reason that i might sooner or later find rediculous, i've decided to post it in the thread. Hey, maybe someone will learn from it
As i continue my life-long quest to load a (frikkin)wavefile, i've decided to give your code a deeper look and pick your brain a bit(no disrespect to the thread starter, PaulMorel. you're code and tutorial was greatly appreciated
I'm trying to use the LoadRIFFWAVE() function from main(). I've tried all kinds of things, one or two methods actually got the program to load, but i got this runtime error that says that the char* filename argument isn't initialized. here's a code snippet (yeah, i know you were waiting for that
Code: Select all
// Aciddose ADRIFF.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include "c:\Documents and Settings\esiadmin\My Documents\source\aciddose\riff.h"
int main(int argc, char* argv[])
{
/*ADRIFF::PCM* wtf;
char* omfgFile = &ADRIFF::LoadRIFFWAVE;*/
if( argc != 2 )
{
std::cout << "Please specify a filename and directory." << std::endl;
}
else
{
std::cout << "Ok gonna load a .wav file in this bitz." << std::endl;
if(ADRIFF::LoadRIFFWAVE(&pcm, &filename)/*ADRIFF::LoadRIFFWAVE(ADRIFF::PCM *pcm, char *filename)*/)
{
std::cout << "File loaded in this mofo!\n" << std::endl;
}
}
return 0;
}
Code: Select all
// Aciddose ADRIFF.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include "c:\Documents and Settings\esiadmin\My Documents\source\aciddose\riff.h"
int main(int argc, char* argv[])
{
ADRIFF::PCM* wtf;
char* omfgFile;
if( argc != 2 )
{
std::cout << "Please specify a filename and directory." << std::endl;
}
else
{
std::cout << "Ok gonna load a .wav file in this bitz." << std::endl;
if(ADRIFF::LoadRIFFWAVE(wtf, omfgFile)/*ADRIFF::LoadRIFFWAVE(ADRIFF::PCM *pcm, char *filename)*/)
{
std::cout << "File loaded in this mofo!\n" << std::endl;
}
}
return 0;
}
P.S.
I am looking at a few different books right now, trying to find some info on pointers and functions. but nothing i've found so far is helping much. i'll keep searching.
- KVRAF
- 9600 posts since 17 Sep, 2002 from Gothenburg Sweden
You never set the omfgFile. You just declare it. It never gets a value. My pointer-fu is a bit weak but either omfgFile = argv; or omfgFile = argv[0];
should work i think. Don't feel like firing up MSVC for the moment. Dinner is cooking.
EDIT: Silly me. argv[0] is the name of the program. argv[1] it should be(i think);
OK. You got me firing up MSVC.
EDIT2: Yep. char* omfgFile=argv[1]; did the trick.
BTW which version of MSVC are you running ? I had to fix lots of stuff before it compiled. Could just be me sucking though.
EDIT3: You never initialize the ADRIFF::PCM* pointer either.
ADRIFF::PCM* wtf = new ADRIFF::PCM();
should do the trick.
It works here now.
should work i think. Don't feel like firing up MSVC for the moment. Dinner is cooking.
EDIT: Silly me. argv[0] is the name of the program. argv[1] it should be(i think);
OK. You got me firing up MSVC.
EDIT2: Yep. char* omfgFile=argv[1]; did the trick.
BTW which version of MSVC are you running ? I had to fix lots of stuff before it compiled. Could just be me sucking though.
EDIT3: You never initialize the ADRIFF::PCM* pointer either.
ADRIFF::PCM* wtf = new ADRIFF::PCM();
should do the trick.
It works here now.
-
- KVRian
- 940 posts since 11 Mar, 2001 from nyc
sweet!! thanks!! omg that's tricky stuff.... maybe i should go back to the very beginning of pointers and classes. omfg that's gonna suck. but i guess it must be done!!!
i'm running MSVC 2005 standard edition.
-edit-
ahh so you're the guy with the clever quote in their sig that's been getting me girls at the sophisticated parties!! i was wondering when i'd bump into that sig again
i'm running MSVC 2005 standard edition.
-edit-
ahh so you're the guy with the clever quote in their sig that's been getting me girls at the sophisticated parties!! i was wondering when i'd bump into that sig again
- KVRAF
- 9600 posts since 17 Sep, 2002 from Gothenburg Sweden
It's really easy stuff actually. Imagine the following:laserbeak wrote:omg that's tricky stuff....:
Code: Select all
int a;
int b;
int c = a + b;Code: Select all
ADRIFF::PCM* wtf;
char* omfgFile;Take the char pointer *omfgFile for example,how is it to know that it should take the value of the second argument in argv unless you tell it ?
BTW if you type "laserbeaksMarvelousWavLoadingProgram Sine.wav" in the console argv[0]= "laserbeaksMarvelousWavLoadingProgram" and argv[1]="Sine.wav" and should you add more arguments they obviously become argv[2],argv[3] and so on.
Same thing with the wtf pointer. That is a pointer to an object so it needs to be initialized with a call to the constructor. wtf = new ADRIFF::PCM();
Simple stuff really. Wait 'til you get to heavy pointer arithmetic stuff. Enough to make a grown man cry.
I'm glad i can be of service on so many levels. I'm useful in so many ways it's almost scary.ahh so you're the guy with the clever quote in their sig that's been getting me girls at the sophisticated parties!! i was wondering when i'd bump into that sig again
-
- KVRian
- 940 posts since 11 Mar, 2001 from nyc
hmm i see. i was thinking more along the lines of "i've made a pointer, here take it, damnit!!"
anyway, buddy of mines hooked me up with a series of C programming videos in .mov format and it has an extensive pointer section. i'm gonna look at this over the weekend
anyway, buddy of mines hooked me up with a series of C programming videos in .mov format and it has an extensive pointer section. i'm gonna look at this over the weekend
-
- KVRian
- 940 posts since 11 Mar, 2001 from nyc
accidose:
is this code for a basic format? it looks like it checks for a wavefile to me, but when i run it, i always get a return value of -1. i'm gonna print all the info and see if it matches a wavefile. is there any advice you could give me?
-edit-
nvm.
turns out it was my file directory syntax.
is this code for a basic format? it looks like it checks for a wavefile to me, but when i run it, i always get a return value of -1. i'm gonna print all the info and see if it matches a wavefile. is there any advice you could give me?
-edit-
nvm.
turns out it was my file directory syntax.
-
- KVRian
- 940 posts since 11 Mar, 2001 from nyc
Don't mean to bring this old topic back up but i've been finding this quite helpful. so here it is.
http://bcbjournal.org/articles/vol2/980 ... Part_I.htm
http://bcbjournal.org/articles/vol2/981 ... Part_1.htm
http://bcbjournal.org/articles/vol2/980 ... part_2.htm
http://bcbjournal.org/articles/vol2/980 ... Part_I.htm
http://bcbjournal.org/articles/vol2/981 ... Part_1.htm
http://bcbjournal.org/articles/vol2/980 ... part_2.htm
