stk-code_catmod/src/audio/music_information.cpp
mbjornstk 5fe41e5625 Run expand -t4 to convert tabs to spaces. No other whitespace fixes, but
there are still trailing spaces and lines with 5 spaces as indent (fix them
as the files are changed for other reasons). src/guiengine/CGUIFont.* and
src/bullet/ not processed to allow cleaner updates from upstream.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4320 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2009-12-18 00:36:35 +00:00

276 lines
8.8 KiB
C++

// $Id: music_information.cpp 1610 2008-03-01 03:18:53Z hikerstk $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
//
// 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 3
// 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "audio/music_information.hpp"
#include <stdexcept>
#include <sstream>
#include "audio/music_ogg.hpp"
#include "config/user_config.hpp"
#include "lisp/lisp.hpp"
#include "lisp/parser.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
#include "utils/string_utils.hpp"
MusicInformation::MusicInformation(const std::string& filename)
{
m_title = "";
m_composer = "";
m_numLoops = LOOP_FOREVER;
m_normal_filename = "";
m_fast_filename = "";
m_normal_music = NULL;
m_fast_music = NULL;
m_enable_fast = false;
m_faster_time = 1.0f;
m_max_pitch = 0.1f;
m_gain = 1.0f;
m_adjustedGain = 1.0f;
if(StringUtils::getExtension(filename)!="music")
{
// Create information just from ogg file
// -------------------------------------
m_title = StringUtils::removeExtension(StringUtils::getBasename(filename));
m_normal_filename = filename;
return;
}
// Otherwise read config file
// --------------------------
lisp::Parser parser;
const lisp::Lisp* const ROOT = parser.parse(filename);
const lisp::Lisp* const LISP = ROOT->getLisp("music-information");
if(!LISP)
{
delete ROOT;
std::ostringstream msg;
msg << "Couldn't load music information '" << filename
<< "': no music-information node.";
throw std::runtime_error(msg.str());
}
LISP->get ("title", m_title );
LISP->get ("composer", m_composer );
LISP->get ("loop", m_numLoops );
LISP->get ("music", m_normal_filename);
LISP->get ("enable-fast", m_enable_fast );
LISP->get ("fast-music", m_fast_filename );
// m_faster_time is used for twice: either as time to fade in faster music
// (if available), or the time to increase the pitch (if no faster music
// is available). We allow each .music file to use any of the two names.
// LISP->get doesn't change the value if the item is not found.
LISP->get ("fade-time", m_faster_time );
LISP->get ("faster-time", m_faster_time );
LISP->get ("max-pitch", m_max_pitch );
LISP->getVector("tracks", m_all_tracks );
LISP->get ("gain", m_gain );
m_adjustedGain = m_gain;
// Get the path from the filename and add it to the ogg filename
std::string path=StringUtils::getPath(filename);
m_normal_filename=path+"/"+m_normal_filename;
// Get the path from the filename and add it to the ogg filename
if(m_fast_filename!="")
{
m_fast_filename=path+"/"+m_fast_filename;
}
delete ROOT;
} // MusicInformation
//-----------------------------------------------------------------------------
void MusicInformation::addMusicToTracks()
{
for(int i=0; i<(int)m_all_tracks.size(); i++)
{
Track* track=track_manager->getTrack(m_all_tracks[i]);
if(track) track->addMusic(this);
}
} // addMusicToTracks
//-----------------------------------------------------------------------------
void MusicInformation::startMusic()
{
m_time_since_faster = 0.0f;
m_mode = SOUND_NORMAL;
if (m_normal_filename== "") return;
// First load the 'normal' music
// -----------------------------
if(StringUtils::getExtension(m_normal_filename)!="ogg")
{
fprintf(stderr, "WARNING: music file %s format not recognized.\n",
m_normal_filename.c_str());
return;
}
m_normal_music = new MusicOggStream();
if((m_normal_music->load(m_normal_filename)) == false)
{
delete m_normal_music;
m_normal_music=0;
fprintf(stderr, "WARNING: Unabled to load music %s, not supported or not found.\n",
m_normal_filename.c_str());
return;
}
m_normal_music->volumeMusic(m_adjustedGain);
m_normal_music->playMusic();
// Then (if available) load the music for the last track
// -----------------------------------------------------
if(m_fast_filename=="")
{
m_fast_music = NULL;
return; // no fast music
}
if(StringUtils::getExtension(m_fast_filename)!="ogg")
{
fprintf(stderr,
"WARNING: music file %s format not recognized, fast music is ignored\n",
m_fast_filename.c_str());
return;
}
m_fast_music= new MusicOggStream();
if((m_fast_music->load(m_fast_filename)) == false)
{
delete m_fast_music;
m_fast_music=0;
fprintf(stderr, "WARNING: Unabled to load fast music %s, not supported or not found.\n",
m_fast_filename.c_str());
return;
}
m_fast_music->volumeMusic(m_adjustedGain);
} // startMusic
//-----------------------------------------------------------------------------
void MusicInformation::update(float dt)
{
switch(m_mode)
{
case SOUND_FADING: {
if ( m_normal_music == NULL || m_fast_music == NULL ) break;
m_time_since_faster +=dt;
if(m_time_since_faster>=m_faster_time)
{
m_mode=SOUND_FAST;
m_normal_music->stopMusic();
m_fast_music->update();
return;
}
float fraction=m_time_since_faster/m_faster_time;
m_normal_music->updateFading(1-fraction);
m_fast_music->updateFading(fraction);
break;
}
case SOUND_FASTER: {
if ( m_normal_music == NULL ) break;
m_time_since_faster +=dt;
if(m_time_since_faster>=m_faster_time)
{
// Once the pitch is adjusted, just switch back to normal
// mode. We can't switch to fast music mode, since this would
// play m_fast_music, which isn't available.
m_mode=SOUND_NORMAL;
return;
}
float fraction=m_time_since_faster/m_faster_time;
m_normal_music->updateFaster(fraction, m_max_pitch);
break;
}
case SOUND_NORMAL:
if ( m_normal_music == NULL ) break;
m_normal_music->update();
break;
case SOUND_FAST:
if ( m_fast_music == NULL ) break;
m_fast_music->update();
break;
} // switch
} // update
//-----------------------------------------------------------------------------
void MusicInformation::stopMusic()
{
if (m_normal_music != NULL)
{
m_normal_music->stopMusic();
m_normal_music = NULL;
}
if (m_fast_music != NULL)
{
m_fast_music->stopMusic();
m_fast_music=NULL;
}
} // stopMusic
//-----------------------------------------------------------------------------
void MusicInformation::pauseMusic()
{
if (m_normal_music != NULL) m_normal_music->pauseMusic();
if (m_fast_music != NULL) m_fast_music->pauseMusic();
} // pauseMusic
//-----------------------------------------------------------------------------
void MusicInformation::resumeMusic()
{
if (m_normal_music != NULL) m_normal_music->resumeMusic();
if (m_fast_music != NULL) m_fast_music->resumeMusic();
} // resumeMusic
//-----------------------------------------------------------------------------
void MusicInformation::volumeMusic(float gain)
{
m_adjustedGain = m_gain * gain;
if (m_normal_music != NULL) m_normal_music->volumeMusic(m_adjustedGain);
if (m_fast_music != NULL) m_fast_music->volumeMusic(m_adjustedGain);
} // volumeMusic
//-----------------------------------------------------------------------------
void MusicInformation::switchToFastMusic()
{
if(!m_enable_fast) return;
m_time_since_faster = 0.0f;
if(m_fast_music)
{
m_mode = SOUND_FADING;
m_fast_music->playMusic();
}
else
{
// FIXME: for now this music is too annoying,
m_mode = SOUND_FASTER;
}
} // switchToFastMusic
//-----------------------------------------------------------------------------