Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Playing sound with OpenAL (no alut) [solved]
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Portage & Programming
View previous topic :: View next topic  
Author Message
tenspd137
Guru
Guru


Joined: 22 Aug 2006
Posts: 391

PostPosted: Mon Oct 22, 2012 3:28 am    Post subject: Playing sound with OpenAL (no alut) [solved] Reply with quote

Hi all,

I was trying to figure out how to get a sample OpenAL program to work. It appears to do everything but play the sound. I found it while googling and fixed it up for Linux (was orginally a windows tutorial)

Code:

#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <AL/al.h>
#include <AL/alc.h>
#include <string>
using namespace std;

typedef unsigned int DWORD;
typedef unsigned char BYTE;

int endWithError(string msg, int error=0)
{
    //Display error message in console
    cout << msg << "\n";
    return error;
}

int main(int argc, char *argv[])

    //Loading of the WAVE file
    FILE *fp = NULL;                                                            //Create FILE pointer for the WAVE file
    fp=fopen("WAVE/Sound.wav","rb");                                            //Open the WAVE file
    if (!fp) return endWithError("Failed to open file");                        //Could not open file
   
    //Variables to store info about the WAVE file (all of them is not needed for OpenAL)
    char type[4];
    DWORD size,chunkSize;
    short formatType,channels;
    DWORD sampleRate,avgBytesPerSec;
    short bytesPerSample,bitsPerSample;
    DWORD dataSize;
   
    //Check that the WAVE file is OK
    fread(type,sizeof(char),4,fp);                                              //Reads the first bytes in the file
    if(type[0]!='R' || type[1]!='I' || type[2]!='F' || type[3]!='F')            //Should be "RIFF"
    return endWithError ("No RIFF");                                            //Not RIFF

    fread(&size, sizeof(DWORD),1,fp);                                           //Continue to read the file
    fread(type, sizeof(char),4,fp);                                             //Continue to read the file
    if (type[0]!='W' || type[1]!='A' || type[2]!='V' || type[3]!='E')           //This part should be "WAVE"
    return endWithError("not WAVE");                                            //Not WAVE
   
    fread(type,sizeof(char),4,fp);                                              //Continue to read the file
    if (type[0]!='f' || type[1]!='m' || type[2]!='t' || type[3]!=' ')           //This part should be "fmt "
    return endWithError("not fmt ");                                            //Not fmt
   
    //Now we know that the file is a acceptable WAVE file
    //Info about the WAVE data is now read and stored
    fread(&chunkSize,sizeof(DWORD),1,fp);
    fread(&formatType,sizeof(short),1,fp);
    fread(&channels,sizeof(short),1,fp);
    fread(&sampleRate,sizeof(DWORD),1,fp);
    fread(&avgBytesPerSec,sizeof(DWORD),1,fp);
    fread(&bytesPerSample,sizeof(short),1,fp);
    fread(&bitsPerSample,sizeof(short),1,fp);
   
    fread(type,sizeof(char),4,fp);
    if (type[0]!='d' || type[1]!='a' || type[2]!='t' || type[3]!='a')           //This part should be "data"
    return endWithError("Missing DATA");                                        //not data
   
    fread(&dataSize,sizeof(DWORD),1,fp);                                        //The size of the sound data is read
   
    //Display the info about the WAVE file
    cout << "Chunk Size: " << chunkSize << "\n";
    cout << "Format Type: " << formatType << "\n";
    cout << "Channels: " << channels << "\n";
    cout << "Sample Rate: " << sampleRate << "\n";
    cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n";
    cout << "Bytes Per Sample: " << bytesPerSample << "\n";
    cout << "Bits Per Sample: " << bitsPerSample << "\n";
    cout << "Data Size: " << dataSize << "\n";
       
    unsigned char* buf= new unsigned char[dataSize];                            //Allocate memory for the sound data
    cout << fread(buf,sizeof(BYTE),dataSize,fp) << " bytes loaded\n";           //Read the sound data and display the
                                                                                //number of bytes loaded.
                                                                                //Should be the same as the Data Size if OK
   

    //Now OpenAL needs to be initialized
    ALCdevice *device;                                                          //Create an OpenAL Device
    ALCcontext *context;                                                        //And an OpenAL Context
    device = alcOpenDevice(NULL);                                               //Open the device
    if(!device) return endWithError("no sound device");                         
