diff --git a/daemon/src/config/yamlnode.cpp b/daemon/src/config/yamlnode.cpp
index 9bd2abcc2c59e15497c210da7536f7608cdb33a9..ada00d4a499b4002f3cc608d165657579d0c3ffd 100644
--- a/daemon/src/config/yamlnode.cpp
+++ b/daemon/src/config/yamlnode.cpp
@@ -109,6 +109,17 @@ void MappingNode::getValue(const std::string &key, int *i) const
     *i = std::atoi(node->getValue().c_str());
 }
 
+void MappingNode::getValue(const std::string &key, double *d) const
+{
+    ScalarNode *node = static_cast<ScalarNode*>(getValue(key));
+    if (!node) {
+        ERROR("node %s not found", key.c_str());
+        return;
+    }
+
+    *d = std::atof(node->getValue().c_str());
+}
+
 void MappingNode::getValue(const std::string &key, std::string *v) const
 {
     ScalarNode *node = static_cast<ScalarNode*>(getValue(key));
diff --git a/daemon/src/config/yamlnode.h b/daemon/src/config/yamlnode.h
index ffd388f61187e4d7b0a7f0ae7bc015a889cd0da4..684cbc033e738866daa7bea10206e6d86787244f 100644
--- a/daemon/src/config/yamlnode.h
+++ b/daemon/src/config/yamlnode.h
@@ -65,6 +65,7 @@ class YamlNode {
         virtual YamlNode *getValue(const std::string &key) const = 0;
         virtual void getValue(const std::string &key UNUSED, bool *b) const = 0;
         virtual void getValue(const std::string &key UNUSED, int *i) const = 0;
+        virtual void getValue(const std::string &key UNUSED, double *d) const = 0;
         virtual void getValue(const std::string &key UNUSED, std::string *s) const = 0;
 
     private:
@@ -89,6 +90,7 @@ class YamlDocument : public YamlNode {
         virtual YamlNode *getValue(const std::string &key UNUSED) const { return NULL; }
         virtual void getValue(const std::string &key UNUSED, bool *b) const { *b = false; }
         virtual void getValue(const std::string &key UNUSED, int *i) const { *i = 0; }
+        virtual void getValue(const std::string &key UNUSED, double *d) const { *d = 0.0; }
         virtual void getValue(const std::string &key UNUSED, std::string *s) const { *s = ""; }
 
     private:
@@ -110,6 +112,7 @@ class SequenceNode : public YamlNode {
         virtual YamlNode *getValue(const std::string &key UNUSED) const { return NULL; }
         virtual void getValue(const std::string &key UNUSED, bool *b) const { *b = false; }
         virtual void getValue(const std::string &key UNUSED, int *i) const { *i = 0; }
+        virtual void getValue(const std::string &key UNUSED, double *d) const { *d = 0.0; }
         virtual void getValue(const std::string &key UNUSED, std::string *s) const { *s = ""; }
 
 
@@ -136,6 +139,7 @@ class MappingNode : public YamlNode {
         YamlNode *getValue(const std::string &key) const;
         void getValue(const std::string &key, bool *b) const;
         void getValue(const std::string &key, int *i) const;
+        void getValue(const std::string &key, double *d) const;
         void getValue(const std::string &key, std::string *s) const;
 
         virtual void deleteChildNodes();
@@ -160,6 +164,7 @@ class ScalarNode : public YamlNode {
         virtual YamlNode *getValue(const std::string &key UNUSED) const { return NULL; }
         virtual void getValue(const std::string &key UNUSED, bool *b) const { *b = false; }
         virtual void getValue(const std::string &key UNUSED, int *i) const { *i = 0; }
+        virtual void getValue(const std::string &key UNUSED, double *d) const { *d = 0.0; }
         virtual void getValue(const std::string &key UNUSED, std::string *s) const { *s = ""; }
 
         virtual void deleteChildNodes() {}
diff --git a/daemon/src/preferences.cpp b/daemon/src/preferences.cpp
index be3ce3e14e372f63456567165bd4d872606fb15b..60fb102e049c12f5e4f54a6169b22e110e8b2eb6 100644
--- a/daemon/src/preferences.cpp
+++ b/daemon/src/preferences.cpp
@@ -115,8 +115,6 @@ static const char * const TOGGLE_PICKUP_HANGUP_SHORT_KEY = "togglePickupHangup";
 static const char * const DFT_PULSE_LENGTH_STR = "250"; /** Default DTMF lenght */
 static const char * const ZRTP_ZIDFILE = "zidFile";     /** The filename used for storing ZIDs */
 static const char * const ALSA_DFT_CARD    = "0";          /** Default sound card index */
-static const char * const DFT_VOL_SPKR_STR = "100";     /** Default speaker volume */
-static const char * const DFT_VOL_MICRO_STR    = "100";    /** Default mic volume */
 } // end anonymous namespace
 
 Preferences::Preferences() :
@@ -299,8 +297,8 @@ AudioPreference::AudioPreference() :
     , pulseDeviceRingtone_("")
     , recordpath_("")
     , alwaysRecording_(false)
-    , volumemic_(atoi(DFT_VOL_SPKR_STR))
-    , volumespkr_(atoi(DFT_VOL_MICRO_STR))
+    , volumemic_(1.0)
+    , volumespkr_(1.0)
     , noisereduce_(false)
     , echocancel_(false)
 {}
@@ -386,10 +384,10 @@ void AudioPreference::serialize(Conf::YamlEmitter &emitter)
     Conf::ScalarNode audioapi(audioApi_);
     Conf::ScalarNode recordpath(recordpath_); //: /home/msavard/Bureau
     Conf::ScalarNode alwaysRecording(alwaysRecording_);
-    std::stringstream micstr;
+    std::ostringstream micstr;
     micstr << volumemic_;
     Conf::ScalarNode volumemic(micstr.str()); //:  100
-    std::stringstream spkrstr;
+    std::ostringstream spkrstr;
     spkrstr << volumespkr_;
     Conf::ScalarNode volumespkr(spkrstr.str()); //: 100
     Conf::ScalarNode noise(noisereduce_);
@@ -438,6 +436,13 @@ AudioPreference::setRecordPath(const std::string &r)
     }
 }
 
+namespace {
+    double clamp(double min, double max, double val)
+    {
+        return std::min(max, std::max(min, val));
+    }
+}
+
 void AudioPreference::unserialize(const Conf::YamlNode &map)
 {
     map.getValue(AUDIO_API_KEY, &audioApi_);
@@ -449,7 +454,9 @@ void AudioPreference::unserialize(const Conf::YamlNode &map)
 
     map.getValue(ALWAYS_RECORDING_KEY, &alwaysRecording_);
     map.getValue(VOLUMEMIC_KEY, &volumemic_);
+    volumemic_ = clamp(-1.0, 1.0, volumemic_);
     map.getValue(VOLUMESPKR_KEY, &volumespkr_);
+    volumespkr_ = clamp(-1.0, 1.0, volumespkr_);
     map.getValue(NOISE_REDUCE_KEY, &noisereduce_);
     map.getValue(ECHO_CANCEL_KEY, &echocancel_);
 
diff --git a/daemon/src/preferences.h b/daemon/src/preferences.h
index 27ad5470622919643abb2b1b54edf81389a54b5e..2d3b876538155f102a88f96cddc1fe2acc2a8637 100644
--- a/daemon/src/preferences.h
+++ b/daemon/src/preferences.h
@@ -356,8 +356,8 @@ class AudioPreference : public Serializable {
         // general preference
         std::string recordpath_; //: /home/msavard/Bureau
         bool alwaysRecording_;
-        int volumemic_;
-        int volumespkr_;
+        double volumemic_;
+        double volumespkr_;
 
         bool noisereduce_;
         bool echocancel_;