Advertisement

OpenAL sound dependent on object

Started by June 21, 2015 06:37 PM
3 comments, last by eReS 9 years, 6 months ago

Hello, I make myself familiar with basics of OpenAL.

I want to use the library to produce sound (let it be simple beep at first) which will be dependent on the size of an object in front of the player. By dependent I mean its position and a stereo effect. The bigger the object, the closer sound should be. Depending on object position (left/center/right) sound should also "wander" from one side to the other. (either discretized into l/c/r bins, or some (non)linear function for that, I have no experience what should that be of a function for sound)

Can you point me out idea how can I make that size- and position-dependent sound moving?

By now I managed to create movable sound source dependent on user pressing arrows from keyboard, sound de/activated by another key.

(if wanted I can paste my code however I know it is very basics).

Will be grateful for opinion on that,

thank you.

Matt

In OpenAL you have sound sources and listeners. You can move either one, or both if you want. You say you have figured out how to move a sound source using the arrow keys, so I don't understand what you are having difficulties with. Can you give an example of what you need to do?

Advertisement

Yes. I want to play a beep every 500ms with its location dependent on object. Suppose I get an image with object size and location. (small = far away, left of the image = left from listener). Beep helps me to hear where it is. Then comes next image.

I was using the only tutorial I found until that time from youtube and managed the arrow keys control this way below. The part I used for arrow navigation is commented out and directly above is part which I try and cannot make it work. If you could help me out giving an example how to make it work the way I want, I would be grateful.


#include <iostream>
#include <fstream>
#include <cstring>
#include <AL/al.h>
#include <AL/alc.h>
#include <SDL/SDL.h>

// install packages for openAL
// install packages for SDL

using namespace std;

bool isBigEndian()
{
    int a=1; // bigEndian: 0000...1, littleEndian 00000000 100...000
    return !((char*)&a)[0]; // Access 1st byte of char array, (1 if littleEndian)
}

int convertToInt(char* buffer,int len)
{
    int a=0;
    if(!isBigEndian())
        for(int i=0;i<len;i++)
            ((char*)&a)[i]=buffer[i];
    else
        for(int i=0;i<len;i++)
            ((char*)&a)[3-i]=buffer[i];
    return a;
}

char* loadWAV(const char* fn,int& chan,int& samplerate,int& bps,int& size)
{
    char buffer[4];
    std::ifstream in(fn,std::ios::binary);
    in.read(buffer,4);
    if(strncmp(buffer,"RIFF",4)!=0)
    {
        std::cout << "this is not a valid WAVE file"  << std::endl;
        return NULL;
    }
    in.read(buffer,4);
    in.read(buffer,4);      //WAVE
    in.read(buffer,4);      //fmt
    in.read(buffer,4);      //16
    in.read(buffer,2);      //1
    in.read(buffer,2);
    chan=convertToInt(buffer,2);
    in.read(buffer,4);
    samplerate=convertToInt(buffer,4);
    in.read(buffer,4);
    in.read(buffer,2);
    in.read(buffer,2);
    bps=convertToInt(buffer,2);
    in.read(buffer,4);      //data
    in.read(buffer,4);
    size=convertToInt(buffer,4);
    char* data=new char[size];
    in.read(data,size); // Read very data
    return data;
}

int main(int argc,char** argv)
{
    int channel,sampleRate,bps,size;
    char* data=loadWAV("test.wav",channel,sampleRate,bps,size);
    if (!data)
    {
        std::cout << " no data loaded " << std::endl;
        delete[] data;
    }
    else
    {std::cout << " success loading " << std::endl; }

    ALCdevice* device=alcOpenDevice(NULL);
    if(device==NULL)
    {
        std::cout << "cannot open sound card" << std::endl;
        alcCloseDevice(device);
        return 0;
    }
    ALCcontext* context=alcCreateContext(device,NULL);
    if(context==NULL)
    {
        std::cout << "cannot open context" << std::endl;
        alcDestroyContext(context);
        return 0;
    }
    alcMakeContextCurrent(context);

    unsigned int bufferid,format;
    alGenBuffers(1,&bufferid);
    if(channel==1)
    {
        if(bps==8)
        {
            format=AL_FORMAT_MONO8;
            std::cout << "mono 8" << std::endl;
        }else{
            format=AL_FORMAT_MONO16;
            std::cout << "mono 16" << std::endl;
        }
    }else{
        if(bps==8)
        {
            format=AL_FORMAT_STEREO8;
            std::cout << "stereo 8" << std::endl;
        }else{
            format=AL_FORMAT_STEREO16;
            std::cout << "stereo 16" << std::endl;
        }
    }
    alBufferData(bufferid,format,data,size,sampleRate);

    unsigned int sourceid;
    alGenSources(1,&sourceid);
    alSourcei(sourceid,AL_BUFFER,bufferid);

    //alSourcePlay(sourceid);
    //SDL_Delay(5000);

    ALint state;
    // ###### HERE PART OF CODE I TRIED AND DID NOT WORK
    while(true)
    {
        float x=1.0,z=0.0;
    
        // Set for sourceid parameter position with x,0,z
        alSource3f(sourceid,AL_POSITION,x,0,z);
        // Set for sourceid parameter looping sound continuously looping
        alSourcei(sourceid,AL_LOOPING,AL_TRUE);
        std::cout << "x: " << x << " z: " << z << std::endl;
        
        alSourcePlay(sourceid);
    }
    // ###### end
   /* SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Surface* screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);
    SDL_Event event;
    Uint32 start;
    bool running = 1;
    bool b[4]={0,0,0,0};
    // x: forward, z: to the right
    float x=1.0,z=0.0;
    while(running)
    {
        start=SDL_GetTicks();
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
            case SDL_QUIT:
                running=false;
                break;
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                case SDLK_UP:
                    b[0]=true;
                    break;
                case SDLK_RIGHT:
                    b[1]=true;
                    break;
                case SDLK_DOWN:
                    b[2]=true;
                    break;
                case SDLK_LEFT:
                    b[3]=true;
                    break;
                case SDLK_SPACE:
                    alSourcePlay(sourceid);
                    state = 1;
                    break;
                case SDLK_BACKSPACE:
                    alSourceStop(sourceid);
                    state = 2;
                    break;
                }
                break;
                case SDL_KEYUP:
                    switch(event.key.keysym.sym)
                    {
                    case SDLK_UP:
                        b[0]=false;
                        break;
                    case SDLK_RIGHT:
                        b[1]=false;
                        break;
                    case SDLK_DOWN:
                        b[2]=false;
                        break;
                    case SDLK_LEFT:
                        b[3]=false;
                        break;
                    }
                    break;
            }
        }

        if(b[0])
            z+=0.3;
        if(b[1])
            x+=0.3;
        if(b[2])
            z-=0.3;
        if(b[3])
            x-=0.3;
        // Set for sourceid parameter position with x,0,z
        alSource3f(sourceid,AL_POSITION,x,0,z);
        // Set for sourceid parameter looping sound continuously looping
        alSourcei(sourceid,AL_LOOPING,AL_TRUE);
        std::cout << "x: " << x << " z: " << z << std::endl;
        cout << " alint state is :" << state << endl;

        // Velocity for Doppler effect
        float f[]={1,0,0,0,1,0}; // 6DOFs: 3 for looking direction, "upvector"
        alListenerfv(AL_ORIENTATION,f); // Set orientation param of listener (no id -> only one listener)


        if(1000/30.0>SDL_GetTicks()-start)
            SDL_Delay(1000/30.0-(SDL_GetTicks()-start));
    }
*/

    alDeleteSources(1,&sourceid);
    alDeleteBuffers(1,&bufferid);

    alcDestroyContext(context);
    alcCloseDevice(device);
    delete[] data;
    return 0;
}

replace your while(true) loop with the following:


float x=1.0,z=0.0;

// Set for sourceid parameter position with x,0,z
alSource3f(sourceid,AL_POSITION,x,0,z);

// Set for sourceid parameter looping sound continuously looping
alSourcei(sourceid,AL_LOOPING,AL_TRUE);
std::cout << "x: " << x << " z: " << z << std::endl;
        
alSourcePlay(sourceid);

int iState;
alGetSourcei( sourceid, AL_SOURCE_STATE, &iState );


while( iState == AL_PLAYING ) {
  //sound is still playing
}

Helped, thank you!

This topic is closed to new replies.

Advertisement