Problem with mp3 playback using SDL_mixer and S MPeg.dll

If I am repeatedly turning mp3 playback on, off and on again, music erratically
sounds like its played 100 times too fast. Turning music off and on again cures
the problem. It’s like ‘on - off - on - off - on - off - on - error - off - on -
ok’.

I have tried to debug smpeg.dll and sdl_mixer for days, but I just cannot figure
what’s going on here.

Any idea/bug fix/pointer to where I have to look into?

karx11erx

A follow up:

I have found out that the audio data arriving when the music sounds sped up is
different from the one when it’s playing normally. Also, the pathological data
looks different every time the bug strikes. Looks to me like the mp3 decoding
stuff has a problem (unitialized variable).

SIntHero,

you’re reply is uncalled for. I was asking for advice where
to look for the problem.

SlntHero,

I’d rather sue you for not saying Merry Christmas … :wink:

Merry Christmas and a happy new year to you, too. :slight_smile:

Btw, I think I have found the reason for the bug. SDL_mixer first starts the
music, then sets the playback position to the start. For mp3, this means that a
few threads are created, deleted and recreated very quickly. SDL or Windows do
not seem to like that. After I had temporarily disabled the positioning call,
the problem was gone.

You can find this in [SDL_mixer]music.c::music_internal_play(), there’s a
call to music_internal_position(0.0) for the case that the parameter position
== 0.0.

[smpeg]MPEGaudio.cpp::Stop() contained a bug. After the statement ‘playing =
false;’ the following should be inserted:

#ifdef THREADED_AUDIO
StopDecoding();
#endif

Another flaw was located in [smpeg]MPEGaudio.cpp, where
MPEGaudio::StopDecoding() calls SDL_WaitThread(). SDL_KillThread() is safer.

[smpeg]MPEGaudio::StartDecoding() could use some error handling in case ring or
decode_thread cannot be allocated (call StopDecoding() then).

Looks like SDL_mixer + SMPeg run pretty well with these fixes. :slight_smile:

If you want the source code or a DLL post here.

karx

Fistman,

I don’t care about theories if the practise proofs otherwise.

It would suffice if the killing one of the participatigng threads would just
take a short while while the (feeding) thread is already gone.

Fact is that removing that positioning call (in SDL_mixer) removed the problem
of faulty mp3 playback.

Btw, another problem were Windows project settings. The library should be set to
’multithreaded DLL’, not just ‘multithreaded’. Inconsistencies in this setting
through a project (i.e. smpeg settings this way, main program settings that way)
are likely to result in smpeg not functioning properly.

Same goes btw. for the required vorbis files. I had to get the ogg/vorbis source
code (ogg, vorbis, vorbisfile), fix the project settings and recompile the stuff
to get them going, too.

On a side note, SDL_mixer crashes on WinXP if turning off ogg music playback
while having other sound channels open. Looks like closing the music somehow
invalidates all channel buffers. I couldn’t find out how (gawk, all these
threads!), but completely turning off all sounds cured the problem in my case.

Actually, the entire SDL and SDL_mixer sound handling is crap. You have one
global setting for frequency etc. - no chance to mix sounds and music if they
are sampled with different frequencies unless you resample one of them (which I
had to implement in my case :-/). Why the heck global variables instead of
encapsuled sound objects operating separately from each other?

Frack, if you want to have something done right, you have to do it yourself. :frowning:

Ryan,

you can find the complete modified source code of mpeg on
http://www.descent2.de/d2x.html (link near the bottom of the page).

David Olofson <david olofson.net> writes:

Well, whether or not this guy is a jerk, I have to agree on this
point: Killing a thread is really a last resort thing, if all else
fails.

David,

call SDL_WaitThread() if you don’t care to wait for eternity for the smpeg
decoder thread to terminate.