Sign in to follow this  
Fire Lancer

Problem loading wav files

Recommended Posts

Fire Lancer    189
I wrote a class for loading wav files (currently only PCM ones). It works for some files (testing with the ones for the August08 sdk in samples/media/wav), but for others it seems to corrupt something and the resulting sound data just produces a continous noise (I know my playback works fine since if i use the dx SDK's CWaveFile class it works fine...). One of the files doesnt even load. I know for this one its because theres a "PAD " section between "fmt " and "data", but having looked over the files in a hex editor none of the other files do. This file also has a "fmt " size of 40 bytes with the first 2 (the ones that define the format I thought?) being 65534, however the CWaveFile class loads it fine, so it must be PCM?? They all work fine with the CWaveFile class...
class SoundData
{
public:
	WAVEFORMATEX * GetFormat(){return &format;}
	unsigned char* GetData()  {return data;}//PCM, ADPCM or xWMA supported
	unsigned       GetSize()  {return size;}
	virtual ~SoundData(){}
protected:
	unsigned char *data;
	unsigned size;
	WAVEFORMATEX format;
};
class Wav : public SoundData
{
public:
	Wav(const std::string &file);
	virtual ~Wav();
private:
	void LoadPCM(std::ifstream &file);
};



Wav::Wav(const std::string &fileName)
{
	std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary);
	
	//check this is really a wave
	char id[4];
	file.read(id, 4);
	if(strcmp(id,"RIFF")==0)
		throw std::string("Not a media file");
	//skip over the next 4 bytes
	file.seekg(4,std::ios::cur);
	//make sure its wave
	file.read(id, 4);
	if(strcmp(id,"WAVE")==0)
		throw std::string("Not a wave file");
	//skip over "fmt "
	file.seekg(4,std::ios::cur);
	//get format chunk size and format tag
	file.read((char*)&format.cbSize, sizeof(unsigned));
	file.read((char*)&format.wFormatTag, sizeof(unsigned short));
	//decide what format we have
	switch(format.wFormatTag)
	{
	case 1:
		LoadPCM(file);
		break;
	default:
		{
			std::stringstream ss;
			ss << "Unknown wave format: " << format.wFormatTag;
			std::string str = ss.str();
			throw str;
		}
	}
	file.close();

	//done
	std::cout << "Loaded file:\n";
	std::cout << "\tChannels:         " << format.nChannels << "\n";
	std::cout << "\tSample Rate:      " << format.nSamplesPerSec << "\n";
	std::cout << "\tBits per Sample:  " << format.wBitsPerSample << "\n";
	std::cout << "\tBlock Align:      " << format.nBlockAlign << "\n";
	std::cout << "\tBytes per second: " << format.nAvgBytesPerSec << "\n";
	std::cout << "\tData Size:        " << size << "\n";
	std::cout << std::endl;
};
void Wav::LoadPCM(std::ifstream &file)
{
	if(format.cbSize < 16)
	{
		std::stringstream ss;
		ss << "Unknown format size... less than 16: " << format.cbSize;
		throw std::string(ss.str());
	}
	//----FORMAT CHUNK----///
	//we already have format tag + size
	//channels
	file.read((char*)&format.nChannels,       sizeof(unsigned short));
	file.read((char*)&format.nSamplesPerSec,  sizeof(unsigned));
	file.read((char*)&format.nAvgBytesPerSec, sizeof(unsigned));
	file.read((char*)&format.nBlockAlign,     sizeof(unsigned short));
	file.read((char*)&format.wBitsPerSample,  sizeof(unsigned short));
	//skip to end of format section
	file.seekg(format.cbSize-16,std::ios::cur);//we only know how to read the first 16 bytes, so ignore the rest
	//----DATA----//
	char str[4];
	//file.seekg(4,std::ios::cur);//skip over "data" string
	file.read(str,4);
	//data size
	file.read((char*)&size, sizeof(unsigned));
	data = new unsigned char[size*2];
	//read in the entire data section
	file.read((char*)data, size);
	//done
}
Wav::~Wav()
{
	delete[] data;
}




Share this post


Link to post
Share on other sites
Fire Lancer    189
Ok that got some of them working, except for the MusicSurround.wav from the SDK samples, it works with the CWaveFile but for my class it fails with "Unknown wave format: 65534". having checked the file in a hex editor the 16-bit format does indeed appear to be that (first 2 bytes after the size in the "fmt " section...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this