Merge pull request #11538 from kencooke/audio-mac-bugfix2

Additional cleanup of audio noise gate
This commit is contained in:
John Conklin II 2017-10-17 11:02:55 -07:00 committed by GitHub
commit 31b8013ed9
2 changed files with 51 additions and 44 deletions

View file

@ -135,6 +135,7 @@ static const int32_t exp2Table[1 << EXP2_TABBITS][3] = {
static const int IEEE754_FABS_MASK = 0x7fffffff;
static const int IEEE754_MANT_BITS = 23;
static const int IEEE754_EXPN_BITS = 8;
static const int IEEE754_EXPN_BIAS = 127;
//
@ -152,7 +153,7 @@ static inline int32_t peaklog2(float* input) {
// split into e and x - 1.0
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
int32_t x = (peak << (31 - IEEE754_MANT_BITS)) & 0x7fffffff;
int32_t x = (peak << IEEE754_EXPN_BITS) & 0x7fffffff;
// saturate
if (e > 31) {
@ -191,7 +192,7 @@ static inline int32_t peaklog2(float* input0, float* input1) {
// split into e and x - 1.0
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
int32_t x = (peak << (31 - IEEE754_MANT_BITS)) & 0x7fffffff;
int32_t x = (peak << IEEE754_EXPN_BITS) & 0x7fffffff;
// saturate
if (e > 31) {
@ -234,7 +235,7 @@ static inline int32_t peaklog2(float* input0, float* input1, float* input2, floa
// split into e and x - 1.0
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
int32_t x = (peak << (31 - IEEE754_MANT_BITS)) & 0x7fffffff;
int32_t x = (peak << IEEE754_EXPN_BITS) & 0x7fffffff;
// saturate
if (e > 31) {
@ -259,30 +260,30 @@ static inline int32_t peaklog2(float* input0, float* input1, float* input2, floa
// Count Leading Zeros
// Emulates the CLZ (ARM) and LZCNT (x86) instruction
//
static inline int CLZ(uint32_t x) {
static inline int CLZ(uint32_t u) {
if (x == 0) {
if (u == 0) {
return 32;
}
int e = 0;
if (x < 0x00010000) {
x <<= 16;
if (u < 0x00010000) {
u <<= 16;
e += 16;
}
if (x < 0x01000000) {
x <<= 8;
if (u < 0x01000000) {
u <<= 8;
e += 8;
}
if (x < 0x10000000) {
x <<= 4;
if (u < 0x10000000) {
u <<= 4;
e += 4;
}
if (x < 0x40000000) {
x <<= 2;
if (u < 0x40000000) {
u <<= 2;
e += 2;
}
if (x < 0x80000000) {
if (u < 0x80000000) {
e += 1;
}
return e;
@ -290,19 +291,19 @@ static inline int CLZ(uint32_t x) {
//
// Compute -log2(x) for x=[0,1] in Q31, result in Q26
// x = 0 returns 0x7fffffff
// x < 0 undefined
// x <= 0 returns 0x7fffffff
//
static inline int32_t fixlog2(int32_t x) {
if (x == 0) {
if (x <= 0) {
return 0x7fffffff;
}
// split into e and x - 1.0
int e = CLZ((uint32_t)x);
x <<= e; // normalize to [0x80000000, 0xffffffff]
x &= 0x7fffffff; // x - 1.0
uint32_t u = (uint32_t)x;
int e = CLZ(u);
u <<= e; // normalize to [0x80000000, 0xffffffff]
x = u & 0x7fffffff; // x - 1.0
int k = x >> (31 - LOG2_TABBITS);
@ -320,13 +321,18 @@ static inline int32_t fixlog2(int32_t x) {
//
// Compute exp2(-x) for x=[0,32] in Q26, result in Q31
// x < 0 undefined
// x <= 0 returns 0x7fffffff
//
static inline int32_t fixexp2(int32_t x) {
if (x <= 0) {
return 0x7fffffff;
}
// split into e and 1.0 - x
int e = x >> LOG2_FRACBITS;
x = ~(x << LOG2_INTBITS) & 0x7fffffff;
uint32_t u = (uint32_t)x;
int e = u >> LOG2_FRACBITS;
x = ~(u << LOG2_INTBITS) & 0x7fffffff;
int k = x >> (31 - EXP2_TABBITS);

View file

@ -40,7 +40,7 @@ class MonoDCBlock {
public:
void process(int32_t& x) {
x <<= 15; // scale to Q30
x *= (1 << 15); // scale to Q30
x -= _dcOffset; // remove DC
_dcOffset += x >> 13; // pole = (1.0 - 2^-13) = 0.9999
}
@ -53,8 +53,8 @@ class StereoDCBlock {
public:
void process(int32_t& x0, int32_t& x1) {
x0 <<= 15;
x1 <<= 15;
x0 *= (1 << 15);
x1 *= (1 << 15);
x0 -= _dcOffset[0];
x1 -= _dcOffset[1];
@ -71,10 +71,10 @@ class QuadDCBlock {
public:
void process(int32_t& x0, int32_t& x1, int32_t& x2, int32_t& x3) {
x0 <<= 15;
x1 <<= 15;
x2 <<= 15;
x3 <<= 15;
x0 *= (1 << 15);
x1 *= (1 << 15);
x2 *= (1 << 15);
x3 *= (1 << 15);
x0 -= _dcOffset[0];
x1 -= _dcOffset[1];
@ -100,10 +100,10 @@ protected:
int _histogram[NHIST] = {};
// peakhold
int32_t _holdMin = 0x7fffffff;
int32_t _holdInc = 0x7fffffff;
uint32_t _holdMin = 0x7fffffff;
uint32_t _holdInc = 0x7fffffff;
uint32_t _holdMax = 0x7fffffff;
int32_t _holdRel = 0x7fffffff;
uint32_t _holdRel = 0x7fffffff;
int32_t _holdPeak = 0x7fffffff;
// hysteresis
@ -177,18 +177,23 @@ void GateImpl::setThreshold(float threshold) {
void GateImpl::setHold(float hold) {
const double RELEASE = 100.0; // release = 100ms
const double PROGHOLD = 0.100; // progressive hold = 100ms
const double PROGHOLD = 100.0; // progressive hold = 100ms
// pure hold = 1 to 1000ms
hold = MAX(hold, 1.0f);
hold = MIN(hold, 1000.0f);
// compute final tc
_holdMin = msToTc(RELEASE, _sampleRate);
_holdInc = (int32_t)((_holdMin - 0x7fffffff) / (PROGHOLD * _sampleRate));
_holdInc = MIN(_holdInc, -1); // prevent 0 on long releases
_holdMax = 0x7fffffff - (uint32_t)(_holdInc * (double)hold/1000.0 * _sampleRate);
// compute tc increment, to progress from 0x7fffffff to _holdMin in PROGHOLD ms
double progSamples = PROGHOLD/1000.0 * _sampleRate;
_holdInc = (uint32_t)((0x7fffffff - _holdMin) / progSamples);
_holdInc = MAX(_holdInc, 1); // prevent 0 on long releases
// compute initial tc, to progress from _holdMax to 0x7fffffff in hold ms
double holdSamples = (double)hold/1000.0 * _sampleRate;
_holdMax = 0x7fffffff + (uint32_t)(_holdInc * holdSamples);
}
//
@ -318,8 +323,6 @@ void GateImpl::processHistogram(int numFrames) {
// smooth threshold update
_threshAdapt = threshold + MULQ31((_threshAdapt - threshold), tcThreshold);
//printf("threshold = %0.1f\n", (_threshAdapt - (LOG2_HEADROOM_Q15 << LOG2_FRACBITS)) * -6.02f / (1 << LOG2_FRACBITS));
}
//
@ -336,10 +339,8 @@ int32_t GateImpl::peakhold(int32_t peak) {
// (_holdRel > _holdMin) progressive hold
// (_holdRel = _holdMin) release
_holdRel += _holdInc; // update progressive hold
_holdRel = MAX((uint32_t)_holdRel, (uint32_t)_holdMin); // saturate at final value
int32_t tc = MIN((uint32_t)_holdRel, 0x7fffffff);
_holdRel -= _holdInc; // update progressive hold
int32_t tc = MIN(MAX(_holdRel, _holdMin), 0x7fffffff); // saturate to [_holdMin, 0x7fffffff]
peak += MULQ31((_holdPeak - peak), tc); // apply release
} else {