[SOLVED] JOAL & Streaming = memory leaking?

hi, i hope someone of you guys can help me or point me in the right direction.

first here’s my setup:

		

//if it's the first time we pass this section here the source is initialised with 2 buffers (this two buffers are different to the buffers which are used for the queuing) 
if (!environmentSource.isInit()){
	System.out.println("Init");
        //This function inits the buffers with the start data of a wav file
	queueBuffers = ressMan.getBufferInitQueue(2, sourceID, queueBuffers);
	//Then i queue the buffers up on the source 			
	environmentSource.queueBuffers(queueBuffers);			 
 	environmentSource.setInit(true);
}


//Here's the part where the things go wrong
//I made it similar to the update() method in http://home.halden.net/tombr/ogg/OggPlayer.java			
if ((environmentSource.getBuffersProcessed()>0)){

      //This is the buffer which will be queued next on the source (do i need a existing one here, or can i use a newly generated?)
      environmentSource.queueBuffer = OpenALFactory.generateBuffers(1);				
	
     //Now i trie to unqueue the new generated buffer 			
      environmentSource.unqueueBuffers(environmentSource.queueBuffer);
	
     //Load data to the buffer				
     ressMan.getBufferQueue(1, sourceID, environmentSource.queueBuffer);
	
     //Queue the buffer 			
     environmentSource.queueBuffers( environmentSource.queueBuffer);
}

as u can see i’m using some functions from the Audio3D package provided with JOAL (i extendet them a little bit, just for my needs).
all buffer variables are Sound3D.Buffers, the loading of the data from the wav file works really fine. i also hear the sound and the streaming works but
i get a linear increase of memory usage because of calling:

environmentSource.queueBuffer = OpenALFactory.generateBuffers(1);

every time the source processed a buffer, but the unqeue function isn’t releasing the memory of the Buffer, i also tried to reuse the buffer but with the effect that only the data from the initialisation is queued each time?

it would be very helpful if someone could explain me what the alSourceUnqueueBuffers() really does (and how to use it in JOAL)?
and maybe how the streaming really works! And please don’t point me to tutorials which are written in C++, i already read them and they’re all using pointers to queue the buffers on the sources, since there are no pointers in java, this won’t help me, unless you know how to do something simillar in java.

it would really help me if you could port me this 2 functions to JOAL


bool ogg_stream::update()
{
    int processed;
    bool active = true;
 
    alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
 
    while(processed--)
    {
        ALuint buffer;
        
        alSourceUnqueueBuffers(source, 1, &buffer);
        check();
 
        active = stream(buffer);
 
        alSourceQueueBuffers(source, 1, &buffer);
        check();
    }
 
    return active;
}


bool ogg_stream::stream(ALuint buffer)
{
    char data[BUFFER_SIZE];
    int  size = 0;
    int  section;
    int  result;
 
    while(size < BUFFER_SIZE)
    {
        result = ov_read(&oggStream, data + size, BUFFER_SIZE - size, 0, 2, 1, & section);
    
        if(result > 0)
            size += result;
        else
            if(result < 0)
                throw oggString(result);
            else
                break;
    }
    
    if(size == 0)
        return false;
 
    alBufferData(buffer, format, data, size, vorbisInfo->rate);
    check();
 
    return false;
}

i really hope someone can explain it to me!
thanks in advance
martin

Just FYI, when you see a C OpenAL routine passing a pointer to an int or similar, in order to call the same routine from JOAL you need to allocate a 1-element int[], put your value as element 0 of that array, and pass the array (plus a 0 “offset” argument) to the associated Java binding.

Taken from the OpenAL 1.1 Programmer’s Guide w/ EFX SDK:

My understanding from this description is that unqueue buffers pulls-off buffers from what the source will play, only if the buffer has already been processed.
The thing is, unqueueing a buffer will not free-up memory. Memory can only be freed if a source or buffer is destroyed. Maybe, once the buffer has been played, you can unqueue it and then destroy the buffer.

thank you guys for your answers, they should help me a lot!

as far as i understand now things should work like this:

  1. i have to initialise the source with an array of int values, bind some data to them, and queue them up on the source using alSourceQueueBuffers()
  2. i check if a buffer has been processed by the source via the alGetSourcei() method
  3. if a buffer has been processed i can now call the alSourceUnqueueBuffers() method with a new int [] array which the function fills with the id from the unqueued buffer
  4. i can bind some new data to it using the al.alBufferData()
  5. i queue the new initialised buffer to the source using alSourceQueueBuffers()
  6. repeat steps 2-6 until there is no more data to stream from a file.

i hope i now understand it in the right way.

thanks very much
martin

as i described in the previous post, this is how it works. :slight_smile:

thank you Ken & Ultraq for pointing me in the right direction!