Index: code/branches/presentation2/src/orxonox/sound/BaseSound.cc
===================================================================
--- code/branches/presentation2/src/orxonox/sound/BaseSound.cc	(revision 6106)
+++ code/branches/presentation2/src/orxonox/sound/BaseSound.cc	(revision 6117)
@@ -29,4 +29,5 @@
 #include "BaseSound.h"
 
+#include <cassert>
 #include <vector>
 #include <AL/alut.h>
@@ -36,4 +37,5 @@
 #include "core/GameMode.h"
 #include "core/Resource.h"
+#include "core/XMLPort.h"
 
 namespace orxonox
@@ -42,8 +44,14 @@
         : audioSource_(0)
         , audioBuffer_(0)
-        , bPlayOnLoad_(false)
         , bLoop_(false)
+        , state_(Stopped)
     {
         RegisterRootObject(BaseSound);
+
+        if (GameMode::playsSound())
+        {
+            alGenSources(1, &this->audioSource_);
+            assert(this->audioSource_ != 0);
+        }
     }
 
@@ -51,76 +59,84 @@
     {
         this->setSource("");
+        if (GameMode::playsSound())
+            alDeleteSources(1, &this->audioSource_);
+    }
+
+    void BaseSound::XMLPortExtern(Element& xmlelement, XMLPort::Mode mode)
+    {
+        XMLPortParam(BaseSound, "volume", setVolume,  getVolume,  xmlelement, mode);
+        XMLPortParam(BaseSound, "loop",   setLooping, getLooping, xmlelement, mode);
+        XMLPortParam(BaseSound, "play",   play,       isPlaying,  xmlelement, mode);
+        XMLPortParam(BaseSound, "source", setSource,  getSource,  xmlelement, mode);
     }
 
     void BaseSound::play()
     {
+        if (!this->isPlaying() && GameMode::showsGraphics())
+        {
+            this->state_ = Playing;
+            alSourcePlay(this->audioSource_);
+
+            if (alGetError() != AL_NO_ERROR)
+                 COUT(2) << "Sound: OpenAL: Error playing sound " << this->audioSource_ << std::endl;
+        }
+    }
+
+    void BaseSound::stop()
+    {
+        this->state_ = Stopped;
+        if (GameMode::playsSound())
+            alSourceStop(this->audioSource_);
+    }
+
+    void BaseSound::pause()
+    {
+        if (this->isStopped())
+            return;
+        this->state_ = Paused;
+        if (GameMode::playsSound())
+            alSourcePause(this->audioSource_);
+    }
+
+    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_))
-        {
-            if (this->bLoop_)
-                alSourcei(this->audioSource_, AL_LOOPING, AL_TRUE);
-            else
-                alSourcei(this->audioSource_, AL_LOOPING, AL_FALSE);
-            alSourcePlay(this->audioSource_);
-
-            if (alGetError() != AL_NO_ERROR)
-            {
-                 COUT(2) << "Sound: OpenAL: Error playin sound " << this->audioSource_ << std::endl;
-            }
-        }
-    }
-
-    void BaseSound::stop()
-    {
-        if (alIsSource(this->audioSource_))
+            alSourcef(this->audioSource_, AL_GAIN, vol);
+    }
+
+    void BaseSound::setLooping(bool val)
+    {
+        this->bLoop_ = val;
+        if (GameMode::playsSound())
+            alSourcei(this->audioSource_, AL_LOOPING, (val ? AL_TRUE : AL_FALSE));
+    }
+
+    void BaseSound::setSource(const std::string& source)
+    {
+        if (!GameMode::playsSound() || source == this->source_) 
+        {
+            this->source_ = source;
+            return;
+        }
+
+        if (this->audioBuffer_ != 0 && alIsBuffer(this->audioBuffer_))
+        {
             alSourceStop(this->audioSource_);
-    }
-
-    void BaseSound::pause()
-    {
-        if (alIsSource(this->audioSource_))
-            alSourcePause(this->audioSource_);
-    }
-
-    bool BaseSound::isPlaying()
-    {
-        if (alIsSource(this->audioSource_))
-            return getSourceState() == AL_PLAYING;
-        return false;
-    }
-
-    bool BaseSound::isPaused()
-    {
-        if (alIsSource(this->audioSource_))
-            return getSourceState() == AL_PAUSED;
-        return true;
-    }
-
-    bool BaseSound::isStopped()
-    {
-        if (alIsSource(this->audioSource_))
-            return getSourceState() == AL_INITIAL || getSourceState() == AL_STOPPED;
-        return true;
-    }
-
-    void BaseSound::setPlayOnLoad(bool val)
-    {
-        this->bPlayOnLoad_ = true;
-        this->play();
-    }
-
-    void BaseSound::setSource(const std::string& source)
-    {
+            // Unload old sound first
+            alSourcei(this->audioSource_, AL_BUFFER, 0);
+            alDeleteBuffers(1, &this->audioBuffer_);
+            this->audioBuffer_ = 0;
+        }
+
         this->source_ = source;
-        if (!GameMode::playsSound())
-            return;
-
-        if (source.empty() && alIsSource(this->audioSource_))
-        {
-            // Unload sound
-            alSourcei(this->audioSource_, AL_BUFFER, 0);
-            alDeleteSources(1, &this->audioSource_);
-            alDeleteBuffers(1, &this->audioBuffer_);
-            return;
-        }
+        if (source_.empty()) 
+            return;
 
         COUT(3) << "Sound: OpenAL ALUT: loading file " << source << std::endl;
@@ -129,5 +145,5 @@
         if (fileInfo == NULL)
         {
-            COUT(2) << "Warning: Sound file '" << source << "' not found" << std::endl;
+            COUT(2) << "Sound: Warning: Sound file '" << source << "' not found" << std::endl;
             return;
         }
@@ -147,5 +163,5 @@
             {
                 COUT(2) << "Sound: Trying fallback ogg loader" << std::endl;
-                this->audioBuffer_ = loadOggFile();
+                this->audioBuffer_ = this->loadOggFile();
             }
 
@@ -157,5 +173,4 @@
         }
 
-        alGenSources(1, &this->audioSource_);
         alSourcei(this->audioSource_, AL_BUFFER, this->audioBuffer_);
         if (alGetError() != AL_NO_ERROR)
@@ -166,14 +181,13 @@
 
         alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
-
-        if (this->bPlayOnLoad_)
-            this->play();
-    }
-
-    ALint BaseSound::getSourceState()
-    {
-        ALint state;
-        alGetSourcei(this->audioSource_, AL_SOURCE_STATE, &state);
-        return state;
+        alSourcef (this->audioSource_, AL_GAIN, this->volume_);
+        alSourcei (this->audioSource_, AL_LOOPING, (this->bLoop_ ? AL_TRUE : AL_FALSE));
+        if (this->isPlaying() || this->isPaused())
+            alSourcePlay(this->audioSource_);
+        if (this->isPaused())
+            alSourcePause(this->audioSource_);
+
+        if (alGetError() != AL_NO_ERROR)
+            COUT(2) << "Sound: OpenAL: Error playing sound " << this->audioSource_ << std::endl;
     }
 
@@ -259,4 +273,3 @@
         return buffer;
     }
-
-} // namespace: orxonox
+}
