3

SDL_mixerを使用して、SDLでプロジェクトに取り組んでいます。すべて問題ないように思えますが、終了しようとすると、アプリがクラッシュします。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)

4

3 に答える 3

3

最後に私はそれを理解することができたので、私の場合にうまくいった解決策を書いています。.mp3ファイルを .oggに変換する必要がありました。それだけです。おそらく、その mp3 ファイルが何らかの形で破損しているか、SDL ライブラリのエラーでした。

于 2012-01-05T22:32:20.760 に答える
2

私は実際に少し前に同じ問題を抱えていました。

誰かが解決策を探していて、.ogg 変換が機能しない場合は、確認できる内容について簡単なヒントを次に示します。

正しい初期化解除順序

私の個人的なケースでは、音楽ファイルの割り当てを解除する前に SDL_mixer が終了Free_Music()し、ファイルが破損したためではなく、SDL_mixer が閉じられ、まだ呼び出されているためにエラーが発生しました。

の戻り値を使用してMix_QueryMusic(0,0,0)、オーディオがまだ開いていて使用できるかどうか、またはエラー (int 0) があるかどうかを確認できます。

これは、どこかでスマート ポインターを指すラッパーを使用すると、非常に迅速に発生する可能性があります。BEFOREまたは!の前に、すべてのスマート ポインターが範囲外であることを確認してください。Mix_Quit()Mix_AudioClose()これは通常、ポインターの所有権をもう少し詳しく調べると実行できます。私の場合、AudioManager クラスのみで shared_ptr を使用し、残りのクラスで weak_ptr を使用することでうまくいきました。オーディオを閉じるか、Mix_Music を終了する前に、AudioManager クラスに初期化を解除するように指示しただけです。

フラグを正しく設定し、AudioClose を使用する

次に、 や など、Mix_Init開く必要があるすべてのファイルがフラグに含まれているかどうかを確認します。Mix_INIT_MP3Mix_INIT_OGG

Mix_AudioClose()さらに、プログラムの最後でオーディオを閉じる必要もあります。

于 2017-01-08T12:15:47.867 に答える