3

I'm working on my project in SDL, with SDL_mixer. Everything sounds ok, but when I attempt to quit, my app crash. I think that it's related to Mix_FreeMusic function (I figured that out after using a lot of breakpoints) - I marked that line in code below:

In main.cpp, function RunEverything,

//sound-related code:
if(SDL_Init(SDL_INIT_EVERYTHING) == -1) { printf("error: %s\n", SDL_GetError()); return NULL; }

int audio_rate = 22050;
Uint16 audio_format = AUDIO_S16; /* 16-bit stereo */
int audio_channels = 2;
int audio_buffers = 4096;
if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) { printf("Unable to open audio!\n"); return NULL; }

Later in main.cpp:

int Screen_MainMenu(SDL_Surface *screen)
{
    SDL_Event event;
    CL_Menu Menu;
    /* ... */
    Mix_AllocateChannels(2);
    Mix_PlayMusic(Menu.mMusic, -1);

    while(quit==false) 
    {
        // some time-management, drawing stuff on screen etc., nothing audio-related

        while(SDL_PollEvent(&event))    
        {
            switch(event.type) 
            {
                case SDL_KEYDOWN:
                        switch(event.key.keysym.sym)
                        {
                        case SDLK_ESCAPE:
                            quit = true;
                            break;
                        case SDLK_UP:
                            Menu.kKlik = Mix_PlayChannel(-1, Menu.mKlik, 0);
                            break;
                        case SDLK_DOWN:
                            Menu.kKlik = Mix_PlayChannel(-1, Menu.mKlik, 0);
                            break;
                        }
                    break;
                case SDL_QUIT:
                    quit = true;
                    break;
            }
        }
    }
    Menu.FreeMem();
    return 0;

in class.h:

class CL_Menu
{
public:
    // some SDL_Surface & TTF_Font
    Mix_Music *mMusic;
    int kKlik;
    Mix_Chunk *mKlik;

    CL_Menu();
    void FreeMem();
};

in class.cpp:

CL_Menu::CL_Menu()
{
//loading .png & .ttf
    mMusic = Mix_LoadMUS("MP3/Sirio-Dance_Of_Stars.mp3");
    mKlik = Mix_LoadWAV("MP3/klik.wav");
};

void CL_Menu::FreeMem()
{
    //while(Mix_Playing(kKlik) != 0);
    Mix_HaltChannel(kKlik);
    Mix_HaltMusic();    
    Mix_FreeChunk(mKlik);   

// CloseFont & FreeSurface

    Mix_HaltMusic();
    SDL_Delay(100);
    Mix_FreeMusic(mMusic); // <-- that line probably causes crash
    mMusic = NULL;
};

I'm using win7 x64, Visual Studio 2010 and latest SDL libs. Also I noticed, that when I close my program within 10-15 seconds, it works fine. Only when it runs about 20-30 seconds, I get a crash.

edit: If it's important, my mp3 is rather big - about 9 MB (192 kb/s)

genpfault
  • 51,148
  • 11
  • 85
  • 139
Greg Witczak
  • 1,634
  • 4
  • 27
  • 56
  • Not an answer, but `Mix_FreeMusic()` is documented as halting the music if necessary. Does the problem persist if you remove the calls to `Mix_HaltMusic()` and `SDL_Delay()`? – Frédéric Hamidi Dec 26 '11 at 11:46
  • I knew that, but "for safety reasons" I decided to halt music by myself. Removing that lines or increasing SDL_Delay to 10 seconds doesn't fix the problem. – Greg Witczak Dec 26 '11 at 11:53
  • How does you SDL lib handle your mp3 ? are you linked libs (lame I guess) okay ? – dzen Jan 05 '12 at 22:38

3 Answers3

3

Finally I managed to figure it out, so I'm writing a solution that worked in my case. I had to convert my .mp3 file to .ogg. And that's all. Probably that mp3 file was somehow corrupted, or it was an error in the SDL library.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Greg Witczak
  • 1,634
  • 4
  • 27
  • 56
2

I actually had the same problem just a while ago.

If anyone is searching for a solution and the .ogg conversion does not work, here are some quick hints as to what you can check:

Correct Deinitialization Order

In my personal case, the SDL_mixer quit before deallocation of the music file, giving an error on Free_Music() not because the file was corrupted, but because SDL_mixer was closed and still being called.

You can use the return value of Mix_QueryMusic(0,0,0) to see if your Audio is still open and available for use, or if there's an error (int 0).

This can happen quite quickly if you somewhere use a wrapper, to which you point a smart pointer. Be sure ALL smart pointers are out of scope BEFORE Mix_Quit() or Mix_AudioClose()! This can usually be done if you look a bit deeper into ownership of your pointers. In my case, having only the AudioManager class use shared_ptr and the rest use weak_ptr did the trick. I simply told the AudioManager class to deinitialize BEFORE closing my audio or quitting Mix_Music.

Setting Flags correctly and using the AudioClose

Secondly, see if your Mix_Init flags include all files that should be opened, like Mix_INIT_MP3 and Mix_INIT_OGG.

Furthermore, you should also close your audio by Mix_AudioClose() at the end of your program.

Draken
  • 3,134
  • 13
  • 34
  • 54
trashy
  • 21
  • 1
0

I had a similar problem, only in C. Mix_Quit() was being called before Mix_FreeMusic(). Once I put everything in the right order, the problem went away.

I was also confused about Mix_Quit() and Mix_CloseAudio(). From my research I discovered you call Mix_Quit() once for each Mix_Init() you called, and you call Mix_CloseAudio() just once after you're done with Mix_Quit().

Neil Roy
  • 603
  • 5
  • 13