Jump to content
  • Advertisement
Sign in to follow this  
helpmenow

loading sound

This topic is 3829 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

im haveing a problem loading a wav file i can get it to load but there just seems to be a little bit of garbage data at the begining of the sound so i hacked the code a bit and it seems to work but i want to do it the right way will somebody help me. this code is all from How to Load a Wave File by Nathan "nPawn" Davidson i had to modifiy it a lot sorry i dont know how to post code fstream file; file.open(Path, ios::in | ios::binary); if(file) { char id[5], *sound_buffer; //four bytes to hold 'RIFF' DWORD size; //32 bit value to hold file size WORD format_tag, channels, block_align, bits_per_sample; //our 16 values DWORD format_length, sample_rate, avg_bytes_sec, data_size, i; //our 32 bit values id[4] = '\0'; file.read(reinterpret_cast<char *>(&id[0]), sizeof(char) * 4); // --------------- UpperString(id); if (FindString(id, "RIFF")) { file.read(reinterpret_cast<char *>(&size), sizeof(DWORD)); // --------------- file.read(reinterpret_cast<char *>(&id[0]), sizeof(char) * 4); // --------------- UpperString(id); if (FindString(id, "WAVE")) { file.read(reinterpret_cast<char *>(&id[0]), sizeof(char) * 4); file.read(reinterpret_cast<char *>(&format_length), sizeof(DWORD)); file.read(reinterpret_cast<char *>(&format_tag), sizeof(WORD)); file.read(reinterpret_cast<char *>(&channels), sizeof(WORD)); file.read(reinterpret_cast<char *>(&sample_rate), sizeof(DWORD)); file.read(reinterpret_cast<char *>(&avg_bytes_sec), sizeof(DWORD)); file.read(reinterpret_cast<char *>(&block_align), sizeof(WORD)); file.read(reinterpret_cast<char *>(&bits_per_sample), sizeof(WORD)); file.read(reinterpret_cast<char *>(&id[0]), sizeof(char) * 4); // data corrupt file.read(reinterpret_cast<char *>(&data_size), sizeof(DWORD)); file.read(reinterpret_cast<char *>(&id[0]), sizeof(char) * 4); // this is hack file.read(reinterpret_cast<char *>(&id[0]), sizeof(char) * 4); // this is hack file.read(reinterpret_cast<char *>(&id[0]), sizeof(char) * 4); // this is hack file.read(reinterpret_cast<char *>(&id[0]), sizeof(char) * 4); // this is hack size -= 40 + 16; // have to use file size because data is corrupt (header + hack) sound_buffer = new char[size]; //set aside sound buffer space file.read(reinterpret_cast<char *>(&sound_buffer[0]), sizeof(char) * size); [Edited by - helpmenow on June 16, 2008 12:17:34 AM]

Share this post


Link to post
Share on other sites
Advertisement
You can find the .wav format specifications on MSDN. There are several variants of the .wav header.

What you read in the "//data corrupt" line is the ExtraInformationSize field of the WAVEFORMATEX structure, indicating the number of additional bytes of data that follow the normal WAVEFORMATEX header fields. It is used for the WAVEFORMATEXTENSIBLE structure and houses 3 additional fields: number of valid bits per sample, a mask indicating which speakers the channels are mapped to and a GUID indicating the .wav's sub format.

That should do the trick:

file.read(reinterpret_cast<char *>(&id[0]), sizeof(char) * 4);
file.read(reinterpret_cast<char *>(&format_length), sizeof(DWORD));
file.read(reinterpret_cast<char *>(&format_tag), sizeof(WORD));
file.read(reinterpret_cast<char *>(&channels), sizeof(WORD));
file.read(reinterpret_cast<char *>(&sample_rate), sizeof(DWORD));
file.read(reinterpret_cast<char *>(&avg_bytes_sec), sizeof(DWORD));
file.read(reinterpret_cast<char *>(&block_align), sizeof(WORD));
file.read(reinterpret_cast<char *>(&bits_per_sample), sizeof(WORD));

if(format_tag == WAVEFORMATPCM) {
// Skip format_length - 18 bytes
// These could have been used for whatever purpose
} else if(format_tag == WAVEFORMATEXTENSIBLE) {
WORD validBitsPerSample;
DWORD chanelMaskFlags;
GUID subFormat;

file.read(reinterpret_cast<char *>(&validBitsPerSample), sizeof(WORD));
file.read(reinterpret_cast<char *>(&channelMaskFlagslength), sizeof(DWORD));
file.read(reinterpret_cast<char *>(&subFormat), sizeof(GUID));
// Skip format_length - 40 bytes
// These could have been used for whatever purpose

if(subFormat != KSDATAFORMAT_SUBTYPE_PCM) {
// Wave is compressed or doesn't contain PCM data
throw runtime_error("Unsupported .wav file format");
}

} else {
// Wave is compressed or doesn't contain PCM data
throw runtime_error("Unsupported .wav file format");
}

Share this post


Link to post
Share on other sites
Another example for PCM format.


struct WAVE_HEADER{
char chHeaderChunkID[4];
long lHeaderChunkSize;
char chSubchunkID[4];

char chFormatTag[4];
unsigned long dwFormatChunkSize;
unsigned short wAudioFormat; //PCM için 1
unsigned short wChannels;
unsigned long dwSamplesPerSec;
unsigned long dwAvgBytesPerSec;
unsigned short wBlockAlign;
unsigned short wBitsPerSample;

char chDataChunkID[4];
unsigned long dwDataChunkSize;
};

char *buff;
FILE * fp;
fp=fopen("c:\\a.wav","rb");
fread(&WaveHeader,sizeof(WAVE_HEADER),1,fp);
buff=new char[WaveHeader.dwDataChunkSize];
fread(buff,WaveHeader.dwDataChunkSize,1,fp);




Share this post


Link to post
Share on other sites
@3ddreams: That's very scary code. Some suggestions:

- Without #pragma pack, you're ignoring alignment issues which may cause the offsets of your struct members to no longer match the file format.

- There's no guarantee the 'fmt ' chunk comes directly after the file header. And no guarantee that the 'data' chunk comes directly after the 'fmt ' chunk. There are lots of variations of the .wav format with additional tags out there.

- You are assuming all .wav files use WAVEFORMATEX. Windows 2000 introduced an new format called WAVEFORMATEXTENSIBLE that doesn't match your structure and would result in your dwDataChunkSize containing garbage. This page has some wave files using the new format for testing: Wave File Examples.

Share this post


Link to post
Share on other sites
I show olny an example one of wave formats. This is not constant way for loading wave files. But if file format is constant this code works.

Share this post


Link to post
Share on other sites
ok cygon ive checked your code out and i dont know where the WAVEFORMATPCM is defined i would like to try it out but since i cant guess what value it is i need to know a header file or something your code seems like it would work though

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!