Index: /code/branches/sound3/src/orxonox/sound/AmbientSound.cc
===================================================================
--- /code/branches/sound3/src/orxonox/sound/AmbientSound.cc	(revision 6068)
+++ /code/branches/sound3/src/orxonox/sound/AmbientSound.cc	(revision 6069)
@@ -31,4 +31,5 @@
 #include "core/CoreIncludes.h"
 #include "core/EventIncludes.h"
+#include "core/GameMode.h"
 #include "core/XMLPort.h"
 #include "SoundManager.h"
@@ -42,4 +43,7 @@
     {
         RegisterObject(AmbientSound);
+
+        // Ambient sounds always fade in
+        this->setVolume(0);
     }
 
@@ -51,7 +55,8 @@
     {
         SUPER(AmbientSound, XMLPort, xmlelement, mode);
-        XMLPortParamExtern(AmbientSound, BaseSound, this, "source", setSource, getSource, xmlelement, mode);
+        XMLPortParamExtern(AmbientSound, BaseSound, this, "volume", setVolume, getVolume, xmlelement, mode);
         XMLPortParamExtern(AmbientSound, BaseSound, this, "loop", setLoop, getLoop, xmlelement, mode);
         XMLPortParamExtern(AmbientSound, BaseSound, this, "playOnLoad", setPlayOnLoad, getPlayOnLoad, xmlelement, mode);
+        XMLPortParamExtern(AmbientSound, BaseSound, this, "source", setSource, getSource, xmlelement, mode);
     }
 
@@ -64,20 +69,19 @@
     void AmbientSound::play()
     {
-        COUT(3) << this->getSource() << ": Playing" << std::endl;
-        if(GameMode::playsSound())
+        if (GameMode::playsSound())
         {
+            COUT(3) << "Sound: " << this->getSource() << ": Playing" << std::endl;
             SoundManager::getInstance().registerAmbientSound(this);
-            this->BaseSound::play();
         }
     }
 