//Error during device oening
    context = alcCreateContext(device, NULL);                                   //Give the device a context
    alcMakeContextCurrent(context);                                             //Make the context the current
    if(!context) return endWithError("no sound context");                       //Error during context handeling

    ALuint source;                                                              //Is the name of source (where the sound come from)
    ALuint buffer;                                                           //Stores the sound data
    ALuint frequency=sampleRate;;                                               //The Sample Rate of the WAVE file
    ALenum format=0;                                                            //The audio format (bits per sample, number of channels)
   
    alGenBuffers(1, &buffer);                                                    //Generate one OpenAL Buffer and link to "buffer"
    alGenSources(1, &source);                                                   //Generate one OpenAL Source and link to "source"
    if(alGetError() != AL_NO_ERROR) return endWithError("Error GenSource");     //Error during buffer/source generation
   
    //Figure out the format of the WAVE file
    if(bitsPerSample == 8)
    {
        if(channels == 1)
            format = AL_FORMAT_MONO8;
        else if(channels == 2)
            format = AL_FORMAT_STEREO8;
    }
    else if(bitsPerSample == 16)
    {
        if(channels == 1)
            format = AL_FORMAT_MONO16;
        else if(channels == 2)
            format = AL_FORMAT_STEREO16;
    }
    if(!format) return endWithError("Wrong BitPerSample");                      //Not valid format

    alBufferData(buffer, format, buf, dataSize, frequency);                    //Store the sound data in the OpenAL Buffer
    if(alGetError() != AL_NO_ERROR)
    return endWithError("Error loading ALBuffer");                              //Error during buffer loading
 
    //Sound setting variables
    ALfloat SourcePos[] = { 0.0, 0.0, 0.0 };                                    //Position of the source sound
    ALfloat SourceVel[] = { 0.0, 0.0, 0.0 };                                    //Velocity of the source sound
    ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 };                                  //Position of the listener
    ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 };                                  //Velocity of the listener
    ALfloat ListenerOri[] = { 0.0, 0.0, -1.0,  0.0, 1.0, 0.0 };                 //Orientation of the listener
                                                                                //First direction vector, then vector pointing up)
    //Listener                                                                               
    alListenerfv(AL_POSITION,    ListenerPos);                                  //Set position of the listener
    alListenerfv(AL_VELOCITY,    ListenerVel);                                  //Set velocity of the listener
    alListenerfv(AL_ORIENTATION, ListenerOri);                                  //Set orientation of the listener
   
    //Source
    alSourcei (source, AL_BUFFER,   buffer);                                 //Link the buffer to the source
    alSourcef (source, AL_PITCH,    1.0f     );                                 //Set the pitch of the source
    alSourcef (source, AL_GAIN,     1.0f     );                                 //Set the gain of the source
    alSourcefv(source, AL_POSITION, SourcePos);                                 //Set the position of the source
    alSourcefv(source, AL_VELOCITY, SourceVel);                                 //Set the velocity of the source
    alSourcei (source, AL_LOOPING,  AL_FALSE );                                 //Set if source is looping sound
   
    //PLAY
    alSourcePlay(source);                                                       //Play the sound buffer linked to the source
    if(alGetError() != AL_NO_ERROR) return endWithError("Error playing sound"); //Error when playing sound
     //Pause to let the sound play
   
    //Clean-up
    fclose(fp);                                                                 //Close the WAVE file
    delete[] buf;                                                               //Delete the sound data buffer
    alDeleteSources(1, &source);                                                //Delete the OpenAL Source
    alDeleteBuffers(1, &buffer);                                                 //Delete the OpenAL Buffer
    alcMakeContextCurrent(NULL);                                                //Make no context current
    alcDestroyContext(context);                                                 //Destroy the OpenAL Context
    alcCloseDevice(device);                                                     //Close the OpenAL Device
   
    return EXIT_SUCCESS;                                                       
}



When I run it, it outputs:
Code:

Chunk Size: 16
Format Type: 1
Channels: 1
Sample Rate: 22050
Average Bytes Per Second: 22050
Bytes Per Sample: 1
Bits Per Sample: 8
Data Size: 24641
24641 bytes loaded


I tried stepping through it with ddd - no luck. I do have pulseaudio, so I opened pavucontrol - my test program doesn't show up when I run it. As a sanity check, I installed warzone2100 (which is OpenAL based) - it runs fine with sound, so I don't think my drivers are goofy. I was able to play my wave file with alsaplayer, so I don't think it is my test sound. Could someone out there who knows about OpenAL give it a shot and maybe help me figure out what I am missing? I tried looking for tutorials, but they are kind of sparse - at least the ones I found.

Thanks!


***EDIT***
I was able to later figure out what I was missing - in another example I found, I needed to add something like this
Code:


alGetSourcei(source, AL_SOURCE_STATE, &source_state);
TEST_ERROR("source state get");
while (source_state == AL_PLAYING) {
alGetSourcei(source, AL_SOURCE_STATE, &source_state);
TEST_ERROR("source state get");
}


Basically, I wasn't letting the sound play out.

Hope this little bit helps someone else.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Portage & Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum