#ifndef __WaveReader__
#define __WaveReader__
#undef min
#undef max
#include <string>
#include "Resource.h"
class WaveFile {
public:
int chunk_id;
int chunk_size;
int format;
int subchunk_1_id;
int subchunk_1_size;
short audio_format;
short num_channels;
int sample_rate;
int byte_rate;
short block_align;
short bits_per_sample;
int subchunk_2_id;
int subchunk_2_size;
char* data;
};
class WaveReader {
public:
WaveFile* fWave;
WaveReader() {
fWave = new WaveFile();
}
virtual ~WaveReader() {
if (fWave->data != NULL)
delete[] fWave->data;
delete fWave;
}
bool loadWaveHeader() {
char buffer[4];
read(buffer, 4);
if (strncmp(buffer, "RIFF", 4) != 0) {
debugMessage("Not a valid WAV file!");
return false;
}
fWave->chunk_id = toInt(buffer, 4);
read(buffer, 4);
fWave->chunk_size = toInt(buffer, 4);
read(buffer, 4);
fWave->format = toInt(buffer, 4);
read(buffer, 4);
fWave->subchunk_1_id = toInt(buffer, 4);
read(buffer, 4);
fWave->subchunk_1_size = toInt(buffer, 4);
read(buffer, 2);
fWave->audio_format = toInt(buffer, 2);
read(buffer, 2);
fWave->num_channels = toInt(buffer, 2);
read(buffer, 4);
fWave->sample_rate = toInt(buffer, 4);
read(buffer, 4);
fWave->byte_rate = toInt(buffer, 4);
read(buffer, 2);
fWave->block_align = toInt(buffer, 2);
read(buffer, 2);
fWave->bits_per_sample = toInt(buffer, 2);
read(buffer, 4);
if (strncmp(buffer, "data", 4) != 0) {
read(buffer, 4);
int _extra_size = toInt(buffer, 4);
char _extra_data[_extra_size];
read(_extra_data, _extra_size);
read(buffer, 4);
fWave->subchunk_2_id = toInt(buffer, 4);
} else {
fWave->subchunk_2_id = toInt(buffer, 4);
}
read(buffer, 4);
fWave->subchunk_2_size = toInt(buffer, 4);
return true;
}
void loadWave()
{
fWave->data = new char[fWave->subchunk_2_size];
read(fWave->data, fWave->subchunk_2_size);
}
virtual void read(char* buffer, unsigned int size) = 0;
protected:
inline int toInt(char* buffer, int len)
{
int a = 0;
for(int i = 0; i < len; i++) {
((char*)&a)[i] = buffer[i];
}
return a;
}
};
class WaveResourceReader : public WaveReader {
public:
WaveResourceReader(const char* name) :
offset(0) {
resource = Resource::open(name);
};
~WaveResourceReader() {
Resource::destroy(resource);
};
void read(char* buffer, unsigned int size) override {
size_t read_len = resource->read((void*)buffer, size, offset);
offset += read_len;
}
private:
Resource* resource;
size_t offset;
};
#endif