Buffer size problem

View: New views
11 Messages — Rating Filter:   Alert me  

Buffer size problem

by Jimmy Gervais :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I created a simple program to experiment with OpenAl before getting into more serious work. The program generates white noise. The problem is that it crashes when the buffer size is higher than about 280'000, sometimes less. I tested in MONO16 and STEREO16, it makes no difference. The size variable is of ALsizei type, and everything else also follows AL "standard". I looked on the Internet to see what was the max size, and read 1GB. It hangs at alBufferData(), but sometimes it gets over it without making any sound. I really don't get it.

I'm on a HP laptop working with 3GB of RAM, AMD Turion X2 64 2GHz, vista 32 bits.

Any hint would be much appreciated. Thank you!

Jimmy


_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Re: Buffer size problem

by Zarnick Maelstorm :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Are you sure you're not leaking any kind of memory in the process? Could you post some code?

Zarnick
http://www.geekvault.org


On Fri, Jul 3, 2009 at 3:05 PM, Jimmy Gervais <jimbo8086@...> wrote:
Hi,

I created a simple program to experiment with OpenAl before getting into more serious work. The program generates white noise. The problem is that it crashes when the buffer size is higher than about 280'000, sometimes less. I tested in MONO16 and STEREO16, it makes no difference. The size variable is of ALsizei type, and everything else also follows AL "standard". I looked on the Internet to see what was the max size, and read 1GB. It hangs at alBufferData(), but sometimes it gets over it without making any sound. I really don't get it.

I'm on a HP laptop working with 3GB of RAM, AMD Turion X2 64 2GHz, vista 32 bits.

Any hint would be much appreciated. Thank you!

Jimmy


_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal



_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Re: Buffer size problem

by Jimmy Gervais :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 Here's the code:

    /* initialize random seed: */
    srand ( time(NULL) );

    ALCdevice* Device;
    ALCcontext* Context;

    ALsizei taille = 260000; // The size of my buffer
    ALuint * MesTampons; // My AL buffer pointers
    ALuint * LaSource; // My AL source pointer
    MesTampons = new ALuint[2];
    LaSource = new ALuint[1];

    ALvoid * PTampon1; // My Buffer
    short * Tampon1;
    Tampon1 = (short*)PTampon1;
    Tampon1 = new short [taille];

    alGenBuffers(2,MesTampons);

    // I generate pseudo white noise for testing purpose
    double AleatD;
    ALuint Aleat;
    for(int i = 0; i < taille; i++)
    {
        AleatD = rand() * pow(2,16);
        Aleat = (ALuint)AleatD;
        Tampon1[i] = Aleat;
    }

    // Open the default device
    Device = alcOpenDevice(NULL); // select the "preferred device"
    if (Device)
    {
        Context=alcCreateContext(Device,NULL);
        alcMakeContextCurrent(Context);
    }

std::cout << "Buffers ... " << std::endl;
    alBufferData(MesTampons[0], AL_FORMAT_STEREO16, PTampon1, taille, 44100); // Hangs here when size >  ~ 250'000

    alGenSources(1,LaSource);
    alSourcei(LaSource[0], AL_BUFFER, MesTampons[0]);
    alSourcePlay(LaSource[0]);

std::cout << "Playing ... " << std::endl;

    // Verifying status
    ALint * Etat;
    Etat = new ALint;
    alGetSourcei(LaSource[0], AL_SOURCE_STATE, Etat);
    // Run until sound stops
    while (*Etat != AL_STOPPED)
    {
        alGetSourcei(LaSource[0], AL_SOURCE_STATE, Etat);
    }

    alcDestroyContext(Context);
    alcCloseDevice(Device);
_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Parent Message unknown Re: Buffer size problem

by Jimmy Gervais :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>Instead of using dynamic allocation, have you tried fixed buffer? Also, you can create white noise with the >alutCreateBufferWaveform().

>I'm a new user of OpenAL myself, so I'm sorry I can't provide you with more help.

Well, the size is predefined so I don't see what difference it would make. Do you?

Thanks I'll see about alutCreateBufferWaveform(). Right now I just have al, alc and alext (they came with SFML libraries). I'm going to look for alut.

>Actually, it makes difference the way the computer allocates the memory, but this is out of scope here. Try with defines, >something like this
>#define MAX_SIZE 250000
>int main(int argc, char *argv[])
>{
> ALuint buffer[MAX_SIZE];
>}
>This way you don't allocate the memory using new, and on the heap, which may lead to memory leak.



Thanks, it went up to 550000 with #define, better but doesn't really solve the prob ... ;)



_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Re: Buffer size problem

by Chris Robinson-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Friday 03 July 2009 11:40:51 am Jimmy Gervais wrote:
>     ALvoid * PTampon1; // My Buffer
>     short * Tampon1;
>     Tampon1 = (short*)PTampon1;
>     Tampon1 = new short [taille];
...
> std::cout << "Buffers ... " << std::endl;
>     alBufferData(MesTampons[0], AL_FORMAT_STEREO16, PTampon1, taille,
> 44100); // Hangs here when size >  ~ 250'000

This doesn't look right. PTampon1 is left uninitialized, Tampon1 is set to the
uninitialized value, then overwritten with a new buffer. PTampon1, still
uninitialized, is passed to alBufferData. That it sometimes works is just a
coincidence: if PTampon1 happens to be NULL, alBufferData will cause an error
and return without crashing (though attaching it to a source an d trying to
play the source will fail, too). If it's a non-NULL value, it will likely
crash.

Something like this should work:

    short * Tampon1; // My Buffer
    Tampon1 = new short [taille];
...
std::cout << "Buffers ... " << std::endl;
    alBufferData(MesTampons[0], AL_FORMAT_STEREO16, Tampon1, taille, 44100);

You don't need the extra PTampon1 pointer. It may also help to turn on
compiler warnings (-Wall -Wextra in GCC), as that would have warned you about
the uninitialized pointer.
_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Re: Buffer size problem

by Jimmy Gervais :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The call needs a ALvoid pointer, it is specified and otherwise returns an error, hence to copy. But you are right about its location, it is not initialized and then used to create an array, overwritting the memory hazardously. So I did this instead:

    ALvoid * PTampon1; // My Buffer void pointer
    short * Tampon1; // My Buffer short pointer
    Tampon1 = new short [B_SIZE]; // Initializing the short pointer with a new array
    PTampon1 = (ALvoid*)Tampon1; // Copy the short pointer into a void one

Now it doesn't crash, not even with 500MB, but I got no sound at all!! loll
I put the warning option on as you suggested, but got none either ways.
Thanks for your help, I might be half way through now.

2009/7/3 Chris Robinson <chris.kcat@...>
On Friday 03 July 2009 11:40:51 am Jimmy Gervais wrote:
>     ALvoid * PTampon1; // My Buffer
>     short * Tampon1;
>     Tampon1 = (short*)PTampon1;
>     Tampon1 = new short [taille];
...
> std::cout << "Buffers ... " << std::endl;
>     alBufferData(MesTampons[0], AL_FORMAT_STEREO16, PTampon1, taille,
> 44100); // Hangs here when size >  ~ 250'000

This doesn't look right. PTampon1 is left uninitialized, Tampon1 is set to the
uninitialized value, then overwritten with a new buffer. PTampon1, still
uninitialized, is passed to alBufferData. That it sometimes works is just a
coincidence: if PTampon1 happens to be NULL, alBufferData will cause an error
and return without crashing (though attaching it to a source an d trying to
play the source will fail, too). If it's a non-NULL value, it will likely
crash.

Something like this should work:

   short * Tampon1; // My Buffer
   Tampon1 = new short [taille];
...
std::cout << "Buffers ... " << std::endl;
   alBufferData(MesTampons[0], AL_FORMAT_STEREO16, Tampon1, taille, 44100);

You don't need the extra PTampon1 pointer. It may also help to turn on
compiler warnings (-Wall -Wextra in GCC), as that would have warned you about
the uninitialized pointer.
_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal


_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Re: Buffer size problem

by Chris Robinson-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Friday 03 July 2009 11:26:04 pm Jimmy Gervais wrote:
> The call *needs *a ALvoid pointer, it is specified and otherwise returns an
> error, hence to copy.

In C++, any pointer type can implicitly cast to a void*, as long as it doesn't
remove const-ness. Setting PTampon1 to Tampon1 like you do does the same work,
but is harder to follow.

Even if it needs the cast (by not recognizing ALvoid* as void*), then this
would work, too:
alBufferData(MesTampons[0], AL_FORMAT_STEREO16, (ALvoid*)Tampon1, taille,
             44100);

> Now it doesn't crash, not even with 500MB, but I got *no sound at all*!!

Probably the way you're generating the sound:

        AleatD = rand() * pow(2,16);
        Aleat = (ALuint)AleatD;
pow(2,16) = 1<<16 = 0x10000
0xABCD * 0x1000 = 0xABCD0000

        Tampon1[i] = Aleat;
(short)0xABCD0000 = 0x0000

The value given by rand() is effectively shifted up by 16 bits, which leaves
the bottom 16 bits as 0. When cast to a short, it takes the bottom 16 bits,
which will always be 0 (silence).
_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Re: Buffer size problem

by Jimmy Gervais :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

You pointed the right place, but the real problem was my understanding of the rand() function. In another langage it generates a floating point value between 0 and 1, which I can multiply by the max value I want. But in C++, in generates an integer between 0 and MAX_RAND, which already is 2^16. Also, my conversion was to ALuint, instead of short. The only thing left was to randomize the sign too, because 16bits audio is signed, which leads to:

 Tampon1[i] = rand() * (short)pow(-1,(rand() % 2) == 1);

Also, I noted that when the buffer is too small, that being under 8192, the Source State is AL_INITIATE, so looking for AL_STOPPED only is no good.

Now everything works fine, so thank you so much for your help!

Jimmy

2009/7/4 Chris Robinson <chris.kcat@...>
On Friday 03 July 2009 11:26:04 pm Jimmy Gervais wrote:
> The call *needs *a ALvoid pointer, it is specified and otherwise returns an
> error, hence to copy.

In C++, any pointer type can implicitly cast to a void*, as long as it doesn't
remove const-ness. Setting PTampon1 to Tampon1 like you do does the same work,
but is harder to follow.

Even if it needs the cast (by not recognizing ALvoid* as void*), then this
would work, too:
alBufferData(MesTampons[0], AL_FORMAT_STEREO16, (ALvoid*)Tampon1, taille,
            44100);

> Now it doesn't crash, not even with 500MB, but I got *no sound at all*!!

Probably the way you're generating the sound:

       AleatD = rand() * pow(2,16);
       Aleat = (ALuint)AleatD;
pow(2,16) = 1<<16 = 0x10000
0xABCD * 0x1000 = 0xABCD0000

       Tampon1[i] = Aleat;
(short)0xABCD0000 = 0x0000

The value given by rand() is effectively shifted up by 16 bits, which leaves
the bottom 16 bits as 0. When cast to a short, it takes the bottom 16 bits,
which will always be 0 (silence).
_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal


_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Re: Buffer size problem

by Chris Robinson-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Saturday 04 July 2009 1:29:27 am Jimmy Gervais wrote:
> Also, I noted that when the buffer is too small, that being under 8192, the
> Source State is AL_INITIATE, so looking for AL_STOPPED only is no good.

It should only be AL_INITIAL if it hasn't been started. If alBufferData fails,
then alSourcei(LaSource[0], AL_BUFFER, MesTampons[0]); and
alSourcePlay(LaSource[0]); will both fail too, leaving the source in an
AL_INITIAL state. Be sure to regularly check for errors using alGetError()
after calls which can fail (the need to do that can be mitigated by verifying
parameters before calling the al* functions, though some functions, like
alGenSources and alSourcei(..., AL_BUFFER, ...) can still generate an error).

In particular, the buffer size passed to alBufferData needs to be a multiple
of the block size (eg. multiple of 4 for STEREO16).
_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Re: Buffer size problem

by Jimmy Gervais :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Yeah I meant AL_INITIAL sorry. I take good note of your advices.

By the way, I have the OpenAl Programmer's guide and Specification, but it seems to be limited to AL.h. I'd like to use ALC or ALEXT, especially because right now I'm limited to STEREO16 but I know Alext.h includes other formats with higher bitrates. What should I do? Study the headers?



2009/7/4 Chris Robinson <chris.kcat@...>
On Saturday 04 July 2009 1:29:27 am Jimmy Gervais wrote:
> Also, I noted that when the buffer is too small, that being under 8192, the
> Source State is AL_INITIATE, so looking for AL_STOPPED only is no good.

It should only be AL_INITIAL if it hasn't been started. If alBufferData fails,
then alSourcei(LaSource[0], AL_BUFFER, MesTampons[0]); and
alSourcePlay(LaSource[0]); will both fail too, leaving the source in an
AL_INITIAL state. Be sure to regularly check for errors using alGetError()
after calls which can fail (the need to do that can be mitigated by verifying
parameters before calling the al* functions, though some functions, like
alGenSources and alSourcei(..., AL_BUFFER, ...) can still generate an error).

In particular, the buffer size passed to alBufferData needs to be a multiple
of the block size (eg. multiple of 4 for STEREO16).
_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal


_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal

Re: Buffer size problem

by Chris Robinson-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Saturday 04 July 2009 3:05:57 am Jimmy Gervais wrote:
> By the way, I have the OpenAl Programmer's guide and Specification, but it
> seems to be limited to AL.h. I'd like to use ALC or ALEXT, especially
> because right now I'm limited to STEREO16 but I know Alext.h includes other
> formats with higher bitrates. What should I do? Study the headers?

There's four standard formats: AL_FORMAT_MONO8, AL_FORMAT_MONO16,
AL_FORMAT_STEREO8, and AL_FORMAT_STEREO16. 8-bit formats use unsigned samples,
and 16-bit formats use signed samples. Stereo formats are interleaved, so the
first sample is for the left speaker, the second is for the right, etc.
There's not much to ALC, except device initialization and queries, and audio
capture (which is detailed in the spec).

The AL extensions aren't too well documented, aside partly from EFX and X-RAM
which has documentation in the OpenAL SDK. For other extensions, there's some
info here:
http://icculus.org/alextreg/
and here:
http://connect.creativelabs.com/openal/OpenAL%20Wiki/Extensions.aspx

If you have any specific questions, feel free to ask.
_______________________________________________
Openal mailing list
Openal@...
http://opensource.creative.com/mailman/listinfo/openal