-    void AmbientSound::replay()
+    void AmbientSound::doPlay()
     {
-        this->BaseSound::play();
+        BaseSound::play();
     }
 
     void AmbientSound::stop()
     {
-        if(GameMode::playsSound())
+        if (GameMode::playsSound())
         {
             SoundManager::getInstance().unregisterAmbientSound(this);
@@ -87,26 +91,39 @@
     void AmbientSound::doStop()
     {
-        this->BaseSound::stop();
+        BaseSound::stop();
+    }
+
+    void AmbientSound::pause()
+    {
+        if (GameMode::playsSound())
+        {
+            SoundManager::getInstance().pauseAmbientSound(this);
+        }
+    }
+
+    void AmbientSound::doPause()
+    {
+        BaseSound::pause();
     }
 
     void AmbientSound::setSource(const std::string& source)
     {
-        if(source.find('/') == std::string.npos && GameMode::playsSound())
+        if (GameMode::playsSound())
         {
             std::string filePath = SoundManager::getInstance().getAmbientPath(source);
-            if(!(filePath.empty()))
+            if (!filePath.empty())
             {
-                this->BaseSound::setSource(filePath);
+                BaseSound::setSource(filePath);
                 return;
             }
+            COUT(3) << "Sound: " << source << ": Not a valid name! Ambient sound will not change." << std::endl;       
         }
-        COUT(3) << source << ": Not a valid name! Ambient sound will not change." << std::endl;       
     }
 
     void AmbientSound::changedActivity() 
     {
-        COUT(3) << this->getSource() << ": ChangedActivity: " << this->isActive() << std::endl;
+        COUT(3) << "Sound: " << this->getSource() << ": ChangedActivity: " << this->isActive() << std::endl;
         this->BaseObject::changedActivity();
-        if(this->isActive())
+        if (this->isActive())
         {
             this->play();
Index: /code/branches/sound3/src/orxonox/sound/AmbientSound.h
===================================================================
--- /code/branches/sound3/src/orxonox/sound/AmbientSound.h	(revision 6068)
+++ /code/branches/sound3/src/orxonox/sound/AmbientSound.h	(revision 6069)
@@ -22,8 +22,10 @@
  *   Author:
  *      Reto Grieder
+ *      Kevin Young
  *   Co-authors:
  *      ...
  *
  */
+
 #ifndef _AmbientSound_H__
 #define _AmbientSound_H__
@@ -43,14 +45,9 @@
     class _OrxonoxExport AmbientSound : public BaseSound, public BaseObject
     {
+        friend class SoundManager;
+
     public:
         AmbientSound(BaseObject* creator);
         virtual ~AmbientSound();
-
-        virtual void play();
-        void replay();      // Continue playing without re-registering the sound
-        virtual void stop();
-        void doStop();
-
-        virtual void setSource(const std::string& source);
 
         virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
@@ -58,6 +55,14 @@
         virtual void changedActivity();
 
+        virtual void play();
+        virtual void stop();
+        virtual void pause();
+
+        virtual void setSource(const std::string& source);
 
     private:
+        void doPlay();      // Continue playing without re-registering the sound
+        void doStop();
+        void doPause();
     };
 }
Index: /code/branches/sound3/src/orxonox/sound/BaseSound.cc
===================================================================
--- /code/branches/sound3/src/orxonox/sound/BaseSound.cc	(revision 6068)
+++ /code/branches/sound3/src/orxonox/sound/BaseSound.cc	(revision 6069)
@@ -93,5 +93,5 @@
         if (alIsSource(this->audioSource_))
             return getSourceState() == AL_PAUSED;
-        return true;
+        return false;
     }
 
@@ -103,11 +103,15 @@
     }
 
-    void BaseSound::setPlayOnLoad(bool val)
-    {
-        this->bPlayOnLoad_ = val;
-        if(val)
-        {
-            this->play();
-        }
+    void BaseSound::setVolume(float vol)
+    {
+        if (vol > 1 || vol < 0)
+        {
+            COUT(2) << "Sound warning: volume out of range, cropping value." << std::endl;
+            vol = vol > 1 ? 1 : vol;
+            vol = vol < 0 ? 0 : vol;
+        }
+        this->volume_ = vol;
+        if (alIsSource(this->audioSource_))
+            alSourcef(this->audioSource_, AL_GAIN, vol);
     }
 
@@ -178,11 +182,8 @@
         alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
 
+        this->setVolume(this->volume_);
+
         if (this->bPlayOnLoad_)
             this->play();
-    }
-
-    ALuint BaseSound::getALAudioSource()
-    {
-        return audioSource_;
     }
 
@@ -275,4 +276,3 @@
         return buffer;
     }
-
-} // namespace: orxonox
+}
Index: /code/branches/sound3/src/orxonox/sound/BaseSound.h
===================================================================
--- /code/branches/sound3/src/orxonox/sound/BaseSound.h	(revision 6068)
+++ /code/branches/sound3/src/orxonox/sound/BaseSound.h	(revision 6069)
@@ -26,4 +26,5 @@
  *
  */
+
 #ifndef _BaseSound_H__
 #define _BaseSound_H__
@@ -32,5 +33,4 @@
 
 #include <string>
-#include <OgreSharedPtr.h>
 #include <OgreDataStream.h>
 #include "core/OrxonoxClass.h"
@@ -51,5 +51,5 @@
         virtual void play();
         virtual void stop();
-        void pause();
+        virtual void pause();
 
         bool isPlaying();
@@ -58,13 +58,16 @@
 
         virtual void setSource(const std::string& source);
-        const std::string& getSource() { return this->source_; }
+        virtual const std::string& getSource() const { return this->source_; }
 
-        bool getPlayOnLoad() { return this->bPlayOnLoad_; }
-        void setPlayOnLoad(bool val);
+        void setVolume(float vol);
+        float getVolume() const { return this->volume_; }
 
