summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugenio Favalli <elvenprogrammer@gmail.com>2005-04-11 19:47:17 +0000
committerEugenio Favalli <elvenprogrammer@gmail.com>2005-04-11 19:47:17 +0000
commit160e544a794dfc35e37d3790d606b76c0acb8b0e (patch)
treef4b7e07482271bf638b053b6f1afaf2aeec1ee5d
parentceaae48958dd674e5aac67606de183bb6b0ac36e (diff)
downloadmana-client-160e544a794dfc35e37d3790d606b76c0acb8b0e.tar.gz
mana-client-160e544a794dfc35e37d3790d606b76c0acb8b0e.tar.bz2
mana-client-160e544a794dfc35e37d3790d606b76c0acb8b0e.tar.xz
mana-client-160e544a794dfc35e37d3790d606b76c0acb8b0e.zip
Improving sound engine (now it loads samples through resource manager)
and support music fading (still somthing to fix)
-rw-r--r--src/game.cpp15
-rw-r--r--src/gui/setup.cpp2
-rw-r--r--src/main.cpp11
-rw-r--r--src/sound.cpp240
-rw-r--r--src/sound.h127
5 files changed, 224 insertions, 171 deletions
diff --git a/src/game.cpp b/src/game.cpp
index 4ec83d5d..3ddd72a9 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -224,8 +224,8 @@ void do_input()
}
else if ((keysym.sym == SDLK_F7))
{
- SOUND_SID id = sound.loadItem("data/sfx/fist-swish.ogg");
- sound.startItem(id, 120);
+ SOUND_ID id = sound.loadSfx("data/sfx/fist-swish.ogg");
+ sound.playSfx(id);
}
// Emotions, Skill dialog
@@ -373,7 +373,7 @@ void do_input()
- }
+ }
}
else if (event.type == SDL_QUIT)
{
@@ -532,13 +532,8 @@ void do_input()
player_node->y,
player_node->direction);
player_node->walk_time = tick_time;
-
- if (config.getValue("sound", 0) == 1) { // Temp fix
- ResourceManager *resman = ResourceManager::getInstance();
- SoundEffect *sample = resman->getSoundEffect(
- "sfx/fist-swish.ogg");
- sample->play(0, 120);
- }
+
+ sound.playSfx("sfx/fist-swish.ogg");
}
}
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index 9f304b61..6d4dade4 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -230,7 +230,7 @@ void Setup::action(const std::string &eventId)
if (soundCheckBox->isMarked()) {
config.setValue("sound", 1);
try {
- sound.init(32, 20);
+ sound.init();
}
catch (const char *err) {
new OkDialog(this, "Sound Engine", err);
diff --git a/src/main.cpp b/src/main.cpp
index 8a32f043..b6a3b4fa 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -291,11 +291,10 @@ void init_engine()
// initialize sound-engine and start playing intro-theme /-kth5
try {
- if (config.getValue("sound", 0) == 1) {
- SDL_InitSubSystem(SDL_INIT_AUDIO);
- sound.init(32, 20);
+ if (config.getValue("sound", 0) == 1) {
+ sound.init();
}
- sound.setVolume(64);
+ //sound.setVolume(64);
}
catch (const char *err) {
state = ERROR;
@@ -351,7 +350,7 @@ int main(int argc, char *argv[])
switch (state) {
case LOGIN:
logger.log("State: LOGIN");
- sound.startBgm("data/music/Ivano(de)Jeanette.ogg");
+ sound.playMusic("data/music/Ivano(de)Jeanette.ogg");
/*bgm = resman->getMusic("music/Ivano(de)Jeanette.ogg");
bgm->play(-1);*/
login();
@@ -365,7 +364,7 @@ int main(int argc, char *argv[])
charSelect();
break;
case GAME:
- sound.stopBgm();
+ sound.fadeOutMusic(3000);
//bgm->stop();
logger.log("State: GAME");
try {
diff --git a/src/sound.cpp b/src/sound.cpp
index cdd9de49..98fef632 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -25,144 +25,214 @@
#include "log.h"
#include "main.h"
-void Sound::init(int voices, int mod_voices)
+void Sound::init()
{
// Don't initialize sound engine twice
- if (isOk == 0) return;
-
- bgm = NULL;
- int audio_rate = 44100;
- Uint16 audio_format = MIX_DEFAULT_FORMAT;
- int audio_channels = 2;
- int audio_buffers = 4096;
-
- if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers))
- {
-#ifndef __DEBUG
- throw("Unable to open audio device!");
-#else
- throw(Mix_GetError());
-#endif
- }
+ if (installed) return;
- Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
- char *format_str="Unknown";
- switch (audio_format) {
- case AUDIO_U8: format_str="U8"; break;
- case AUDIO_S8: format_str="S8"; break;
- case AUDIO_U16LSB: format_str="U16LSB"; break;
- case AUDIO_S16LSB: format_str="S16LSB"; break;
- case AUDIO_U16MSB: format_str="U16MSB"; break;
- case AUDIO_S16MSB: format_str="S16MSB"; break;
- }
+ logger.log("Sound::init() Initializing sound...");
- pan = 128;
+ if (SDL_InitSubSystem(SDL_INIT_AUDIO) == -1) {
+ logger.log("Sound::init() Failed to initialize audio subsystem");
+ return;
+ }
+
+ const size_t audioBuffer = 4096;
+
+ const int res = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT,
+ 2, audioBuffer);
+ if (res >= 0) {
+ Mix_AllocateChannels(16);
+ } else {
+ logger.log("Sound::init Could not initialize audio: %s",
+ Mix_GetError());
+ return;
+ }
+
+ info();
+
+ music = NULL;
items = -1;
- isOk = 0;
+
+ installed = true;
+}
- logger.log("Sound::init() Initializing Sound");
- char driver[40];
- logger.log("Sound::init() Driver name: %s", SDL_AudioDriverName(driver, 40));
- logger.log("Sound::init() Spec: %i %s %i", audio_rate, format_str,
- audio_channels);
+void Sound::info() {
+ SDL_version compiledVersion;
+ const SDL_version *linkedVersion;
+ char driver[40] = "Unknown";
+ char *format = "Unknown";
+ int rate = 0;
+ Uint16 audioFormat = 0;
+ int channels = 0;
+
+ MIX_VERSION(&compiledVersion);
+ linkedVersion = Mix_Linked_Version();
+
+ SDL_AudioDriverName(driver, 40);
+
+ Mix_QuerySpec(&rate, &audioFormat, &channels);
+ switch (audioFormat) {
+ case AUDIO_U8: format = "U8"; break;
+ case AUDIO_S8: format = "S8"; break;
+ case AUDIO_U16LSB: format = "U16LSB"; break;
+ case AUDIO_S16LSB: format = "S16LSB"; break;
+ case AUDIO_U16MSB: format = "U16MSB"; break;
+ case AUDIO_S16MSB: format = "S16MSB"; break;
+ }
+
+ logger.log("Sound::info() SDL_mixer: %i.%i.%i (compiled)",
+ compiledVersion.major,
+ compiledVersion.minor,
+ compiledVersion.patch);
+ logger.log("Sound::info() SDL_mixer: %i.%i.%i (linked)",
+ linkedVersion->major,
+ linkedVersion->minor,
+ linkedVersion->patch);
+ logger.log("Sound::info() Driver: %s", driver);
+ logger.log("Sound::init() Format: %s", format);
+ logger.log("Sound::init() Rate: %i", rate);
+ logger.log("Sound::init() Channels: %i", channels);
}
-void Sound::setVolume(int music)
+void Sound::setMusicVolume(int volume)
{
- if (isOk == -1) return;
+ if (!installed) return;
- if (!isMaxVol(music)) {
- vol_music = music;
- Mix_VolumeMusic(vol_music);
- }
+ musicVolume = volume;
+ Mix_VolumeMusic(volume);
}
-void Sound::adjustVolume(int amusic)
+void Sound::setSfxVolume(int volume)
{
- if (isOk == -1) return;
+ if (!installed) return;
- if (!isMaxVol(vol_music + amusic)) {
- vol_music += amusic;
- Mix_VolumeMusic(vol_music);
- }
+ sfxVolume = volume;
+ Mix_Volume(-1, volume);
}
-void Sound::startBgm(char *in, int loop)
+void Sound::playMusic(const char *path, int loop)
{
- if (isOk == -1) return;
+ if (!installed) return;
- if (bgm != NULL) {
- stopBgm();
+ if (music != NULL) {
+ stopMusic();
}
- logger.log("Sound::startBgm() playing \"%s\" %d times", in, loop);
+ logger.log("Sound::startMusic() Playing \"%s\" %i times", path, loop);
- bgm = Mix_LoadMUS(in);
- if (bgm) {
- Mix_PlayMusic(bgm, loop);
+ music = Mix_LoadMUS(path);
+ if (music) {
+ Mix_PlayMusic(music, loop);
}
else {
- logger.log("Sound::startBgm() warning: error loading file.");
+ logger.log("Sound::startMusic() Warning: error loading file.");
}
}
-void Sound::stopBgm()
+void Sound::stopMusic()
{
- if (isOk == -1) return;
+ if (!installed) return;
- logger.log("Sound::stopBgm()");
+ logger.log("Sound::stopMusic()");
- if (bgm != NULL) {
+ if (music != NULL) {
Mix_HaltMusic();
- Mix_FreeMusic(bgm);
- bgm = NULL;
+ Mix_FreeMusic(music);
+ music = NULL;
}
}
-SOUND_SID Sound::loadItem(char *fpath)
+void Sound::fadeInMusic(const char *path, int loop, int ms)
{
- logger.log("Sound::loadItem() precaching \"%s\"", fpath);
+ if (!installed) return;
+
+ if (music != NULL) {
+ stopMusic();
+ }
- Mix_Chunk *newItem;
- if ((newItem = Mix_LoadWAV(fpath))) {
- soundpool[++items] = newItem;
- logger.log("Sound::loadItem() success SOUND_SID = %d", items);
+ logger.log("Sound::fadeInMusic() Fading \"%s\" %i times (%i ms)", path,
+ loop, ms);
+
+ music = Mix_LoadMUS(path);
+ if (music) {
+ Mix_FadeInMusic(music, loop, ms);
+ }
+ else {
+ logger.log("Sound::fadeInMusic() Warning: error loading file.");
+ }
+}
+
+void Sound::fadeOutMusic(int ms)
+{
+ if (!installed) return;
+
+ logger.log("Sound::fadeOutMusic() Fading-out (%i ms)", ms);
+
+ if (music != NULL) {
+ Mix_FadeOutMusic(ms);
+ Mix_FreeMusic(music);
+ music = NULL;
+ }
+}
+
+SOUND_ID Sound::loadSfx(const char *path)
+{
+ /* If sound system is not installed it can't load
+ * samples because doesn't know how to convert them */
+ if (!installed) return 0;
+
+ logger.log("Sound::loadSfx() pre-caching \"%s\"", path);
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ SoundEffect *sample = resman->getSoundEffect(path);
+ if (sample) {
+ soundPool[++items] = sample;
+ logger.log("Sound::loadSfx() SOUND_ID = %d", items);
return items;
}
return 0;
}
-void Sound::startItem(SOUND_SID id, int volume)
+void Sound::playSfx(SOUND_ID id)
{
- if (soundpool[id]) {
- logger.log("Sound::startItem() playing SOUND_SID = %d", id);
- Mix_VolumeChunk(soundpool[id], volume);
- Mix_PlayChannel(-1, soundpool[id], 0);
+ if (!installed) return;
+
+ if (soundPool[id]) {
+ logger.log("Sound::playSfx() Playing SOUND_ID = %d", id);
+ soundPool[id]->play(0, sfxVolume);
+ }
+}
+
+void Sound::playSfx(const char *path)
+{
+ if (!installed) return;
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ SoundEffect *sample = resman->getSoundEffect(path);
+ if (sample) {
+ sample->play(0, 120);
+ logger.log("Sound::playSfx() Playing: %s", path);
}
}
void Sound::clearCache()
{
- for (SOUND_SID i = 0; i == items; i++) {
- Mix_FreeChunk(soundpool[i]);
- soundpool[i] = NULL;
+ for (SOUND_ID i = 0; i == items; i++) {
+ soundPool[i]->unload();
+ delete soundPool[i];
+ soundPool[i] = NULL;
}
- soundpool.clear();
- logger.log("Sound::clearCache() wiped all items off the cache");
+ soundPool.clear();
+ logger.log("Sound::clearCache() Wiped all items off the cache");
}
void Sound::close()
{
- isOk = -1;
+ installed = false;
clearCache();
Mix_CloseAudio();
- logger.log("Sound::close() shutting down Sound");
-}
-
-bool Sound::isMaxVol(int vol)
-{
- if (vol > 0 && vol < 128) return false;
- else return true;
+ logger.log("Sound::close() Shutting down sound...");
}
diff --git a/src/sound.h b/src/sound.h
index 44499618..c0f2f3ba 100644
--- a/src/sound.h
+++ b/src/sound.h
@@ -24,13 +24,14 @@
#ifndef _TMW_SOUND_H
#define _TMW_SOUND_H
+#include <guichan.hpp>
#include <SDL.h>
#include <SDL_mixer.h>
#include <map>
-#include <string>
-#include <fstream>
-typedef short SOUND_SID;
+#include "resources/resourcemanager.h"
+
+typedef short SOUND_ID;
/** Sound engine
*
@@ -39,115 +40,103 @@ typedef short SOUND_SID;
class Sound {
public:
/**
- * \brief Install the sound engine
- *
- * \param voices Overall reserved voices
- * \param mod_voices Voices dedicated for mod-playback
- *
- * Overall voices must not be less or equal to the specified amount of
- * mod_voices! if mod-voices is too low some mods will not sound
- * correctly since a couple of tracks are not going to be played along
- * w/ the others. so missing ins- truments can be a result. 32/20
- * sounds realistic here.
+ * Installs the sound engine.
*/
- void init(int voices, int mod_voices);
+ void init();
+
+ /**
+ * Logs various info about sound device.
+ */
+ void info();
/**
- * \brief Deinstall all sound functionality
- *
- * Normally you won't need to call this since this is done by SDL when
- * shutting itself down. but if you find a reason to delete the
- * sound-engine from memory (e.g. garbage-collection) feel free to use
- * it. :-P
+ * Removes all sound functionalities.
*/
void close();
/**
- * \brief Start background music
+ * Starts background music.
*
* \param in Full path to file
* \param loop The number of times the song is played (-1 = infinite)
*/
- void startBgm(char *in, int loop = -1);
+ void playMusic(const char *path, int loop = -1);
/**
- * \brief Stop all currently running background music tracks
+ * Stops currently running background music track.
+ */
+ void stopMusic();
+
+ /**
+ * Fades in background music.
*
- * You need to stop all playback when you want to switch from mod to
- * midi. playing a new track is usually simple as calling StartMIDI()
- * or StartMOD() again. passing NULL to the playing functions only
- * means to make playback stop.
+ * \param in Full path to file
+ * \param loop The number of times the song is played (-1 = infinite)
+ * \param ms Duration of fade-in effect (ms)
*/
- void stopBgm();
+ void fadeInMusic(const char *path, int loop = -1, int ms = 2000);
+
+ /**
+ * Fades out currently running background music track.
+ *
+ * \param ms Duration of fade-out effect (ms)
+ */
+ void fadeOutMusic(int ms);
/**
- * \brief Set the volume value-range: 0-128
+ * Sets music volume.
*
- * \param music Volume value
- *
- * All values may only be between 0-128 where 0 means muted.
+ * \param volume Volume value
*/
- void setVolume(int music);
+ void setMusicVolume(int volume);
/**
- * \brief Adjusts current volume
- * \param amusic Volume difference
+ * Sets sfx volume.
+ *
+ * \param volume Volume value
*/
- void adjustVolume(int amusic);
+ void setSfxVolume(int volume);
/**
- * \brief Preloads a sound-item into buffer
+ * Preloads a sound-item into buffer.
*
- * \param fpath Full path to file
- *
- * Please make sure that the object is not loaded more than once since
- * the function will not run any checks on its own!
- *
- * The return value should be kept as a reference to the object loaded.
- * if not it is practicaly lost.
+ * \param path Full path to file
*/
- SOUND_SID loadItem(char *fpath);
+ SOUND_ID loadSfx(const char *path);
/**
- * \brief Plays an item in soundpool
+ * Plays an item in soundpool.
*
* \param id Id returned to the item in the soundpool
- * \param volume Volume the sound should be played with (possible
- * range: 0-128)
*/
- void startItem(SOUND_SID id, int volume);
+ void playSfx(SOUND_ID id);
/**
- * \brief Wipe all items off the cache
+ * Plays an item.
+ *
+ * \param path Full path to file
+ */
+ void playSfx(const char *path);
+
+ /**
+ * Wipe all items off the cache
*/
void clearCache();
- Sound() { isOk = -1; }
+ Sound() { installed = false; }
- /** if allegro is shut down or object is deleted any BGM is
- stopped and SFX run out */
- ~Sound() { stopBgm(); close(); }
+ ~Sound() { stopMusic(); close(); }
private:
- /** initial value is -1 which means error or noninitialzed.
- you can only play sounds and bgm if this is 0.
- that should be the case after calling Init() successfully */
- int isOk;
+ bool installed;
- int pan;
- int vol_music;
+ int musicVolume, sfxVolume;
- Mix_Music *bgm;
+ Mix_Music *music;
/** list of preloaded sound data / items */
- std::map<int, Mix_Chunk*> soundpool;
- SOUND_SID items;
-
- /**
- * \brief checks if value equals min-/maximum volume and returns
- * <code>true</code> if that's the case.
- */
- bool isMaxVol(int vol);
+ std::map<int, SoundEffect*> soundPool;
+ SOUND_ID items;
};
#endif