【问题标题】:SDL_Mixer: crash Mix_FreeMusic();SDL_Mixer: 崩溃 Mix_FreeMusic();
【发布时间】:2011-12-26 11:31:04
【问题描述】:

我正在使用 SDL_mixer 处理我的 SDL 项目。一切听起来都不错,但是当我尝试退出时,我的应用程序崩溃了。我认为它与 Mix_FreeMusic 函数有关(我在使用大量断点后发现了这一点) - 我在下面的代码中标记了该行:

ma​​in.cpp 中,函数 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; }

稍后在 ma​​in.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;

class.h中:

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

    CL_Menu();
    void FreeMem();
};

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;
};

我正在使用 win7 x64、Visual Studio 2010 和最新的 SDL 库。 我还注意到,当我在 10-15 秒内关闭程序时,它工作正常。只有当它运行大约 20-30 秒时,我才会崩溃。

编辑:如果重要的话,我的 mp3 相当大 - 大约 9 MB (192 kb/s)

【问题讨论】:

  • 不是答案,但Mix_FreeMusic() 记录为在必要时暂停音乐。如果删除对Mix_HaltMusic()SDL_Delay() 的调用,问题是否仍然存在?
  • 我知道这一点,但“出于安全原因”我决定自己停止音乐。删除这些行或将 SDL_Delay 增加到 10 秒并不能解决问题。
  • 您的 SDL lib 如何处理您的 mp3 ?你链接的库(我猜是蹩脚的)好吗?

标签: c++ sdl sdl-mixer


【解决方案1】:

最后我设法弄清楚了,所以我正在编写一个适用于我的情况的解决方案。 我必须将我的 .mp3 文件转换为 .ogg。就这样。可能该 mp3 文件已损坏,或者是 SDL 库中的错误。

【讨论】:

  • 我在播放 mp3 文件时遇到了同样的问题,没有找到解决方案。
【解决方案2】:

实际上我不久前也遇到了同样的问题。

如果有人在寻找解决方案并且 .ogg 转换不起作用,这里有一些关于您可以检查的快速提示:

正确的取消初始化顺序

在我个人的情况下,SDL_mixer 在释放音乐文件之前退出,在 Free_Music() 上出现错误不是因为文件损坏,而是因为 SDL_mixer 已关闭并且仍在调用。

您可以使用Mix_QueryMusic(0,0,0) 的返回值来查看您的音频是否仍然打开并且可以使用,或者是否存在错误(int 0)。

如果您在某个地方使用包装器,并指向一个智能指针,这可能会很快发生。 确保所有智能指针在Mix_Quit()Mix_AudioClose() 之前都超出范围! 如果您更深入地了解指针的所有权,通常可以做到这一点。在我的情况下,只有 AudioManager 类使用 shared_ptr 而其余的使用 weak_ptr 就可以了。我只是告诉 AudioManager 类在关闭我的音频或退出 Mix_Music 之前取消初始化。

正确设置标志并使用 AudioClose

其次,查看您的Mix_Init 标志是否包含所有应该打开的文件,例如Mix_INIT_MP3Mix_INIT_OGG

此外,您还应该在程序结束时通过Mix_AudioClose() 关闭音频。

【讨论】:

    【解决方案3】:

    我遇到了类似的问题,只是在 C 中。Mix_Quit()Mix_FreeMusic() 之前被调用。一旦我把所有东西都按正确的顺序排列,问题就消失了。

    我也对Mix_Quit()Mix_CloseAudio() 感到困惑。根据我的研究,我发现你为每个调用的 Mix_Init() 调用一次 Mix_Quit(),并且在你调用完 Mix_Quit() 后只调用一次 Mix_CloseAudio()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-02
      • 1970-01-01
      • 2011-11-22
      • 2021-05-14
      • 1970-01-01
      • 2016-11-09
      • 2018-12-11
      • 2013-05-30
      相关资源
      最近更新 更多