I am trying to download .WAV files for playback using OpenAL. I follow the example I found on the Internet, but it acts strangely. Here is the code:
struct RIFF_Header {
char chunkID[4];
long chunkSize;
char format[4];
};
struct WAVE_Format {
char subChunkID[4];
long subChunkSize;
short audioFormat;
short numChannels;
long sampleRate;
long byteRate;
short blockAlign;
short bitsPerSample;
};
struct WAVE_Data {
char subChunkID[4];
long subChunk2Size;
};
bool loadWavFile(std::string filename, ALuint* buffer,
ALsizei* size, ALsizei* frequency,
ALenum* format) {
FILE* soundFile = NULL;
WAVE_Format wave_format;
RIFF_Header riff_header;
WAVE_Data wave_data;
unsigned char* data;
*size = wave_data.subChunk2Size;
*frequency = wave_format.sampleRate;
if (wave_format.numChannels == 1) {
if (wave_format.bitsPerSample == 8 )
*format = AL_FORMAT_MONO8;
else if (wave_format.bitsPerSample == 16)
*format = AL_FORMAT_MONO16;
} else if (wave_format.numChannels == 2) {
if (wave_format.bitsPerSample == 8 )
*format = AL_FORMAT_STEREO8;
else if (wave_format.bitsPerSample == 16)
*format = AL_FORMAT_STEREO16;
}
try {
soundFile = fopen(filename.c_str(), "rb");
if (!soundFile)
throw (filename);
fread(&riff_header, sizeof(RIFF_Header), 1, soundFile);
if ((riff_header.chunkID[0] != 'R' ||
riff_header.chunkID[1] != 'I' ||
riff_header.chunkID[2] != 'F' ||
riff_header.chunkID[3] != 'F') ||
(riff_header.format[0] != 'W' ||
riff_header.format[1] != 'A' ||
riff_header.format[2] != 'V' ||
riff_header.format[3] != 'E'))
throw ("Invalid RIFF or WAVE Header");
fread(&wave_format, sizeof(WAVE_Format), 1, soundFile);
if (wave_format.subChunkID[0] != 'f' ||
wave_format.subChunkID[1] != 'm' ||
wave_format.subChunkID[2] != 't' ||
wave_format.subChunkID[3] != ' ')
throw ("Invalid Wave Format");
if (wave_format.subChunkSize > 16)
fseek(soundFile, sizeof(short), SEEK_CUR);
fread(&wave_data, sizeof(WAVE_Data), 1, soundFile);
if (wave_data.subChunkID[0] != 'd' ||
wave_data.subChunkID[1] != 'a' ||
wave_data.subChunkID[2] != 't' ||
wave_data.subChunkID[3] != 'a')
throw ("Invalid data header");
data = new unsigned char[wave_data.subChunk2Size];
if (!fread(data, wave_data.subChunk2Size, 1, soundFile))
throw ("error loading WAVE data into struct!");
*size = wave_data.subChunk2Size;
*frequency = wave_format.sampleRate;
if (wave_format.numChannels == 1) {
if (wave_format.bitsPerSample == 8 )
*format = AL_FORMAT_MONO8;
else if (wave_format.bitsPerSample == 16)
*format = AL_FORMAT_MONO16;
} else if (wave_format.numChannels == 2) {
if (wave_format.bitsPerSample == 8 )
*format = AL_FORMAT_STEREO8;
else if (wave_format.bitsPerSample == 16)
*format = AL_FORMAT_STEREO16;
}
alGenBuffers(2, buffer);
if(alGetError() != AL_NO_ERROR) {
std::cerr << alGetError() << std::endl;
}
alBufferData(*buffer, *format, (void*)data,
*size, *frequency);
if(alGetError() != AL_NO_ERROR) {
std::cerr << alGetError() << std::endl;
}
fclose(soundFile);
delete data;
return true;
} catch(const char* error) {
std::cerr << error << " : trying to load "
<< filename << std::endl;
if (soundFile != NULL)
fclose(soundFile);
delete data;
return false;
}
}
int main() {
ALuint buffer, source;
ALint state;
ALsizei size;
ALsizei frequency;
ALenum format;
ALCcontext *context;
ALCdevice *device;
device = alcOpenDevice(nullptr);
if (device == NULL)
{
cerr << "Error finding default Audio Output Device" << endl;
}
context = alcCreateContext(device,NULL);
alcMakeContextCurrent(context);
alGetError();
loadWavFile("test.wav", &buffer, &size, &frequency, &format);
alGenSources(1, &source);
alSourcei(source, AL_BUFFER, buffer);
alSourcePlay(source);
do {
alGetSourcei(source, AL_SOURCE_STATE, &state);
} while (state == AL_PLAYING);
alDeleteSources(1, &source);
alDeleteBuffers(1, &buffer);
return 0;
}
I have several WAV files about 50 KB in size. They load and play just fine. However, when I try to download the whole song (yes, I confirmed that the file was correctly formatted using VLC Media Player and MusicBee), it returns "Invalid data header: trying to load test.wav", which is called by this fragment right here:
if (wave_data.subChunkID[0] != 'd' ||
wave_data.subChunkID[1] != 'a' ||
wave_data.subChunkID[2] != 't' ||
wave_data.subChunkID[3] != 'a')
throw ("Invalid data header");
, - , , , 1000 ( , , ). , , . !