-        bool getLoop() { return this->bLoop_; }
+        bool getPlayOnLoad() const   { return this->bPlayOnLoad_; }
+        void setPlayOnLoad(bool val) { this->bPlayOnLoad_ = val; }
+
+        bool getLoop() const   { return this->bLoop_; }
         void setLoop(bool val) { this->bLoop_ = val; }
 
-        ALuint getALAudioSource(void);
+        //ALuint getALAudioSource(void);
 
     protected:
@@ -76,8 +79,9 @@
 
     private:
-        std::string source_;
-        bool bPlayOnLoad_;
-        bool bLoop_;
-        DataStreamPtr dataStream_;
+        std::string     source_;
+        float           volume_;
+        bool            bPlayOnLoad_;
+        bool            bLoop_;
+        DataStreamPtr   dataStream_;
     };
 }
Index: /code/branches/sound3/src/orxonox/sound/SoundManager.cc
===================================================================
--- /code/branches/sound3/src/orxonox/sound/SoundManager.cc	(revision 6068)
+++ /code/branches/sound3/src/orxonox/sound/SoundManager.cc	(revision 6069)
@@ -22,4 +22,5 @@
  *   Author:
  *       Erwin 'vaiursch' Herrsche
+ *       Kevin Young
  *   Co-authors:
  *      ...
@@ -30,4 +31,5 @@
 
 #include <AL/alut.h>
+#include <utility>
 
 #include "util/Exception.h"
@@ -53,5 +55,5 @@
         RegisterRootObject(SoundManager);
 
-        if (!alutInitWithoutContext(NULL,NULL))
+        if (!alutInitWithoutContext(NULL, NULL))
             ThrowException(InitialisationFailed, "Sound: OpenAL ALUT error: " << alutGetErrorString(alutGetError()));
         Loki::ScopeGuard alutExitGuard = Loki::MakeGuard(&alutExit);
@@ -103,15 +105,25 @@
     }
 
