diff --git a/src/music.hpp b/src/music.hpp index 08a235a1a..1bf19c478 100644 --- a/src/music.hpp +++ b/src/music.hpp @@ -31,6 +31,7 @@ public: virtual bool pauseMusic () = 0; virtual bool resumeMusic () = 0; virtual void updateFading(float percent) = 0; + virtual void updateFaster(float percent, float pitch) = 0; virtual void update () = 0; virtual ~Music () {}; diff --git a/src/music_information.cpp b/src/music_information.cpp index ebd041602..a29afa98c 100755 --- a/src/music_information.cpp +++ b/src/music_information.cpp @@ -39,7 +39,9 @@ MusicInformation::MusicInformation(const std::string& filename) m_numLoops = LOOP_FOREVER; m_normal_filename = ""; m_fast_filename = ""; - m_fade_time = 1.0f; + m_faster_time = 1.0f; + m_max_pitch = 0.1f; + if(StringUtils::extension(filename)!="music") { // Create information just from ogg file @@ -65,13 +67,19 @@ MusicInformation::MusicInformation(const std::string& filename) filename.c_str()); throw std::runtime_error(msg); } - LISP->get ("title", m_title ); - LISP->get ("composer", m_composer ); - LISP->get ("loop", m_numLoops ); - LISP->get ("music", m_normal_filename); - LISP->get ("fast-music", m_fast_filename ); - LISP->get ("fade-time", m_fade_time ); - LISP->getVector("tracks", m_all_tracks ); + LISP->get ("title", m_title ); + LISP->get ("composer", m_composer ); + LISP->get ("loop", m_numLoops ); + LISP->get ("music", m_normal_filename); + 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 ); // Get the path from the filename and add it to the ogg filename std::string path=StringUtils::path(filename); diff --git a/src/music_information.hpp b/src/music_information.hpp index a67b55f5e..9752b855f 100755 --- a/src/music_information.hpp +++ b/src/music_information.hpp @@ -32,7 +32,9 @@ private: std::string m_fast_filename; std::vector m_all_tracks; int m_numLoops; - float m_fade_time; + float m_faster_time; // Either time for fading faster + // music in, or time to change pitch + float m_max_pitch; // maximum pitch for faster music static const int LOOP_FOREVER=-1; public: MusicInformation (const std::string& filename); @@ -41,7 +43,8 @@ public: const std::string& getNormalFilename() const {return m_normal_filename; } const std::string& getFastFilename () const {return m_fast_filename; } int getNumLoops () const {return m_numLoops; } - float getFadeTime () const {return m_fade_time; } + float getFasterTime () const {return m_faster_time; } + float getMaxPitch () const {return m_max_pitch; } void addMusicToTracks () const; }; // MusicInformation #endif diff --git a/src/music_ogg.cpp b/src/music_ogg.cpp index bad2cef25..da28be93b 100644 --- a/src/music_ogg.cpp +++ b/src/music_ogg.cpp @@ -221,6 +221,13 @@ void MusicOggStream::updateFading(float percent) update(); } // updateFading +//----------------------------------------------------------------------------- +void MusicOggStream::updateFaster(float percent, float max_pitch) +{ + alSourcef(m_soundSource,AL_PITCH,1+max_pitch*percent); + update(); +} // updateFaster + //----------------------------------------------------------------------------- void MusicOggStream::update() { diff --git a/src/music_ogg.hpp b/src/music_ogg.hpp index 945d138cb..7052e78c1 100644 --- a/src/music_ogg.hpp +++ b/src/music_ogg.hpp @@ -41,6 +41,7 @@ public: virtual void update(); virtual void updateFading(float percent); + virtual void updateFaster(float percent, float max_pitch); virtual bool load(const std::string& filename); diff --git a/src/sound_manager.cpp b/src/sound_manager.cpp index 991fd45a8..f5750f75d 100644 --- a/src/sound_manager.cpp +++ b/src/sound_manager.cpp @@ -167,10 +167,7 @@ void SoundManager::playSfx(unsigned int id) { if(!user_config->doSFX() || !m_initialized) return; - if (id<0 || id>=m_sfxs.size() || !m_sfxs[id]) - { - assert(false); - } + assert(id>=0 && idplay(); } // playSfx @@ -179,7 +176,7 @@ void SoundManager::playSfx(unsigned int id) void SoundManager::playMusic(const MusicInformation* mi) { m_music_information = mi; - m_time_since_fade = 0.0f; + m_time_since_faster = 0.0f; m_mode = SOUND_NORMAL; if(!user_config->doMusic() || !m_initialized) return; @@ -277,12 +274,18 @@ void SoundManager::pauseMusic() */ void SoundManager::switchToFastMusic() { - if(m_fast_music && m_mode==SOUND_NORMAL) + if(m_mode!=SOUND_NORMAL) return; // ignore if already fast + + m_time_since_faster = 0.0f; + if(m_fast_music) { - m_mode = SOUND_FADING; - m_time_since_fade = 0.0f; + m_mode = SOUND_FADING; m_fast_music->playMusic(); } + else + { + m_mode = SOUND_FASTER; + } } // switchToFastMusic //----------------------------------------------------------------------------- @@ -306,17 +309,35 @@ void SoundManager::update(float dt) switch(m_mode) { case SOUND_FADING: { - m_time_since_fade +=dt; - if(m_time_since_fade>=m_music_information->getFadeTime()) + if(!m_music_information) return; + m_time_since_faster +=dt; + if(m_time_since_faster>=m_music_information->getFasterTime()) { m_mode=SOUND_FAST; m_normal_music->stopMusic(); m_fast_music->update(); return; } - float fraction=m_time_since_fade/m_music_information->getFadeTime(); + float fraction=m_time_since_faster/m_music_information->getFasterTime(); m_normal_music->updateFading(1-fraction); m_fast_music->updateFading(fraction); + break; + } + case SOUND_FASTER: { + if(!m_music_information) return; + m_time_since_faster +=dt; + if(m_time_since_faster>=m_music_information->getFasterTime()) + { + // 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_music_information->getFasterTime(); + m_normal_music->updateFaster(fraction, + m_music_information->getMaxPitch()); + break; } case SOUND_NORMAL: diff --git a/src/sound_manager.hpp b/src/sound_manager.hpp index fa04a0e5f..3cb83c59f 100644 --- a/src/sound_manager.hpp +++ b/src/sound_manager.hpp @@ -54,9 +54,12 @@ private: std::map m_allMusic; void loadMusicInformation(); - enum {SOUND_NORMAL, SOUND_FADING, - SOUND_FAST} m_mode; - float m_time_since_fade; + enum {SOUND_NORMAL, // normal music is played + SOUND_FADING, // normal music fading out, faster music fading in + SOUND_FASTER, // change pitch of normal music (i.e. no faster avail) + SOUND_FAST} // playing faster music or max pitch reached + m_mode; + float m_time_since_faster; public: SoundManager();