Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

SDLSoundAgent.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  */
00009 #include "SDLSoundAgent.h"
00010 
00011 #include "Log.h"
00012 #include "Path.h"
00013 #include "ExInfo.h"
00014 #include "SDLException.h"
00015 #include "MixException.h"
00016 #include "Random.h"
00017 #include "BaseMsg.h"
00018 #include "OptionAgent.h"
00019 
00020 BaseMsg *SDLSoundAgent::ms_finished = NULL;
00021 //-----------------------------------------------------------------
00022 /**
00023  * Init sound subsystem.
00024  * @throws SDLException when SDL_INIT_AUDIO cannot be initialized
00025  * @throws MixException when SDL_mixer cannot be initialized
00026  */
00027     void
00028 SDLSoundAgent::own_init()
00029 {
00030     m_music = NULL;
00031     m_soundVolume = MIX_MAX_VOLUME;
00032     if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
00033         throw SDLException(ExInfo("SDL_InitSubSystem"));
00034     }
00035 
00036     int frequency =
00037        OptionAgent::agent()->getAsInt("sound_frequency", MIX_DEFAULT_FREQUENCY);
00038     if(Mix_OpenAudio(frequency, MIX_DEFAULT_FORMAT, 2, 1024) < 0) {
00039         throw MixException(ExInfo("Mix_OpenAudio"));
00040     }
00041     Mix_AllocateChannels(16);
00042 
00043     SoundAgent::own_init();
00044 }
00045 //-----------------------------------------------------------------
00046     void
00047 SDLSoundAgent::own_shutdown()
00048 {
00049     stopMusic();
00050     Mix_CloseAudio();
00051     SDL_QuitSubSystem(SDL_INIT_AUDIO);
00052 }
00053 //-----------------------------------------------------------------
00054 /**
00055  * Play this sound.
00056  * @param sound chunk to play
00057  * @param volume percentage sound volume
00058  * @param loops numer of loops. 0=play once, 1=play twice, -1=play infinite
00059  *
00060  * @return channel number where the sound is played,
00061  * return -1 on error or when sound is NULL
00062  */
00063     int
00064 SDLSoundAgent::playSound(Mix_Chunk *sound, int volume, int loops)
00065 {
00066     int channel = -1;
00067     if (sound) {
00068         channel = Mix_PlayChannel(-1, sound, loops);
00069         if (-1 == channel) {
00070             //NOTE: maybe there are too few open channels
00071             LOG_WARNING(ExInfo("cannot play sound")
00072                     .addInfo("Mix", Mix_GetError()));
00073         }
00074         else {
00075             Mix_Volume(channel, m_soundVolume * volume / 100);
00076         }
00077     }
00078 
00079     return channel;
00080 }
00081 
00082 //-----------------------------------------------------------------
00083 /**
00084  * Set sound volume.
00085  * NOTE: all already running sound will get equals volume
00086  * @param volume percentage volume, e.g. 30%=30
00087  */
00088     void
00089 SDLSoundAgent::setSoundVolume(int volume)
00090 {
00091     m_soundVolume = MIX_MAX_VOLUME * volume / 100;
00092     if (m_soundVolume > MIX_MAX_VOLUME) {
00093         m_soundVolume = MIX_MAX_VOLUME;
00094     }
00095     else if (m_soundVolume < 0) {
00096         m_soundVolume = 0;
00097     }
00098     Mix_Volume(-1, m_soundVolume);
00099 }
00100 
00101 //---------------------------------------------------------------------------
00102 // Music part
00103 //---------------------------------------------------------------------------
00104 
00105 /**
00106  * Play music.
00107  * @param file path to music file (i.e. *.ogg)
00108  * @param finished send this message when music is finished.
00109  * If finished is NULL, play music forever.
00110  */
00111 void
00112 SDLSoundAgent::playMusic(const Path &file,
00113         BaseMsg *finished)
00114 {
00115     stopMusic();
00116 
00117     int loops = -1;
00118     if (finished) {
00119         ms_finished = finished;
00120         loops = 1;
00121     }
00122 
00123     m_music = Mix_LoadMUS(file.getNative().c_str());
00124     if (m_music && (0 == Mix_PlayMusic(m_music, loops))) {
00125         Mix_HookMusicFinished(musicFinished);
00126     }
00127     else {
00128         LOG_WARNING(ExInfo("cannot play music")
00129                 .addInfo("music", file.getNative())
00130                 .addInfo("Mix", Mix_GetError()));
00131     }
00132 }
00133 //-----------------------------------------------------------------
00134 /**
00135  * @param volume percentage volume, e.g. 30%=30
00136  */
00137     void
00138 SDLSoundAgent::setMusicVolume(int volume)
00139 {
00140     Mix_VolumeMusic(MIX_MAX_VOLUME * volume / 100);
00141 }
00142 //-----------------------------------------------------------------
00143     void
00144 SDLSoundAgent::stopMusic()
00145 {
00146     if(Mix_PlayingMusic()) {
00147         Mix_HookMusicFinished(NULL);
00148         Mix_HaltMusic();
00149     }
00150     if (m_music) {
00151         Mix_FreeMusic(m_music);
00152         m_music = NULL;
00153     }
00154     if (ms_finished) {
00155         delete ms_finished;
00156         ms_finished = NULL;
00157     }
00158 }
00159 //-----------------------------------------------------------------
00160 /**
00161  * Callback called when music is finished.
00162  * NOTE: no one exception can be passed to "C" SDL_mixer code
00163  */
00164     void
00165 SDLSoundAgent::musicFinished()
00166 {
00167     try {
00168         if (ms_finished) {
00169             ms_finished->sendClone();
00170         }
00171         else {
00172             LOG_WARNING(ExInfo("NULL == ms_finished"));
00173         }
00174     }
00175     catch (std::exception &e) {
00176         LOG_WARNING(ExInfo("musicFinished error")
00177                 .addInfo("what", e.what()));
00178     }
00179     catch (...) {
00180         LOG_ERROR(ExInfo("musicFinished error - unknown exception"));
00181     }
00182 }
00183 
00184 
00185 

Generated on Wed Jun 1 09:54:31 2005 for Fish Fillets - Next Generation by  doxygen 1.4.2