   SDL_Mixer problem
  could someone tell me if i going about this the wrong way...I am calling this music function in the game loop and it wrks for a little bit with static then crashes...#include "SDL_mixer.h"void music(){#ifndef INIT_AUDIO#define INIT_AUDIOSDL_Init(SDL_INIT_AUDIO);Mix_OpenAudio(44100,MIX_DEFAULT_FORMAT,2,1024);char* selection;Mix_Music * music;bool started=false;#endifif(avatarHealth<=25){selection="LowHealth.wav";started=false;}else{selection="500miles[1].wav";} if(started==false){music=Mix_LoadMUS(selection);if(!music)SDL_Quit();Mix_PlayMusic(music, 1);Mix_VolumeMusic(50);started=true;}//Mix_CloseAudio();}
  You don't want to be calling the function in your game loop; otherwise you're resetting the entire music system every frame. Just call it once before the loop starts.   ;  im only opening the audio once with the def'show can I change the music w/o putting it in the loop?   ;  how would I change the music if no with the above method? (in game loop?)   ;Quote:Original post by BlueBan007im only opening the audio once with the def'sIt looks like there may be some confusion here (either on our part or yours). By the 'defs' I assume you mean the preprocessor statements?It kind of looks like maybe you've taken the concept of 'header guards' and drawn the conclusion that the same technique can be used at run time to ensure that a section of code is only executed once. This isn't how the preprocessor works. The preprocessor processes your source files before they're even compiled. The result is a modified source file, which is then sent to the compiler. The compiler doesn't see the preprocessor statements at all, and by the time the program actually runs, they are long gone.Assuming that INIT_AUDIO hasn't been defined prior to the bit of code you posted, those preprocessor statements will have no effect, and the initialization code will execute every time.The closest run-time equivalent of what you're trying to do would probably be to make the initialization conditional, based on the state of a local static 'has been initialized' variable. However, the more common approach would be to perform the initialization outside of the main loop, as previously suggested.   ;  okay...well I solved it..but I know theres got to be an easier way..this is my jacked global bool way lol:void initMusic(char *selection){Mix_OpenAudio(44100,MIX_DEFAULT_FORMAT,2,1024);music=Mix_LoadMUS(selection);if(!music)SDL_Quit();Mix_PlayMusic(music, -1);Mix_VolumeMusic(50);}void testMusic(){if(avatarHealth<=25){selection="LowHealth.wav";if(passed==false)audioStart=false;passed=true;}else{if(passed==true)audioStart=false;passed=false;selection="500miles[1].wav";}if(audioStart==false){Mix_FreeMusic(music);Mix_CloseAudio();initMusic(selection);audioStart=true;}}I call initMusic(selection) before the loopthen testMusic() inside the loop...and a series of bool checks...tell me the obvious better solution please!   ;  So, what I'd recommend is this:Firstly, define an enum that covers the different kinds of music you want. Maybe:enum MusicTrack{    MUSIC_IDLE,    MUSIC_LOW_HEALTH,    // We put an extra value on the end so that we can track how many values    // are in the enum. It doesn't actually represent a music track itself;    // remember, enums give numbers to the names we're putting here, and they    // count upwards from 0, so MUSIC_MAX_TRACKS will get the number 2 - which    // is exactly how many /actual/ tracks we have.    MUSIC_MAX_TRACKS};Next, it's going to be more efficient to load all your music at the start of your game and then switch between tracks, instead of loading entire tracks whenever you want to change music. It'll use more memory this way, but it's unlikely to be a massive concern for you at this point.// A global table for storing all the loaded music tracks.Mix_Music* musicTracks[MUSIC_MAX_TRACKS];bool LoadMusicTracks(){musicTracks[MUSIC_IDLE]  = Mix_LoadMUS("500miles[1].wav");if(musicTracks[MUSIC_IDLE] == NULL) return false;musicTracks[MUSIC_LOW_HEALTH] = Mix_LoadMUS("LowHealth.wav");if(musicTracks[MUSIC_LOW_HEALTH] == NULL) return false;return true; // All tracks were loaded OK}Having the enum makes it easier to keep track of which music is currently playing. MUSIC_MAX_TRACKS can double up as a value to indicate that nothing is playing, and a PlayTrack function can take care of updating it.MusicTrack currentlyPlayingTrack = MUSIC_MAX_TRACKS;void PlayMusic(MusicTrack track){// If we're asking for a track that is already playing, do nothing.if(currentlyPlayingTrack == track) return;currentlyPlayingTrack = track;Mix_PlayMusic(musicTracks[track], -1);}Your initMusic function now doesn't need to actually play anything at all - it can just call SDL_Init(SDL_AUDIO) and Mix_OpenAudio, then LoadMusicTracks to load the music.Your music-switching logic is now simple:if(avatarHealth <= 25){PlayMusic(MUSIC_LOW_HEALTH);}else{PlayMusic(MUSIC_IDLE);}Easy peasy. Don't forget that you'll need to write some kind of musicShutdown function to free up all the music tracks and shut down SDL_Mixer/SDL Audio.FWIW, I've deliberately written all of this in a very C style, as that's what your existing code looks like. If you're using C++, then it'd be even better, eventually, to wrap it up as one or more classes, and avoid that global state.   