From f8ba6bc80da381e65939c34f3c453abd657152d4 Mon Sep 17 00:00:00 2001 From: philippegorley <philippe.gorley@savoirfairelinux.com> Date: Thu, 15 Nov 2018 14:48:26 -0500 Subject: [PATCH] audio: clip audio signal when mixing Blindly adding both signals results in over/underflows which show up in the signal as noise, avoid that by clamping the result between min and max for s16 samples. Change-Id: Ibbb42d87497c662b5ba9085d4c9efb6f1e45a183 --- src/media/audio/audiobuffer.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/media/audio/audiobuffer.cpp b/src/media/audio/audiobuffer.cpp index 289161c591..2c9acffab1 100644 --- a/src/media/audio/audiobuffer.cpp +++ b/src/media/audio/audiobuffer.cpp @@ -244,8 +244,16 @@ size_t AudioBuffer::mix(const AudioBuffer& other, bool up /* = true */) for (unsigned i = 0; i < chan_num; i++) { unsigned src_chan = upmix ? std::min<unsigned>(i, other.samples_.size() - 1) : i; - for (unsigned j = 0; j < samp_num; j++) - samples_[i][j] += other.samples_[src_chan][j]; + for (unsigned j = 0; j < samp_num; j++) { + // clamp result to min/max + // result must be larger than 16 bits to check for over/underflow + int32_t n = static_cast<int32_t>(samples_[i][j]) + static_cast<int32_t>(other.samples_[src_chan][j]); + if (n < std::numeric_limits<AudioSample>::min()) + n = std::numeric_limits<AudioSample>::min(); + else if (n > std::numeric_limits<AudioSample>::max()) + n = std::numeric_limits<AudioSample>::max(); + samples_[i][j] = n; + } } return samp_num; -- GitLab