diff --git a/src/pcm/PcmChannels.cxx b/src/pcm/PcmChannels.cxx index b90e48580..2e433e611 100644 --- a/src/pcm/PcmChannels.cxx +++ b/src/pcm/PcmChannels.cxx @@ -44,8 +44,8 @@ static typename Traits::value_type StereoToMono(typename Traits::value_type _a, typename Traits::value_type _b) { - typename Traits::long_type a(_a); - typename Traits::long_type b(_b); + typename Traits::sum_type a(_a); + typename Traits::sum_type b(_b); return typename Traits::value_type((a + b) / 2); } @@ -76,7 +76,7 @@ NToStereo(typename Traits::pointer_type dest, assert((end - src) % src_channels == 0); while (src != end) { - typename Traits::long_type sum = *src++; + typename Traits::sum_type sum = *src++; for (unsigned c = 1; c < src_channels; ++c) sum += *src++; @@ -101,7 +101,7 @@ NToM(typename Traits::pointer_type dest, assert((end - src) % src_channels == 0); while (src != end) { - typename Traits::long_type sum = *src++; + typename Traits::sum_type sum = *src++; for (unsigned c = 1; c < src_channels; ++c) sum += *src++; diff --git a/src/pcm/PcmMix.cxx b/src/pcm/PcmMix.cxx index 6a1c40db9..fab2d8154 100644 --- a/src/pcm/PcmMix.cxx +++ b/src/pcm/PcmMix.cxx @@ -125,7 +125,7 @@ template> static typename Traits::value_type PcmAdd(typename Traits::value_type _a, typename Traits::value_type _b) { - typename Traits::long_type a(_a), b(_b); + typename Traits::sum_type a(_a), b(_b); return PcmClamp(a + b); } diff --git a/src/pcm/Traits.hxx b/src/pcm/Traits.hxx index 7212b2dd6..0ec4aaf0a 100644 --- a/src/pcm/Traits.hxx +++ b/src/pcm/Traits.hxx @@ -50,6 +50,13 @@ struct SampleTraits { */ typedef const value_type *const_pointer_type; + /** + * A "long" type that is large and accurate enough for adding + * two values without risking an (integer) overflow or + * (floating point) precision loss. + */ + typedef int sum_type; + /** * A "long" type that is large and accurate enough for * arithmetic without risking an (integer) overflow or @@ -75,6 +82,7 @@ struct SampleTraits { typedef value_type *pointer_type; typedef const value_type *const_pointer_type; + typedef int_least32_t sum_type; typedef int_least32_t long_type; static constexpr size_t SAMPLE_SIZE = sizeof(value_type); @@ -87,6 +95,7 @@ struct SampleTraits { typedef value_type *pointer_type; typedef const value_type *const_pointer_type; + typedef int_least64_t sum_type; typedef int_least64_t long_type; static constexpr size_t SAMPLE_SIZE = sizeof(value_type); @@ -99,6 +108,7 @@ struct SampleTraits { typedef value_type *pointer_type; typedef const value_type *const_pointer_type; + typedef int_least32_t sum_type; typedef int_least64_t long_type; static constexpr size_t SAMPLE_SIZE = sizeof(value_type); @@ -111,6 +121,7 @@ struct SampleTraits { typedef value_type *pointer_type; typedef const value_type *const_pointer_type; + typedef float sum_type; typedef float long_type; static constexpr size_t SAMPLE_SIZE = sizeof(value_type);