Search code examples
c++audio3dopenal

OpenAL not playing sound


I have been working with OpenAL and I can't get it working. I figure the fault should lie in either OpenAL or my parser.

OpenAL:

/* has been initialized */
device = alcOpenDevice(NULL);
if (!device) { /* HANDLE ERROR */ } 
context = alcCreateContext(device, NULL);
if (!context) { /* HANDLE ERROR */ }

/* source has been created */
alGenSources(1, &sourceID);
alSourcef(sourceID, AL_GAIN, 1);
alSourcef(sourceID, AL_PITCH, 1);
alSource3f(sourceID, AL_POSITION, 0, 0, 15);

/* listener has been set up */
alListenerf(AL_GAIN, 1);
alListener3f(AL_POSITION, 0, 0, 15);

/* audio buffer has been created */

/* WAV PARSER CODE GOES UP HERE */
ALuint audioBuffer;
alGenBuffers(1, &audioBuffer);
alBufferData(audioBuffer, format, buffer, dataSize, sampleRate);

/* a sound has been played (or tried to, at least) */
alSourcei(sourceID, AL_BUFFER, audioID);
alSourcePlay(sourceID);
alSourcei(sourceID, AL_BUFFER, 0);    

The reason I suspect OpenAL is because alGenSources and alGenBuffers seem to consistently out 3435973836 instead of the sensible number of 1 or 0. However, when I do alGetError(), there's never an error.

Parser:
For the sake of brevity, I'll try to substitute certain code blocks with comments and trim the code.

FILE* file = fopen(fileName.c_str(), "rb");
char type[5];
type[4] = '\0';
// check to make sure the file is valid using 'fread(type, sizeof(char), 4, file)'
// then compare strcmp(type, "RIFF") != 0
// this is repeated for "RIFF", "WAVE", and "fmt "

// the following variables were all declared earlier in the method
fread(&chunkSize, sizeof(int), 1, file);
fread(&formatType, sizeof(short), 1, file);
fread(&channels, sizeof(short), 1, file);
fread(&sampleRate, sizeof(int), 1, file);
fread(&avgBytesPerSec, sizeof(int), 1, file);
fread(&bytesPerSample, sizeof(short), 1, file);
fread(&bitsPerSample, sizeof(short), 1, file);
// check to see if we're at the audio data now using fread and strcmp
// strcmp(type, "data") != 0

fread(&dataSize, sizeof(int), 1, file);
unsigned char* buffer = new unsigned char[dataSize];
fread(buffer, sizeof(char), dataSize, file);

ALenum format = bitsPerSample == 8 ? (channels == 1 ? AL_FORMAT_MONO8 : AL_FORMAT_STEREO8) : (channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
// audio buffer creation here

(Un)fortunately, my parser also doesn't print out any error messages. At this point I'm stuck.

  • My parser seems to be working
  • OpenAL initialized without any issues
  • a source and listener has been set up
  • an audio buffer has been attempted to be played

What is the issue here?

Edit
I've been tossing the bit of code around for many hours and still have no idea how to proceed. I also have no idea how to debug as I'm not getting any errors from OpenAL or my parser. Any help would be appreciated.


Solution

  • I had the same issue today and found this post on google. After two more hours of searching I finally got this working so let me answer this for future googlers.

    If OpenAL initializes but the generated buffers do not start at 1, then it is likely the device was not setup. Here is a handy tutorial I found that shows how to explicitly select a valid device instead of saying alcOpenDevice(NULL): https://ffainelli.github.io/openal-example/

    I used the list_audio_devices() function and got "OpenAL Soft" which I passed to alcOpenDevice() and I was able to generate buffers for sources and buffers.

    After I got OpenAL working I tried writing a parser and ran into more trouble. Let me help out anyone looking to do .wav parsing as well...

    This link shows how a standard .wav file is laid out in great detail: http://soundfile.sapp.org/doc/WaveFormat/ using this I was able to write the parser esaily.

    Two other resources I used were: https://www.youtube.com/watch?v=V83Ja4FmrqE and https://www.youtube.com/watch?v=YIdgeuEjZoE&t=678s . They show how to read a .wav file, but with some errors. The main issue is that they were reading the chunkSize in the wrong order. But they are useful to show simple fread()ing if you need it. Use the Micorsoft WaveFormat link above for proper formatting.

    One last thing, that took me a long time to fix. Make sure that your fopen_s() read argument is set to "rb", not "r"! Otherwise fread() will prematurely find the end of the file and not read all the data of the audio chunk, giving you a return value that is less than the chunkSize.

    After those fixes I heard sound! ALthough I did not notice it right away because I was stepping through my code. One time I heard a glitchy sound while stepping, then let the code run and the sound played properly.

    I hope this helps. Cheers.