Reading in Wav file

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

I am trying to write code to read and write wavfiles.

My code only accepts 16bit uncompressed PCM wav files atm.

I am running my test of my code with a wavfile that is 43,847,784 bytes in size. So minus 44 byte header, that should be 43,847,740.

But when I print out SubChunk2Size, that I have read in from the header, it prints a value of 27070524.

I have no explanation for this discrepancy. All other values seem to be reading in properly.

my code to read the WavFile

Code: Select all

WavFile::WavFile(std::string filename)
{
	std::ifstream ifs;		
	ifs.open( filename, std::ios::binary | std::ios::in );

	LogStream(LOG_DEBUG) << "WavFile::WavFile - - - - BEGIN READING WAV - - - -";

	if(ifs.fail())
		throw std::invalid_argument("WavFile::WavFile : Failed to open wavFile "+filename);
		
	char hbytes[HEADER_SIZE];

	ifs.read(hbytes , HEADER_SIZE);

	// check that this is actually a wave file
    bool valid_riff = hbytes[0]=='R' && hbytes[1]=='I' && hbytes[2]=='F' && hbytes[3]=='F';
    bool valid_wave = hbytes[8]=='W' && hbytes[9]=='A' && hbytes[10]=='V' && hbytes[11]=='E';
	bool valid_ftm = (hbytes[12]=='f' && hbytes[13]=='m' && hbytes[14]=='t' && hbytes[15]==' ');
	bool valid_data = (hbytes[36]=='d' && hbytes[37]=='a' && hbytes[38]=='t' && hbytes[39]=='a');

	LogStream(LOG_DEBUG) << "WavFile::WavFile - valid_riff="<<valid_riff<<" valid_wave="<<valid_wave<<" valid_ftm="<<valid_ftm<<" valid_data="<<valid_data;
	if(!(valid_data && valid_ftm && valid_riff))
		throw std::invalid_argument("WavFile::WavFile : Invalid argument - unable to open wavfile "+filename);

	int audioFormat = ReadShort(hbytes , 20);
	int SubChunk1Size = ReadInt(hbytes , 16);

	if(audioFormat != 1 || SubChunk1Size != 16)
		throw std::invalid_argument("WavFile::WavFile : Only uncompressed PCM wave format supported."+filename);	

	int subChunk2size = ReadInt(hbytes , 40);
	m_header.num_channels = ReadShort(hbytes , 22);
	m_header.sample_rate = ReadInt(hbytes , 24);
	m_header.bits_per_sample = ReadShort(hbytes , 34);

	LogStream(LOG_DEBUG) << "WavFile::WavFile num_channels="<<m_header.num_channels << " sample_rate="<<m_header.sample_rate<<" bits_per_sample="<<m_header.bits_per_sample;

	m_pcm_data.resize( subChunk2size / sizeof(int16_t) );

	LogStream(LOG_DEBUG) << "WavFile::WavFile - subChunk2size = "<<subChunk2size;
	LogStream(LOG_DEBUG) << "WavFile::WavFile - m_pcm_data.size() = "<<m_pcm_data.size();
	ifs.read((char*)m_pcm_data.data() , subChunk2size);

	LogStream(LOG_DEBUG) << "WavFile: ifstream failbit="<<ifs.fail()<<" badbit="<<ifs.bad()<<" goodbit="<<ifs.good();

	ifs.close();

	LogStream(LOG_DEBUG) << "WavFile::WavFile - - - - END READING WAV - - - -\n";
	LogStream(LOG_DEBUG) << "WavFile::WavFile";
} 
And the output in the log...

Code: Select all

[2572] [SLOG][D] - WavFile::WavFile - - - - BEGIN READING WAV - - - -
[2572] [SLOG][D] - WavFile::WavFile - valid_riff=1 valid_wave=1 valid_ftm=1 valid_data=1
[2572] [SLOG][D] - WavFile::WavFile num_channels=2 sample_rate=96000 bits_per_sample=16
[2572] [SLOG][D] - WavFile::WavFile - subChunk2size = 27070524
[2572] [SLOG][D] - WavFile::WavFile - m_pcm_data.size() = 13535262
[2572] [SLOG][D] - WavFile: ifstream failbit=0 badbit=0 goodbit=1
[2572] [SLOG][D] - WavFile::WavFile - - - - END READING WAV - - - -

Post

Did you check that you don't have different kind of chunks before your data?

Post

Miles1981 wrote:Did you check that you don't have different kind of chunks before your data?
I am not sure what you mean? I read in the header and parsed it data, and it is congruent with what I assumed. Other than that, I am not sure what you mean.

Post

Ap0C552 wrote:I am trying to write code to read and write wavfiles.
Snakepit alert !!!
http://www.kvraudio.com/forum/viewtopic ... 3&t=447027
It's far easier to just reuse a library that already does that than reinvent this wheel again.
We are the KVR collective. Resistance is futile. You will be assimilated. Image
My MusicCalc is served over https!!

Post

My solution to this problem was to read in the header into an unsigned char array, instead of a signed char array.
It's far easier to just reuse a library that already does that than reinvent this wheel again.
I did initially look for this. If there were a single .h file I could use, that would be great. But I don't want to import some library like port audio or something.

Suggestions?

Post

I think it's good practice to write your own wav parser because inevitably you'll end up writing a midi reader and other audio-related stuff. You'll probably end up writing code around and on top of it, and you'll need to customize the code from time to time, so I think it's more elegant if you write it from the ground up, rather than using some prefab code.

Glad you solved your issue. I wrote my own wav-reader class a long time ago and i use it in nearly every plugin I make.

Post Reply

Return to “DSP and Plugin Development”