summaryrefslogblamecommitdiff
path: root/src/sound.cpp
blob: 98fef6324a20d8c02fcc664f1349afe9a3406bbe (plain) (tree)
1
  

















                                                                             

        
   
 
                  
                
                 
 
                  
 
                                          
                          
    
                                                      
    



















                                                                                
               


                         
 



































                                                              

 
                                      
 
                           
    

                            

 
                                    
 
                           
    

                           

 
                                                 
 
                           
        

                        
     
    
                                                                          
 


                                   

          
                                                                       
     
 
 
                       
 
                           
 
                                     
        
                        
                        

                             
     

 
                                                           
 




                           
 





































                                                                           
                     
     

             

 
                                
 
















                                                                 
     

 

                        



                                           
     
    

                                                                    

 
                   
 
                      

                     
                                                        
 
/*
 *  The Mana World
 *  Copyright 2004 The Mana World Development Team
 *
 *  This file is part of The Mana World.
 *
 *  The Mana World is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  The Mana World is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with The Mana World; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  $Id$
 */

#include "sound.h"
#include "log.h"
#include "main.h"

void Sound::init()
{
    // Don't initialize sound engine twice
    if (installed) return;
    
    logger.log("Sound::init() Initializing sound...");
    
    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;
    
	installed = true;
}

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::setMusicVolume(int volume)
{
    if (!installed) return;
    
    musicVolume = volume;
    Mix_VolumeMusic(volume);
}

void Sound::setSfxVolume(int volume)
{
    if (!installed) return;
    
    sfxVolume = volume;
    Mix_Volume(-1, volume);
}

void Sound::playMusic(const char *path, int loop)
{
    if (!installed) return;
        
    if (music != NULL) {
        stopMusic();
    }
    
    logger.log("Sound::startMusic() Playing \"%s\" %i times", path, loop);

    music = Mix_LoadMUS(path);
    if (music) {
        Mix_PlayMusic(music, loop);
    }
    else {
        logger.log("Sound::startMusic() Warning: error loading file.");
    }
}

void Sound::stopMusic()
{
    if (!installed) return;

    logger.log("Sound::stopMusic()");
        
    if (music != NULL) {
        Mix_HaltMusic();
        Mix_FreeMusic(music);
        music = NULL;
    }
}

void Sound::fadeInMusic(const char *path, int loop, int ms)
{
    if (!installed) return;

    if (music != NULL) {
        stopMusic();
    }

    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::playSfx(SOUND_ID id)
{
    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_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");
}

void Sound::close()
{
    installed = false;
    clearCache();
    Mix_CloseAudio();
    logger.log("Sound::close() Shutting down sound...");
}