diff --git a/src/pcm/PcmFormat.cxx b/src/pcm/PcmFormat.cxx
index 06390249d..a0e0bb2de 100644
--- a/src/pcm/PcmFormat.cxx
+++ b/src/pcm/PcmFormat.cxx
@@ -57,9 +57,7 @@ ConvertFromFloat(typename Traits::pointer_type dest,
 
 	while (src != end) {
 		typename Traits::long_type sample(*src++ * factor);
-		*dest++ = PcmClamp<typename Traits::value_type,
-				   typename Traits::long_type,
-				   Traits::BITS>(sample);
+		*dest++ = PcmClamp<F, Traits>(sample);
 	}
 }
 
diff --git a/src/pcm/PcmMix.cxx b/src/pcm/PcmMix.cxx
index d0c20d301..6a1c40db9 100644
--- a/src/pcm/PcmMix.cxx
+++ b/src/pcm/PcmMix.cxx
@@ -38,9 +38,7 @@ PcmAddVolume(typename Traits::value_type _a, typename Traits::value_type _b,
 	       pcm_volume_dither() + PCM_VOLUME_1 / 2)
 		/ PCM_VOLUME_1;
 
-	return PcmClamp<typename Traits::value_type,
-			typename Traits::long_type,
-			Traits::BITS>(c);
+	return PcmClamp<F, Traits>(c);
 }
 
 template<SampleFormat F, class Traits=SampleTraits<F>>
@@ -129,9 +127,7 @@ PcmAdd(typename Traits::value_type _a, typename Traits::value_type _b)
 {
 	typename Traits::long_type a(_a), b(_b);
 
-	return PcmClamp<typename Traits::value_type,
-			typename Traits::long_type,
-			Traits::BITS>(a + b);
+	return PcmClamp<F, Traits>(a + b);
 }
 
 template<SampleFormat F, class Traits=SampleTraits<F>>
diff --git a/src/pcm/PcmUtils.hxx b/src/pcm/PcmUtils.hxx
index 108ba85ae..06b3acb4d 100644
--- a/src/pcm/PcmUtils.hxx
+++ b/src/pcm/PcmUtils.hxx
@@ -26,6 +26,9 @@
 
 #include <stdint.h>
 
+enum class SampleFormat : uint8_t;
+template<SampleFormat F> struct SampleTraits;
+
 /**
  * Add a byte count to the specified pointer.  This is a utility
  * function to convert a source pointer and a byte count to an "end"
@@ -42,13 +45,15 @@ pcm_end_pointer(const T *p, size_t size)
  * Check if the value is within the range of the provided bit size,
  * and caps it if necessary.
  */
-template<typename T, typename U, unsigned bits>
+template<SampleFormat F, class Traits=SampleTraits<F>>
 gcc_const
-static inline T
-PcmClamp(U x)
+static inline typename Traits::value_type
+PcmClamp(typename Traits::long_type x)
 {
-	constexpr U MIN_VALUE = -(U(1) << (bits - 1));
-	constexpr U MAX_VALUE = (U(1) << (bits - 1)) - 1;
+	typedef typename Traits::value_type T;
+	typedef typename Traits::long_type U;
+	constexpr U MIN_VALUE = -(U(1) << (Traits::BITS - 1));
+	constexpr U MAX_VALUE = (U(1) << (Traits::BITS - 1)) - 1;
 
 	typedef std::numeric_limits<T> limits;
 	static_assert(MIN_VALUE >= limits::min(), "out of range");
diff --git a/src/pcm/PcmVolume.cxx b/src/pcm/PcmVolume.cxx
index fafec2d60..8426fd57b 100644
--- a/src/pcm/PcmVolume.cxx
+++ b/src/pcm/PcmVolume.cxx
@@ -39,9 +39,7 @@ pcm_volume_change(typename Traits::pointer_type buffer,
 			  PCM_VOLUME_1 / 2)
 			/ PCM_VOLUME_1;
 
-		*buffer++ = PcmClamp<typename Traits::value_type,
-				     typename Traits::long_type,
-				     Traits::BITS>(sample);
+		*buffer++ = PcmClamp<F, Traits>(sample);
 	}
 }