-    void SoundManager::update(const Clock &time)
-    {
-        this->fadeInAmbientSound(time.getDeltaTime());
-        this->fadeOutAmbientSound(time.getDeltaTime());
+    void SoundManager::update(const Clock& time)
+    {
+        this->processCrossFading(time.getDeltaTime());
     }
 
     void SoundManager::setConfigValues()
     {
-        SetConfigValue(fadeStep_, 0.2f)
+        SetConfigValue(crossFadeStep_, 0.2f)
             .description("Determines how fast sounds should fade, per second.")
             .callback(this, &SoundManager::checkFadeStepValidity);
+    }
+
+    void SoundManager::checkFadeStepValidity()
+    {
+        if (crossFadeStep_ <= 0.0 || crossFadeStep_ >= 1.0 )
+        {
+            COUT(2) << "Sound warning: Sound step out of range, ignoring change." << std::endl;
+            ResetConfigValue(crossFadeStep_);
+        }
+        COUT(3) << "SoundManager: fade step set to " << crossFadeStep_ << std::endl;
+        return;
     }
 
@@ -141,37 +153,51 @@
     void SoundManager::registerAmbientSound(AmbientSound* newAmbient)
     {
-        if(newAmbient != NULL)
-        {
-            if (!(this->ambientSounds_.empty())) 
-            {
-                this->fadeOutList_.push_front(std::make_pair(this->ambientSounds_.front(), 1.0));
-            }
-            this->fadeInList_.push_front(std::make_pair(newAmbient, 0.0));
-            this->ambientSounds_.push_front(newAmbient);
-        }
-    }
-
-    void SoundManager::unregisterAmbientSound(AmbientSound* currentAmbient)
-    {
-        if(currentAmbient == NULL || ambientSounds_.empty())
+        if (newAmbient != NULL)
+        {
+            for (AmbientList::const_iterator it = this->ambientSounds_.begin(); it != this->ambientSounds_.end(); ++it)
+            {
+                if (it->first == newAmbient)
+                {
+                    COUT(2) << "Sound warning: Will not play an AmbientSound twice." << std::endl;
+                    return;
+                }
+            }
+
+            if (!this->ambientSounds_.empty()) 
+            {
+                this->fadeOut(ambientSounds_.front().first);
+            }
+            this->ambientSounds_.push_front(std::make_pair(newAmbient, false));
+            newAmbient->doPlay();
+            this->fadeIn(newAmbient);
+        }
+    }
+
+    void SoundManager::unregisterAmbientSound(AmbientSound* oldAmbient)
+    {
+        if (oldAmbient == NULL || ambientSounds_.empty())
         {
             return;
         }
-        if(this->ambientSounds_.front() == currentAmbient) 
-        {
-            this->fadeOutList_.push_front(std::make_pair(this->ambientSounds_.front(), 1.0));
+        if (this->ambientSounds_.front().first == oldAmbient) 
+        {
+            this->fadeOut(oldAmbient);
             this->ambientSounds_.pop_front();
-            if(!(this->ambientSounds_.empty()))
-            {
-                this->fadeInList_.push_front(std::make_pair(this->ambientSounds_.front(), 0.0));
+            if (!this->ambientSounds_.empty())
+            {
+                if (!this->ambientSounds_.front().second) // Not paused before
+                {
+                    this->ambientSounds_.front().first->doPlay();
+                }
+                this->fadeIn(this->ambientSounds_.front().first);
             }
         }
         else
         {
-            for(std::list<AmbientSound*>::iterator it= this->ambientSounds_.begin(); it != this->ambientSounds_.end(); it++)
-            {
-                if(*it == currentAmbient)
-                {
-                    currentAmbient->doStop();
+            for (AmbientList::iterator it = this->ambientSounds_.begin(); it != this->ambientSounds_.end(); ++it)
+            {
+                if (it->first == oldAmbient)
+                {
+                    this->fadeOut(oldAmbient);
                     this->ambientSounds_.erase(it);
                     break;
@@ -181,74 +207,109 @@
     }
 
-    // Get the current mood and return the full path string to the requested sound.
-    const std::string& SoundManager::getAmbientPath(const std::string& source)
-    {
-        lastReqPath_ = "ambient/" + MoodManager::getInstance().getMood() + "/" + source;
-        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(lastReqPath_);
-        if(fileInfo == NULL)
-        {
-            return BLANKSTRING;
-        }
-        return lastReqPath_;
-    }
-
-    void SoundManager::fadeInAmbientSound(float dt)
-    {
-        if(!(this->fadeInList_.empty()))
-        {
-            for(std::list<std::pair<AmbientSound*, float> >::iterator it= this->fadeInList_.begin(); it != this->fadeInList_.end(); it++)
-            {
-                it->second += fadeStep_ * dt;
-                alSourcef(it->first->getALAudioSource(), AL_GAIN, it->second);
-            }
-            if(this->fadeInList_.back().second >= 1)
-            {
-                this->fadeInList_.pop_back();
-            }
-        }
-    }
-
-    void SoundManager::fadeOutAmbientSound(float dt)
-    {
-        if(!(this->fadeInList_.empty()))
-        {
-            for(std::list<std::pair<AmbientSound*, float> >::iterator it= this->fadeOutList_.begin(); it != this->fadeOutList_.end(); it++)
-            {
-                it->second -= fadeStep_ * dt;
-                alSourcef(it->first->getALAudioSource(), AL_GAIN, it->second);
-            }
-            if(this->fadeOutList_.back().second <= 0)
-            {
-                bool pauseTest = false;
-            
-                for(std::list<AmbientSound*>::iterator it= this->ambientSounds_.begin(); it != this->ambientSounds_.end(); it++)
-                {
-                    if(*it == this->fadeOutList_.back().first)
+    void SoundManager::pauseAmbientSound(AmbientSound* ambient)
+    {
+        if (ambient != NULL)
+        {
+            for (AmbientList::iterator it = this->ambientSounds_.begin(); it != this->ambientSounds_.end(); ++it)
+            {
+                if (it->first == ambient)
+                {
+                    it->second = true;
+                    this->fadeOut(it->first);
+                    return;
+                }
+            }
+        }
+    }
+
+    //! Get the current mood and return the full path string to the requested sound.
+    std::string SoundManager::getAmbientPath(const std::string& source)
+    {
+        std::string path = "ambient/" + MoodManager::getInstance().getMood() + "/" + source;
+        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(path);
+        if (fileInfo == NULL)
+        {
+            return "";
+        }
+        return path;
+    }
+
+    void SoundManager::fadeIn(AmbientSound* sound)
+    {
+        // If we're already fading out --> remove that
+        for (std::list<AmbientSound*>::iterator it = this->fadeOutList_.begin(); it != this->fadeOutList_.end(); it++)
+        {
+            if (*it == sound)
+            {
+                this->fadeOutList_.erase(it);
+                break;
+            }
+        }
+        // No duplicate entries
+        if (std::find(this->fadeInList_.begin(), this->fadeInList_.end(), sound) == this->fadeInList_.end())
+            this->fadeInList_.push_back(sound);
+    }
+
+    void SoundManager::fadeOut(AmbientSound* sound)
+    {
+        // If we're already fading in --> remove that
+        for (std::list<AmbientSound*>::iterator it = this->fadeInList_.begin(); it != this->fadeInList_.end(); it++)
+        {
+            if (*it == sound)
+            {
+                this->fadeInList_.erase(it);
+                break;
+            }
+        }
+        // No duplicate entries
+        if (std::find(this->fadeOutList_.begin(), this->fadeOutList_.end(), sound) == this->fadeOutList_.end())
+            this->fadeOutList_.push_back(sound);
+    }
+
+    void SoundManager::processCrossFading(float dt)
+    {
+        // FADE IN
+        for (std::list<AmbientSound*>::iterator it= this->fadeInList_.begin(); it != this->fadeInList_.end(); it)
+        {
+            if ((*it)->getVolume() + this->crossFadeStep_*dt > 1.0f)
+            {
+                (*it)->setVolume(1.0f);
+                this->fadeInList_.erase(it++);
+            }
+            else
+            {
+                (*it)->setVolume((*it)->getVolume() + this->crossFadeStep_*dt);
+                ++it;
+            }
+        }
+
+        // FADE OUT
+        for (std::list<AmbientSound*>::iterator it = this->fadeOutList_.begin(); it != this->fadeOutList_.end(); it)
+        {
+            if ((*it)->getVolume() - this->crossFadeStep_*dt < 0.0f)
+            {
+                (*it)->setVolume(0.0f);
+
+                // If sound is in the ambient list --> pause
+                for (AmbientList::const_iterator it2 = this->ambientSounds_.begin(); it2 != this->ambientSounds_.end(); ++it2)
+                {
+                    if (it2->first == *it)
                     {
-                        pauseTest = true;
+                        (*it)->doPause();
                         break;
                     }
                 }
-                if(pauseTest)
-                {
-                    this->fadeOutList_.back().first->pause();
-                }
-                else
-                {
-                    this->fadeOutList_.back().first->doStop();
-                }
-                this->fadeOutList_.pop_back();
-            }
-        }
-    }
-
-    void SoundManager::checkFadeStepValidity()
-    {
-        if(fadeStep_ <= 0.0 || fadeStep_ >= 1.0 )
-        {
-            ResetConfigValue(fadeStep_);
-        }
-        COUT(0) << "SoundManager: fade step now set to " << fadeStep_ << std::endl;
-        return;
+                // If not pause (by loop above for instance) --> stop
+                if (!(*it)->isPaused())
+                    (*it)->doStop();
+
+                this->fadeOutList_.erase(it++);
+            }
+            else
+            {
+                (*it)->setVolume((*it)->getVolume() - this->crossFadeStep_*dt);
+                ++it;
+            }
+        }
     }
 }
Index: /code/branches/sound3/src/orxonox/sound/SoundManager.h
===================================================================
--- /code/branches/sound3/src/orxonox/sound/SoundManager.h	(revision 6068)
+++ /code/branches/sound3/src/orxonox/sound/SoundManager.h	(revision 6069)
@@ -22,7 +22,9 @@
  *   Author:
  *       Erwin 'vaiursch' Herrsche
+ *       Kevin Young
  *   Co-authors:
  *      ...
  */
+
 #ifndef _SoundManager_H__
 #define _SoundManager_H__
@@ -30,8 +32,7 @@
 #include "OrxonoxPrereqs.h"
 
-#include <cassert>
 #include <list>
+#include <string>
 #include "util/Singleton.h"
-#include "tools/interfaces/Tickable.h"
 
 namespace orxonox
@@ -45,10 +46,11 @@
     {
         friend class Singleton<SoundManager>;
+
     public:
         SoundManager();
         ~SoundManager();
 
-        void update(const Clock &time);
-        void setConfigValues(void);
+        void update(const Clock& time);
+        void setConfigValues();
 
         void setListenerPosition(const Vector3& position);
@@ -56,22 +58,25 @@
 
         void registerAmbientSound(AmbientSound* newAmbient);
-        void unregisterAmbientSound(AmbientSound* currentAmbient);
-        const std::string& getAmbientPath(const std::string& source);
-        void fadeInAmbientSound(float dt);
-        void fadeOutAmbientSound(float dt);
-        void checkFadeStepValidity(void);
+        void unregisterAmbientSound(AmbientSound* oldAmbient);
+        void pauseAmbientSound(AmbientSound* ambient);
+        std::string getAmbientPath(const std::string& source);
 
     private:
+        void processCrossFading(float dt);
+        void fadeIn(AmbientSound* sound);
+        void fadeOut(AmbientSound* sound);
+
+        void checkFadeStepValidity();
+
         ALCdevice* device_;
         ALCcontext* context_;
        
-        std::list<AmbientSound*> ambientSounds_;
+        typedef std::list<std::pair<AmbientSound*, bool> > AmbientList;
+        AmbientList ambientSounds_;
         
-        float fadeStep_;       //per second
-        std::list<std::pair<AmbientSound*, float> > fadeInList_;
-        std::list<std::pair<AmbientSound*, float> > fadeOutList_;
+        float crossFadeStep_;       //!< Absolute change per second (0.1 means 10% of the nominal volume) for cross fading
+        std::list<AmbientSound*> fadeInList_;
+        std::list<AmbientSound*> fadeOutList_;
         
-        std::string lastReqPath_;
-
         static SoundManager* singletonPtr_s;
     };
Index: /code/branches/sound3/src/orxonox/sound/WorldSound.cc
===================================================================
--- /code/branches/sound3/src/orxonox/sound/WorldSound.cc	(revision 6068)
+++ /code/branches/sound3/src/orxonox/sound/WorldSound.cc	(revision 6069)
@@ -53,7 +53,8 @@
     {
         SUPER(WorldSound, XMLPort, xmlelement, mode);
-        XMLPortParamExtern(WorldSound, BaseSound, this, "source", setSource, getSource, xmlelement, mode);
+        XMLPortParamExtern(WorldSound, BaseSound, this, "volume", setVolume, getVolume, xmlelement, mode);
         XMLPortParamExtern(WorldSound, BaseSound, this, "loop", setLoop, getLoop, xmlelement, mode);
         XMLPortParamExtern(WorldSound, BaseSound, this, "playOnLoad", setPlayOnLoad, getPlayOnLoad, xmlelement, mode);
+        XMLPortParamExtern(WorldSound, BaseSound, this, "source", setSource, getSource, xmlelement, mode);
     }
 
@@ -88,4 +89,3 @@
         }
     }
-
 }
Index: /code/branches/sound3/src/orxonox/sound/WorldSound.h
===================================================================
--- /code/branches/sound3/src/orxonox/sound/WorldSound.h	(revision 6068)
+++ /code/branches/sound3/src/orxonox/sound/WorldSound.h	(revision 6069)
@@ -26,4 +26,5 @@
  *
  */
+
 #ifndef _WorldSound_H__
 #define _WorldSound_H__
