music->interface->GetAudio null dereference exception
Hi!
First of all, thanks for this awesome project! When I try to play several multi-track songs after each other (like in a playlist), I'm getting a dereference exception in this line.
Do you know what causes this issue? I'm using this to load all the music as streams:
void multitrackplayer::loadFiles(std::vector<std::string> paths)
{
multitrackplayer::stop();
for (auto path : paths)
{
auto musicMix = Mix_LoadMUS(path.c_str());
if (musicMix == NULL) {
} else {
_musicTracks.push_back(musicMix);
_duration = std::max(_duration, Mix_MusicDuration(musicMix));
}
}
_started = false;
}
void multitrackplayer::play()
{
if (_musicTracks.size() == 0) {
return;
}
for (auto music : _musicTracks)
{
if (_started) {
Mix_ResumeMusicStream(music);
} else {
int result = Mix_PlayMusicStream(music, 0);
}
Mix_SetFreeOnStop(music, 0); // don't free the music automatically
}
_started = true;
return void();
}
void multitrackplayer::stop()
{
if (_musicTracks.size() == 0) {
return void();
}
for (auto music : _musicTracks)
{
Mix_FreeMusic(music);
music = NULL;
}
_musicTracks.clear();
return void();
}
So I first free the music, when there is something currently playing, then load the new files and play them.
Hi, this looks like an interesting use case! I see one problem here, in multitrackplayer::stop(). It is illegal to call Mix_FreeMusic(music) if music is currently playing. The null dereference is occurring when the internal mixer logic tries to keep playing a music stream that has been freed.
To fix this, you can add Mix_HaltMusicStream(music) prior to Mix_FreeMusic(music).
Thanks for your answer, I will try this soon! However, if it actually fixes the issue, than the docs should be updated, as this is the current description of the Mix_FreeMusic function:
Free the loaded music. If music is playing it will be halted. If music is fading out, then this function will wait (blocking) until the fade out is complete.
That's a good point; I wasn't aware of that part of the specification and have never personally relied on this behavior. It's good for the library to try its best to prevent problems, though, so it'll be good for us to try to meet the specification.
@Wohlstand, maybe the issue is that Mix_FreeMusic doesn't call _Mix_MultiMusic_Remove prior to calling music_internal_halt here (https://github.com/WohlSoft/SDL-Mixer-X/blob/master/src/music.c#L2069)?
I'll try to check this.
Maybe call Mix_HaltMusicStream in the beginning of the Mix_FreeMusic? Code currently looks like, that the music halted callback isn't called as well, when calling FreeMusic?
Maybe call Mix_HaltMusicStream in the beginning of the Mix_FreeMusic? Code currently looks like, that the music halted callback isn't called as well, when calling FreeMusic?
There are already its parts called like music_internal_halt(). Anyway, I going to apply the fix now. Sorry for the delay, I was very busy.
Done, I also added calling of individual music finish hooks in a case if they are presented. Please test out the thing and tell does this fixes your issue or not?
@mbpictures, ping?
Closed because of no reply for a long time when problem had been fixed a while ago.