Jump to content
Eternal Lands Official Forums
0ctane

Music, kill_local_sounds, used_sources problem

Recommended Posts

Background: I have been trying to get music running on OSX. When changing maps I would frequently get "stream_music error: Invalid Operation" showing up in my error log, a few brief music stutters, and then death of music. Cycling sound and music off/on would bring back music until I tried switching maps again. The alBufferData(buffer, AL_FORMAT_STEREO16, data, size, ogg_info->rate); call in stream_music was creating the error, but the problem was deeper.

 

After a lot of code digging, I isolated the main problem to kill_local_sounds in sound.c. The music stopping code at the bottom was never (well, sometimes) being reached. I found that at line 644 used_sources was equal to zero (which thereby prevents music from being cleared). Since music is not peacefully stopped, when stream_music tries to start the new playlist, alBufferData borks and music is killed.

 

So, if I put the following at the beginning of kill_local_sounds before the !used_sources check...

#ifndef	NO_MUSIC
if(have_music)
{
	playing_music = 0;
	alSourceStop(music_source);
	alGetSourcei(music_source, AL_BUFFERS_PROCESSED, &processed);
	alGetSourcei(music_source, AL_BUFFERS_QUEUED, &queued);
	while(queued-- > 0) {
		ALuint buffer;
		alSourceUnqueueBuffers(music_source, 1, &buffer);
	}
}
#endif	//NO_MUSIC

...music rotates just fine when switching maps. Yea!

 

I am very unfamiliar with OpenAL, and I have only been able to hack out this temporary solution by doing a lot of LOG_ERROR() printouts of variables. So, the questions are:

  1. why is used_sources = 0?
  2. how is used_sources related to music?
  3. can this dirty OSX patch be cleaned up?

Any thoughts?

Share this post


Link to post
Share on other sites
1 why is used_sources = 0?
each source in turn is stopped. most of them are .wav, the music is the one special case
2 how is used_sources related to music?
the music uses one of the sources. but tearing down the music takes more than any other source
3 can this dirty OSX patch be cleaned up?
sure it's OSX specific?

if I'm guessing right as to the issue, it should work fine for other OSes as well, in which case it can go in un-ifdef-ed

 

EDIT: CrusadingKNIGHT - Fixed an issue with the quotes which ran together. This post deserves to be readable.

Edited by crusadingknight

Share this post


Link to post
Share on other sites
1 why is used_sources = 0?
each source in turn is stopped. most of them are .wav, the music is the one special case

Hmmm.... then for some reason either used_sources was not properly incremented when starting music, or it was not properly decremented (ie decremented too far). Why is music a "special case"?

3 can this dirty OSX patch be cleaned up?
sure it's OSX specific?

if I'm guessing right as to the issue, it should work fine for other OSes as well, in which case it can go in un-ifdef-ed

I am not sure if it is OSX specific. Does used_sources really need to be checked before trying to stop music? If not, then I do not foresee anyone else having a problem. I could test this out on other OSes, but I am quiet tired. It took me till ~3am last night to finally find that used_sources was the problem. :) Anyone feel like having a go at it?

Share this post


Link to post
Share on other sites
Hmmm.... then for some reason either used_sources was not properly incremented when starting music, or it was not properly decremented (ie decremented too far). Why is music a "special case"?
music is a special case because it's played differently. the .wavs are loaded into memory and then played. the music is streamed from disk. since it has to go through the vorbis libs, there's additional structures, etc.

and maybe it's not that used_sources is decremented too far, but too soon... ie the music stopping should be done before all sources are stopped (since music uses one of those sources)

Share this post


Link to post
Share on other sites
Why is music a "special case"?
music is a special case because it's played differently. the .wavs are loaded into memory and then played. the music is streamed from disk. since it has to go through the vorbis libs, there's additional structures, etc.

Yeah, I had to do some reading on Ogg/Vorbis and learned a bit about the multiple buffers and streaming.

and maybe it's not that used_sources is decremented too far, but too soon... ie the music stopping should be done before all sources are stopped (since music uses one of those sources)

I will try to look into source usage at the time of map change. The stopping of music in kill_local_sounds does not decrement used_sources as far as I can tell....hmmm. Of course, I see no place where starting music actually increments used_sources, so it might be best to have the sound stop code above the !used_sources check anyhow (or maybe have play_ogg_file increment used_sources?).

 

On a related note, why is kill_local_sounds (sound.c) called twice by change_map (map_io.c)?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×