我正在SDL中使用SDL_mixer处理我的项目。一切听起来都不错,但是当我尝试退出时,我的应用程序崩溃了。我认为它与Mix_FreeMusic函数有关(我在使用了很多断点后想到了这一点) - 我在下面的代码中标记了这一行:
在 main.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; }
稍后在 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;
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)
答案 0 :(得分:3)
最后我设法弄清楚了,所以我正在编写一个适用于我的解决方案。 我必须将 .mp3 文件转换为.ogg 。就这样。可能是mp3文件以某种方式损坏了,或者SDL库中的错误。
答案 1 :(得分: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之前取消初始化。
其次,看看您的Mix_Init
标记是否包含应该打开的所有文件,例如Mix_INIT_MP3
和Mix_INIT_OGG
。
此外,您还应该在节目结束时按Mix_AudioClose()
关闭音频。
答案 2 :(得分:0)
我遇到了类似的问题,仅在C. Mix_Quit()
之前被调用Mix_FreeMusic()
。一旦我按顺序排列一切,问题就会消失。
我对Mix_Quit()
和Mix_CloseAudio()
感到困惑。根据我的调查,我发现您为所调用的Mix_Quit()
致电Mix_Init()
一次,并在完成Mix_CloseAudio()
后仅拨打Mix_Quit()
。