// Description: // Audio subsysytem. // // Copyright (C) 2003 Frank Becker // // This program 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 (at your option) any later // version. // // This program 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 // #include #include #include #include #include #include #include #include #include #include "SDL.h" #include "SDL_mixer.h" Audio::Audio(): _sampleManager(0), _soundTrack(0), _playDefaultSoundtrack( true), _playMusic( true), _isPlaying( false) { XTRACE(); bool dummy; //if config variables don't exist (upgrade, etc) update if( ! ConfigS::instance()->getBoolean( "playMusic", dummy)) { Value *v = new Value( _playMusic); ConfigS::instance()->updateKeyword( "playMusic", v); } if( ! ConfigS::instance()->getBoolean( "playDefaultSoundtrack", dummy)) { Value *v = new Value( _playDefaultSoundtrack); ConfigS::instance()->updateKeyword( "playDefaultSoundtrack", v); } } Audio::~Audio() { XTRACE(); LOG_INFO << "Audio shutdown..." << endl; turnMusicOff(); Mix_CloseAudio(); delete _sampleManager; SDL_QuitSubSystem(SDL_INIT_AUDIO); } void Audio::loadMusic( const string &mod) { XTRACE(); if( mod == "") return; LOG_INFO << "Loading soundtrack...[" << mod << "]" << endl; #if 0 //SDL_mixer doesn't have RWops support for MUS yet :( if( !ResourceManagerS::instance()->selectResource( mod)) { LOG_ERROR << "Music file [" << mod << "] not found." << endl; return; } ziStream &infile = ResourceManagerS::instance()->getInputStream(); SDL_RWops *src = RWops_from_ziStream( infile); _soundTrack = Mix_LoadMUS_RW(src); SDL_RWclose( src); #else _soundTrack = Mix_LoadMUS( mod.c_str()); #endif if( !_soundTrack) { LOG_ERROR << "Failed to load soundtrack: [" << mod << "]" << endl; LOG_ERROR << SDL_GetError() << endl; } else { //loop soundtrack Mix_PlayMusic( _soundTrack, -1); _isPlaying = true; } } bool Audio::init( void) { XTRACE(); LOG_INFO << "Initializing Audio..." << endl; bool audio; if( !ConfigS::instance()->getBoolean( "audio", audio)) { audio = false; } if( audio) { if( SDL_InitSubSystem( SDL_INIT_AUDIO) < 0 ) { LOG_ERROR << "Init Audio: failed # " << SDL_GetError() << endl; return false; } if( Mix_OpenAudio(22050, AUDIO_S16, 1, 1024) < 0 ) { LOG_ERROR << "Init Audio (Mixer): failed # " << SDL_GetError() << endl; return false; } _sampleManager = new SampleManager(); ConfigS::instance()->getBoolean( "playMusic", _playMusic); ConfigS::instance()->getBoolean( "playDefaultSoundtrack", _playDefaultSoundtrack); startMusic(); LOG_INFO << "Audio ON." << endl; } else { LOG_INFO << "Audio OFF." << endl; } return true; } void Audio::playSample( const string &sampleName) { if( !_sampleManager) return; Mix_Chunk *sample = _sampleManager->getSample( sampleName); if( sample) { //any channel, no loop Mix_PlayChannel(-1, sample, 0); } } void Audio::turnMusicOff( void) { if( _isPlaying) { Mix_HaltMusic(); if( _soundTrack) { Mix_FreeMusic( _soundTrack); _soundTrack = 0; } _isPlaying = false; } } void Audio::startMusic( void) { if( _playMusic) { string soundtrack = ""; if( _playDefaultSoundtrack) { //look in developer file tree first soundtrack = string("../data/music/TODO.ogg"); struct stat statInfo; if( stat( soundtrack.c_str(), &statInfo) == -1) { //try global soundtrack = DATA_DIR+string("TODO.ogg"); } } else { ConfigS::instance()->getString( "soundtrack", soundtrack); } turnMusicOff(); loadMusic( soundtrack); } else { turnMusicOff(); } } void Audio::updateSettings( void) { bool oldPlayMusic = _playMusic; bool oldPlayDefaultSoundtrack = _playDefaultSoundtrack; ConfigS::instance()->getBoolean( "playMusic", _playMusic); ConfigS::instance()->getBoolean( "playDefaultSoundtrack", _playDefaultSoundtrack); if( (oldPlayMusic == _playMusic) && (oldPlayDefaultSoundtrack == _playDefaultSoundtrack)) { //no changes... return; } startMusic(); } bool Audio::update( void) { if( !_sampleManager) return true; static float nextTime = Timer::getTime()+0.5; float thisTime = Timer::getTime(); if( thisTime > nextTime) { updateSettings(); nextTime = thisTime+0.5; } return true; }