/*
 * Copyright (c) 2009 by Oleg Trifonov <otrifonow@gmail.com>
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */


#include "wav.h"



struct TWaveChunkHeader {
	char iName[4];
	unsigned int iSize;  
};


struct TWaveFormatex {
	unsigned short iFormatTag;
	unsigned short iChannels;
	unsigned int iSamplePerSec;
	unsigned int iAvgBytesPerSec;
	unsigned short iBlockAlign;
	unsigned short iBitsPerSample;
};




WavFile::WavFile() {
}


WavFile::~WavFile() {
}


// открывает файл, возвращает false в случае если возникли ошибки чтения или распознавания
bool WavFile::Open(const char* fileName) {
	TrFileStream f;

	if ( !f.Open(fileName, TrFileStream::EOpenRead) ) {
		iErrorStr = std::string("Can't open file: ") + fileName;
		return false;
	}
	while ( true ) {
		TWaveChunkHeader hdr;
		TWaveFormatex fmt;

		f.Read(&hdr, sizeof(TWaveChunkHeader));    
		std::string chunkName = hdr.iName;
		chunkName.resize(4);    
		if ( chunkName == "RIFF" ) {
			char rt[5];
			rt[4] = 0;
			f.Read(rt, 4);
			iType = rt;      
			if ( strcmp(rt, "WAVE") != 0 ) {
				iErrorStr = "unsupported type: " + iType;
				return false;
			}
		} else if ( chunkName == "fmt " ) {
			f.Read(&fmt, sizeof(TWaveFormatex));
			if ( fmt.iFormatTag != 1 ) {
				iErrorStr = "unsupported format";
				return false;
			}
			iChannels = fmt.iChannels;
			iSampleRate = fmt.iSamplePerSec;
			iBpS = fmt.iAvgBytesPerSec;
			iBitsPerSample = fmt.iBitsPerSample;
		} else if ( chunkName == "data" ) {
			int sz = hdr.iSize - 8;
			iTotalSamples = sz/fmt.iBlockAlign;
			iDurability = double(sz)/fmt.iAvgBytesPerSec;

			unsigned char *data = new unsigned char[sz];
			f.Read(data, sz);
			iData.Open(data, sz);
			delete[] data;
			return true;
		}
	}
	iErrorStr = "can't found data block";
	return false;
}