Question

I am having an issue loading a WAV file in OpenAL. I have a function that opens the file data and casts it to a header struct. Because I know the alignment of data, I simply cast the data pointer as my data header aligned struct.

The issue is that I cannot figure out why it is throwing me 40963. If the header data in the file is correct, I must be doing something wrong with the alBufferData. I haven't used OpenAL until now, so I might be doing something obviously wrong.

Here is my code:

WAV_HEADER

#pragma pack(1)
typedef struct
{
    uint32_t Chunk_ID;
    uint32_t ChunkSize;
    uint32_t Format;

    uint32_t SubChunk1ID;
    uint32_t SubChunk1Size;
    uint16_t AudioFormat;
    uint16_t NumberOfChanels;
    uint32_t SampleRate;
    uint32_t ByteRate;

    uint16_t BlockAlignment;
    uint16_t BitsPerSecond;

    uint32_t SubChunk2ID;
    uint32_t SubChunk2Size;

    //Everything else is data. We note it's offset
    char data[];

} WAV_HEADER;
#pragma pack()

WAV file loader Loader

WAV_HEADER* loadWav(const char* filePath)
{
    long size;
    WAV_HEADER* header;
    void* buffer;

    FILE* file = fopen(filePath, "r");
    assert(file);

    fseek (file , 0 , SEEK_END);
    size = ftell (file);
    rewind (file);

    buffer = malloc(sizeof(char) * size);
    fread(buffer, 1, size, file);

    header = (WAV_HEADER*)buffer;

    //Assert that data is in correct memory location
    assert((header->data - (char*)header) == sizeof(WAV_HEADER));

    //Extra assert to make sure that the size of our header is actually 44 bytes
    //as in the specification https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
    assert((header->data - (char*)header) == 44);

    fclose(file);

    return header;
}

And the function that takes care of the rest of the setup:

void AudioController::OpenFile(const char* filePath)
{
    WAV_HEADER* data = loadWav(filePath);

    ALuint buffer;
    alGenBuffers(1, &buffer);

    alBufferData(buffer, data->Format, data, data->SubChunk2Size, data->ByteRate);

    ALint error;
    if ((error = alGetError()) != ALC_NO_ERROR)
    {
        printf("OpenAL OPEN FILE ERROR: %d \n", error);
    }

    //Delete it for now to avoid leaks. Whether I need to delete the data here
    //I'll figure out later
    delete data;
}

Did I pass in something wrong into the function, or did I setup the header incorrectly?

Any help is greatly appreciated!

PS. This maybe important, here is the constructor that sets up the OpenAL environment:

AudioController::AudioController()
{
    //Open preffered audio device
    mDevice = alcOpenDevice(0);

    //Ensure that there is a device. If not something went wrong
    assert(mDevice);

    mContext = alcCreateContext(mDevice, 0);

    alcMakeContextCurrent(mContext);
    alcProcessContext(mContext);

    ALint error;
    if ((error = alGetError()) != ALC_NO_ERROR)
    {
        printf("OpenAL CONTEXT CREATION: %d \n", error);
    }

}
Was it helpful?

Solution

The format parameter you pass to alBufferData is wrong. Your value is always 'WAVE', but the function expects an OpenAL format such as AL_FORMAT_MONO16, AL_FORMAT_STEREO16, ...

You should build the correct format based on data (data->NumberOfChanels and data->BitsPerSecond in your structure).

Note two errors with your header structure:

  • Your field called BitsPerSecond is in reallity BitsPerSample (usually 8 or 16). see this

  • Maybe your wave file's header is in one block, but there is some files where the three "sub headers" (the blocks in differents color in this link) are in different locations of the file. Thus you must play with the chunk size to find where the chunk header is located. Opening your file with an hexadecimal editor helps a lot to understand correct chunk loading.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top