From 218de29356eb515774efb7e31cc7e9bf5467308d Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 5 Oct 2017 07:39:21 -0700 Subject: [PATCH 1/4] disable compiler optimization as temporary fix --- libraries/audio/src/AudioGate.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/audio/src/AudioGate.cpp b/libraries/audio/src/AudioGate.cpp index 5b2561da07..18884d008a 100644 --- a/libraries/audio/src/AudioGate.cpp +++ b/libraries/audio/src/AudioGate.cpp @@ -13,6 +13,10 @@ #include #include "AudioDynamics.h" +#ifdef __clang__ +#pragma clang optimize off +#endif + // log2 domain headroom bits above 0dB (int32_t) static const int LOG2_HEADROOM_Q30 = 1; From d8341a0929e6992bbdb670f9b684773a854e9a4c Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 5 Oct 2017 09:27:07 -0700 Subject: [PATCH 2/4] Work around compiler optimization bug --- libraries/audio/src/AudioDynamics.h | 19 +++++++++++-------- libraries/audio/src/AudioGate.cpp | 4 ---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/libraries/audio/src/AudioDynamics.h b/libraries/audio/src/AudioDynamics.h index 08daa21348..a759e1c63c 100644 --- a/libraries/audio/src/AudioDynamics.h +++ b/libraries/audio/src/AudioDynamics.h @@ -31,6 +31,9 @@ #define MULQ31(a,b) ((int32_t)(MUL64(a, b) >> 31)) #define MULDIV64(a,b,c) (int32_t)(MUL64(a, b) / (c)) +#define ADDMOD32(a,b) (int32_t)((uint32_t)(a) + (uint32_t)(b)) +#define SUBMOD32(a,b) (int32_t)((uint32_t)(a) - (uint32_t)(b)) + // // on x86 architecture, assume that SSE2 is present // @@ -399,14 +402,14 @@ public: x = MULHI(x, CICGAIN); _buffer[i] = _acc1; - _acc1 += x; // integrator + _acc1 = ADDMOD32(_acc1, x); // integrator i = (i + CIC1 - 1) & MASK; - x = _acc1 - _buffer[i]; // comb + x = SUBMOD32(_acc1, _buffer[i]); // comb _buffer[i] = _acc2; - _acc2 += x; // integrator + _acc2 = ADDMOD32(_acc2, x); // integrator i = (i + CIC2 - 1) & MASK; - x = _acc2 - _buffer[i]; // comb + x = SUBMOD32(_acc2, _buffer[i]); // comb _index = (i + 1) & MASK; // skip unused tap return x; @@ -464,14 +467,14 @@ public: x = MULHI(x, CICGAIN); _buffer[i] = _acc1; - _acc1 += x; // integrator + _acc1 = ADDMOD32(_acc1, x); // integrator i = (i + CIC1 - 1) & MASK; - x = _acc1 - _buffer[i]; // comb + x = SUBMOD32(_acc1, _buffer[i]); // comb _buffer[i] = _acc2; - _acc2 += x; // integrator + _acc2 = ADDMOD32(_acc2, x); // integrator i = (i + CIC2 - 1) & MASK; - x = _acc2 - _buffer[i]; // comb + x = SUBMOD32(_acc2, _buffer[i]); // comb _index = (i + 1) & MASK; // skip unused tap return x; diff --git a/libraries/audio/src/AudioGate.cpp b/libraries/audio/src/AudioGate.cpp index 18884d008a..5b2561da07 100644 --- a/libraries/audio/src/AudioGate.cpp +++ b/libraries/audio/src/AudioGate.cpp @@ -13,10 +13,6 @@ #include #include "AudioDynamics.h" -#ifdef __clang__ -#pragma clang optimize off -#endif - // log2 domain headroom bits above 0dB (int32_t) static const int LOG2_HEADROOM_Q30 = 1; From 82d13090f9a40e6a30372581658663942e6eea8c Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 5 Oct 2017 09:28:30 -0700 Subject: [PATCH 3/4] Better comments --- libraries/audio/src/AudioDynamics.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/audio/src/AudioDynamics.h b/libraries/audio/src/AudioDynamics.h index a759e1c63c..b7c168bfab 100644 --- a/libraries/audio/src/AudioDynamics.h +++ b/libraries/audio/src/AudioDynamics.h @@ -397,6 +397,8 @@ public: // Fast FIR attack/lowpass filter using a 2-stage CIC filter. // The step response reaches final value after N-1 samples. + // NOTE: CIC integrators intentionally overflow, using modulo arithmetic. + // See E. B. Hogenauer, "An economical class of digital filters for decimation and interpolation" const int32_t CICGAIN = 0xffffffff / (CIC1 * CIC2); // Q32 x = MULHI(x, CICGAIN); @@ -462,6 +464,8 @@ public: // Fast FIR attack/lowpass filter using a 2-stage CIC filter. // The step response reaches final value after N-1 samples. + // NOTE: CIC integrators intentionally overflow, using modulo arithmetic. + // See E. B. Hogenauer, "An economical class of digital filters for decimation and interpolation" const int32_t CICGAIN = 0xffffffff / (CIC1 * CIC2); // Q32 x = MULHI(x, CICGAIN); From 8822b1bfa425dc1434d363df542d094543589dc8 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 5 Oct 2017 09:49:38 -0700 Subject: [PATCH 4/4] Minor cleanup --- libraries/audio/src/AudioGate.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/audio/src/AudioGate.cpp b/libraries/audio/src/AudioGate.cpp index 5b2561da07..13c794b923 100644 --- a/libraries/audio/src/AudioGate.cpp +++ b/libraries/audio/src/AudioGate.cpp @@ -6,12 +6,12 @@ // Copyright 2017 High Fidelity, Inc. // -#include "AudioGate.h" - #include +#include #include -#include + #include "AudioDynamics.h" +#include "AudioGate.h" // log2 domain headroom bits above 0dB (int32_t) static const int LOG2_HEADROOM_Q30 = 1; @@ -418,7 +418,7 @@ void GateMono::process(int16_t* input, int16_t* output, int numFrames) { _dc.process(x); // peak detect - int32_t peak = std::abs(x); + int32_t peak = abs(x); // convert to log2 domain peak = fixlog2(peak);