00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <SDL.h>
00023
00024 #include "log.h"
00025 #include "sound.h"
00026
00027 #include "resources/resourcemanager.h"
00028 #include "resources/soundeffect.h"
00029
00030 Sound::Sound():
00031 mInstalled(false),
00032 mSfxVolume(100),
00033 mMusicVolume(60),
00034 mMusic(NULL)
00035 {
00036 }
00037
00038 Sound::~Sound()
00039 {
00040 }
00041
00042 void Sound::init()
00043 {
00044
00045 if (mInstalled)
00046 return;
00047
00048 logger->log("Sound::init() Initializing sound...");
00049
00050 if (SDL_InitSubSystem(SDL_INIT_AUDIO) == -1)
00051 {
00052 logger->log("Sound::init() Failed to initialize audio subsystem");
00053 return;
00054 }
00055
00056 const size_t audioBuffer = 4096;
00057
00058 const int res = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT,
00059 MIX_DEFAULT_CHANNELS, audioBuffer);
00060 if (res < 0)
00061 {
00062 logger->log("Sound::init Could not initialize audio: %s",
00063 Mix_GetError());
00064 return;
00065 }
00066
00067 Mix_AllocateChannels(16);
00068 Mix_VolumeMusic(mMusicVolume);
00069 Mix_Volume(-1, mSfxVolume);
00070
00071 info();
00072
00073 mInstalled = true;
00074
00075 if (!mCurrentMusicFile.empty())
00076 playMusic(mCurrentMusicFile);
00077 }
00078
00079 void Sound::info()
00080 {
00081 SDL_version compiledVersion;
00082 const SDL_version *linkedVersion;
00083 char driver[40] = "Unknown";
00084 const char *format = "Unknown";
00085 int rate = 0;
00086 Uint16 audioFormat = 0;
00087 int channels = 0;
00088
00089 MIX_VERSION(&compiledVersion);
00090 linkedVersion = Mix_Linked_Version();
00091
00092 SDL_AudioDriverName(driver, 40);
00093
00094 Mix_QuerySpec(&rate, &audioFormat, &channels);
00095 switch (audioFormat) {
00096 case AUDIO_U8: format = "U8"; break;
00097 case AUDIO_S8: format = "S8"; break;
00098 case AUDIO_U16LSB: format = "U16LSB"; break;
00099 case AUDIO_S16LSB: format = "S16LSB"; break;
00100 case AUDIO_U16MSB: format = "U16MSB"; break;
00101 case AUDIO_S16MSB: format = "S16MSB"; break;
00102 }
00103
00104 logger->log("Sound::info() SDL_mixer: %i.%i.%i (compiled)",
00105 compiledVersion.major,
00106 compiledVersion.minor,
00107 compiledVersion.patch);
00108 logger->log("Sound::info() SDL_mixer: %i.%i.%i (linked)",
00109 linkedVersion->major,
00110 linkedVersion->minor,
00111 linkedVersion->patch);
00112 logger->log("Sound::info() Driver: %s", driver);
00113 logger->log("Sound::info() Format: %s", format);
00114 logger->log("Sound::info() Rate: %i", rate);
00115 logger->log("Sound::info() Channels: %i", channels);
00116 }
00117
00118 int Sound::getMaxVolume() const
00119 {
00120 return MIX_MAX_VOLUME;
00121 }
00122
00123 void Sound::setMusicVolume(int volume)
00124 {
00125 mMusicVolume = volume;
00126
00127 if (mInstalled)
00128 Mix_VolumeMusic(mMusicVolume);
00129 }
00130
00131 void Sound::setSfxVolume(int volume)
00132 {
00133 mSfxVolume = volume;
00134
00135 if (mInstalled)
00136 Mix_Volume(-1, mSfxVolume);
00137 }
00138
00139 static Mix_Music *loadMusic(const std::string &filename)
00140 {
00141 ResourceManager *resman = ResourceManager::getInstance();
00142 std::string path = resman->getPath("music/" + filename);
00143
00144 if (path.find(".zip/") != std::string::npos ||
00145 path.find(".zip\\") != std::string::npos)
00146 {
00147
00148
00149 logger->log("Loading music \"%s\" from temporary file tempMusic.ogg",
00150 path.c_str());
00151 bool success = resman->copyFile("music/" + filename, "tempMusic.ogg");
00152 if (success)
00153 {
00154 path = resman->getPath("tempMusic.ogg");
00155 } else {
00156 return NULL;
00157 }
00158 } else {
00159 logger->log("Loading music \"%s\"", path.c_str());
00160 }
00161
00162 Mix_Music *music = Mix_LoadMUS(path.c_str());
00163
00164 if (!music)
00165 {
00166 logger->log("Mix_LoadMUS() Error loading '%s': %s", path.c_str(),
00167 Mix_GetError());
00168 }
00169
00170 return music;
00171 }
00172
00173 void Sound::playMusic(const std::string &filename)
00174 {
00175 mCurrentMusicFile = filename;
00176
00177 if (!mInstalled)
00178 return;
00179
00180 haltMusic();
00181
00182 if ((mMusic = loadMusic(filename)))
00183 Mix_PlayMusic(mMusic, -1);
00184 }
00185
00186 void Sound::stopMusic()
00187 {
00188 if (!mInstalled)
00189 return;
00190
00191 logger->log("Sound::stopMusic()");
00192
00193 if (mMusic) {
00194 Mix_HaltMusic();
00195 Mix_FreeMusic(mMusic);
00196 mMusic = NULL;
00197 }
00198 }
00199
00200 void Sound::fadeInMusic(const std::string &path, int ms)
00201 {
00202 mCurrentMusicFile = path;
00203
00204 if (!mInstalled)
00205 return;
00206
00207 haltMusic();
00208
00209 if ((mMusic = loadMusic(path.c_str())))
00210 Mix_FadeInMusic(mMusic, -1, ms);
00211 }
00212
00213 void Sound::fadeOutMusic(int ms)
00214 {
00215 mCurrentMusicFile.clear();
00216
00217 if (!mInstalled)
00218 return;
00219
00220 logger->log("Sound::fadeOutMusic() Fading-out (%i ms)", ms);
00221
00222 if (mMusic) {
00223 Mix_FadeOutMusic(ms);
00224 Mix_FreeMusic(mMusic);
00225 mMusic = NULL;
00226 }
00227 }
00228
00229 void Sound::playSfx(const std::string &path)
00230 {
00231 if (!mInstalled || path.empty())
00232 return;
00233
00234 ResourceManager *resman = ResourceManager::getInstance();
00235 SoundEffect *sample = resman->getSoundEffect(path);
00236 if (sample) {
00237 logger->log("Sound::playSfx() Playing: %s", path.c_str());
00238 sample->play(0, 120);
00239 }
00240 }
00241
00242 void Sound::close()
00243 {
00244 if (!mInstalled)
00245 return;
00246
00247 haltMusic();
00248 logger->log("Sound::close() Shutting down sound...");
00249 Mix_CloseAudio();
00250
00251 mInstalled = false;
00252 }
00253
00254 void Sound::haltMusic()
00255 {
00256 if (!mMusic)
00257 return;
00258
00259 Mix_HaltMusic();
00260 Mix_FreeMusic(mMusic);
00261 mMusic = NULL;
00262 }