OpenAL playing too fast

Started by
5 comments, last by GameDev.net 17 years, 1 month ago
When I make the buffer large enough, my OGGs play fine. However, I really don't want to make every buffer 3MBs. The way I'm doing it now, it is reloading the buffer before it is done playing, so all the information left in the buffer isn't being played. I'm doing this exactly from http://www.devmaster.net/articles/openal-tutorials/lesson8.php tutorial. Even when I use the exact code from that tutorial it isn't working for me. Anyways the problem is with my update code.
bool Ogg::update()
{
	int processed;
	bool active = true;

	alGetSourcei(_source, AL_BUFFERS_PROCESSED, &processed);

	while (processed--)
	{
		ALuint buffer;
		alSourceUnqueueBuffers(_source, 1, &buffer);
		if (!check()) return false;
		active = stream(buffer);
		alSourceQueueBuffers(_source, 1, &buffer);
		if (!check()) return false;
	}

	return active;
}
As you can see, I have no way to tell weather the buffer being dequeued has finished playing. So, it just dequeues the buffer and and then loads the stream up again and then queues it again. Thus, all the information that has not yet been played in that buffer is being lost. I can't just update it when the source isn't playing, since I'm using two buffers. If I do that, half of the song is left out. I think I just need a way to see if the buffer is finished yet and only dequeue it if it is. Can anyone help me out? I've been trying to figure this out for a while now, but I can't seem to find much help for OpenAL.
Advertisement
Hi

This might not be the answer you are looking for, because I don't completely understand some parts of your post, but I will give it a try.

Quote:
As you can see, I have no way to tell weather the buffer being dequeued has finished playing.

Isn't the buffer that done processing is actually finished playing ?

I think you need to ask the Ogg if it is has read all the data.



Here is quote from my engine fill buffer:

bool AudioStreamReader::FillBuffer(const ALuint& buffer){    au_str_size = 0;     while(au_str_size < AUDIO_STREAM_BUFFER_SIZE)    {        au_str_result = ov_read(&_stream->_originalOggFileData , au_str_data + au_str_size, AUDIO_STREAM_BUFFER_SIZE - au_str_size, 0, 2, 1, &au_str_section);            if( au_str_result > 0)            au_str_size += au_str_result;        else            if(au_str_result < 0)                Error_FillBufferFailed( __LINE__ , __FILE__);            else                break;    }    	//Reached EOF    if(au_str_size == 0)	{		_readyToDie = true;        return false;	}     alBufferData(buffer, _stream->format, au_str_data, au_str_size, _stream->vorbisInfo->rate);    ALerror;     return true;}


I have this flag _readyToDie - which indicates that all the data has been read from the ogg stream and the source should clear the buffer and stop playing.

And here is how the audio data gets streamed to the buffer
ALuint buffer;ALint iBuffersProcessed = 0;alGetSourcei( _sourceID , AL_BUFFERS_PROCESSED, &iBuffersProcessed);ALerror;// Queues / Unqueues bufferswhile(iBuffersProcessed--){	alSourceUnqueueBuffers( _sourceID, 1, &buffer);	ALerror; 	FillBuffer(buffer);			//queue buffers if there is a data for them	if( !_readyToDie)	{		alSourceQueueBuffers( _sourceID, 1, &buffer);		ALerror;	}}// Stops or continues playing//check if all buffers have playedif( _readyToDie ){	alGetSourcei( _sourceID , AL_BUFFERS_QUEUED, &iQueuedBuffers);	ALerror;			//EOF REACHED !	if( iQueuedBuffers == 0 )	{		//restart or stop it		if( _loop )		{			//LogAddT("restarting...\n");			Restart();			return true;		}		else		{			//LogAddT("stopping...\n");			Stop();			return false;		}	}}else{	//check for the possible stopped source	alGetSourcei( _sourceID, AL_SOURCE_STATE, &iState);	ALerror;	if( iState != AL_PLAYING )	{		alSourcePlay(_sourceID );		ALerror	}}


I hope this would help.
I don't think that really helps me. Here is the problem: say each buffer is 3 seconds long (I'm just making up a number) every time the update function is called it is switching to the next buffer. So, only about .1 of the 3 seconds per buffer is being played. Or at least I am pretty sure that is what is happening. It's taking about 3 seconds to play a 200 second song.

Has anyone tried to run the source code from the website? When I run the source code that I'm using to build my actual code it does the same thing, so I wasn't really expecting it to work. However, I can't find any other code that works. And I think it could possibly be that something is wrong with my computer. Unless someone else is getting the same problem I am running the example code.

Has anyone ever had a problem like this before?

Edit:

I just realized that I'm using SDL and this appears to only happen if I move the window at some point. However, if I move the window and then restart the program the sound will still be messed up regardless of weather I moved the window that time or not. Does anyone know what my be wrong now?

[Edited by - yahn on March 5, 2007 11:03:24 AM]
Hmm. Check to make sure that the Hz rate is correct for the file Playing a file at the wrong Hz rate will cause it to take a different amount of time.
I'll look into that. I didn't even know that could cause a problem. I just have it set to the default.
It looks pretty strange. I can suggest that you can try a few things:

1. Check bit-rate of the sound file (I assume it is ogg). Try running it with other programs win-amp for example. It probably is OK but I am writing it anyway.

2. Try OpenAL demos included with the SDL, I know one of them is using ogg as an example.

3. Try different files , is it only the problem for ogg files ?

4. How are you streaming from the ogg. Can you post some code ? Is the data from ogg getting streamed from the file or from the memory ?
About the SDL window resize and move problem. I think you might need to run a separate thread if you want to keep updating your sound while doing this. I'm obviously no expert though, so don't take my word for it.

This topic is closed to new replies.

Advertisement