mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 16:50:43 +02:00
Merge pull request #11538 from kencooke/audio-mac-bugfix2
Additional cleanup of audio noise gate
This commit is contained in:
commit
31b8013ed9
2 changed files with 51 additions and 44 deletions
|
@ -135,6 +135,7 @@ static const int32_t exp2Table[1 << EXP2_TABBITS][3] = {
|
||||||
|
|
||||||
static const int IEEE754_FABS_MASK = 0x7fffffff;
|
static const int IEEE754_FABS_MASK = 0x7fffffff;
|
||||||
static const int IEEE754_MANT_BITS = 23;
|
static const int IEEE754_MANT_BITS = 23;
|
||||||
|
static const int IEEE754_EXPN_BITS = 8;
|
||||||
static const int IEEE754_EXPN_BIAS = 127;
|
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
|
// split into e and x - 1.0
|
||||||
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
|
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
|
// saturate
|
||||||
if (e > 31) {
|
if (e > 31) {
|
||||||
|
@ -191,7 +192,7 @@ static inline int32_t peaklog2(float* input0, float* input1) {
|
||||||
|
|
||||||
// split into e and x - 1.0
|
// split into e and x - 1.0
|
||||||
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
|
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
|
// saturate
|
||||||
if (e > 31) {
|
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
|
// split into e and x - 1.0
|
||||||
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
|
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
|
// saturate
|
||||||
if (e > 31) {
|
if (e > 31) {
|
||||||
|
@ -259,30 +260,30 @@ static inline int32_t peaklog2(float* input0, float* input1, float* input2, floa
|
||||||
// Count Leading Zeros
|
// Count Leading Zeros
|
||||||
// Emulates the CLZ (ARM) and LZCNT (x86) instruction
|
// 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;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
int e = 0;
|
int e = 0;
|
||||||
if (x < 0x00010000) {
|
if (u < 0x00010000) {
|
||||||
x <<= 16;
|
u <<= 16;
|
||||||
e += 16;
|
e += 16;
|
||||||
}
|
}
|
||||||
if (x < 0x01000000) {
|
if (u < 0x01000000) {
|
||||||
x <<= 8;
|
u <<= 8;
|
||||||
e += 8;
|
e += 8;
|
||||||
}
|
}
|
||||||
if (x < 0x10000000) {
|
if (u < 0x10000000) {
|
||||||
x <<= 4;
|
u <<= 4;
|
||||||
e += 4;
|
e += 4;
|
||||||
}
|
}
|
||||||
if (x < 0x40000000) {
|
if (u < 0x40000000) {
|
||||||
x <<= 2;
|
u <<= 2;
|
||||||
e += 2;
|
e += 2;
|
||||||
}
|
}
|
||||||
if (x < 0x80000000) {
|
if (u < 0x80000000) {
|
||||||
e += 1;
|
e += 1;
|
||||||
}
|
}
|
||||||
return e;
|
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
|
// Compute -log2(x) for x=[0,1] in Q31, result in Q26
|
||||||
// x = 0 returns 0x7fffffff
|
// x <= 0 returns 0x7fffffff
|
||||||
// x < 0 undefined
|
|
||||||
//
|
//
|
||||||
static inline int32_t fixlog2(int32_t x) {
|
static inline int32_t fixlog2(int32_t x) {
|
||||||
|
|
||||||
if (x == 0) {
|
if (x <= 0) {
|
||||||
return 0x7fffffff;
|
return 0x7fffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// split into e and x - 1.0
|
// split into e and x - 1.0
|
||||||
int e = CLZ((uint32_t)x);
|
uint32_t u = (uint32_t)x;
|
||||||
x <<= e; // normalize to [0x80000000, 0xffffffff]
|
int e = CLZ(u);
|
||||||
x &= 0x7fffffff; // x - 1.0
|
u <<= e; // normalize to [0x80000000, 0xffffffff]
|
||||||
|
x = u & 0x7fffffff; // x - 1.0
|
||||||
|
|
||||||
int k = x >> (31 - LOG2_TABBITS);
|
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
|
// 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) {
|
static inline int32_t fixexp2(int32_t x) {
|
||||||
|
|
||||||
|
if (x <= 0) {
|
||||||
|
return 0x7fffffff;
|
||||||
|
}
|
||||||
|
|
||||||
// split into e and 1.0 - x
|
// split into e and 1.0 - x
|
||||||
int e = x >> LOG2_FRACBITS;
|
uint32_t u = (uint32_t)x;
|
||||||
x = ~(x << LOG2_INTBITS) & 0x7fffffff;
|
int e = u >> LOG2_FRACBITS;
|
||||||
|
x = ~(u << LOG2_INTBITS) & 0x7fffffff;
|
||||||
|
|
||||||
int k = x >> (31 - EXP2_TABBITS);
|
int k = x >> (31 - EXP2_TABBITS);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class MonoDCBlock {
|
||||||
public:
|
public:
|
||||||
void process(int32_t& x) {
|
void process(int32_t& x) {
|
||||||
|
|
||||||
x <<= 15; // scale to Q30
|
x *= (1 << 15); // scale to Q30
|
||||||
x -= _dcOffset; // remove DC
|
x -= _dcOffset; // remove DC
|
||||||
_dcOffset += x >> 13; // pole = (1.0 - 2^-13) = 0.9999
|
_dcOffset += x >> 13; // pole = (1.0 - 2^-13) = 0.9999
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,8 @@ class StereoDCBlock {
|
||||||
public:
|
public:
|
||||||
void process(int32_t& x0, int32_t& x1) {
|
void process(int32_t& x0, int32_t& x1) {
|
||||||
|
|
||||||
x0 <<= 15;
|
x0 *= (1 << 15);
|
||||||
x1 <<= 15;
|
x1 *= (1 << 15);
|
||||||
|
|
||||||
x0 -= _dcOffset[0];
|
x0 -= _dcOffset[0];
|
||||||
x1 -= _dcOffset[1];
|
x1 -= _dcOffset[1];
|
||||||
|
@ -71,10 +71,10 @@ class QuadDCBlock {
|
||||||
public:
|
public:
|
||||||
void process(int32_t& x0, int32_t& x1, int32_t& x2, int32_t& x3) {
|
void process(int32_t& x0, int32_t& x1, int32_t& x2, int32_t& x3) {
|
||||||
|
|
||||||
x0 <<= 15;
|
x0 *= (1 << 15);
|
||||||
x1 <<= 15;
|
x1 *= (1 << 15);
|
||||||
x2 <<= 15;
|
x2 *= (1 << 15);
|
||||||
x3 <<= 15;
|
x3 *= (1 << 15);
|
||||||
|
|
||||||
x0 -= _dcOffset[0];
|
x0 -= _dcOffset[0];
|
||||||
x1 -= _dcOffset[1];
|
x1 -= _dcOffset[1];
|
||||||
|
@ -100,10 +100,10 @@ protected:
|
||||||
int _histogram[NHIST] = {};
|
int _histogram[NHIST] = {};
|
||||||
|
|
||||||
// peakhold
|
// peakhold
|
||||||
int32_t _holdMin = 0x7fffffff;
|
uint32_t _holdMin = 0x7fffffff;
|
||||||
int32_t _holdInc = 0x7fffffff;
|
uint32_t _holdInc = 0x7fffffff;
|
||||||
uint32_t _holdMax = 0x7fffffff;
|
uint32_t _holdMax = 0x7fffffff;
|
||||||
int32_t _holdRel = 0x7fffffff;
|
uint32_t _holdRel = 0x7fffffff;
|
||||||
int32_t _holdPeak = 0x7fffffff;
|
int32_t _holdPeak = 0x7fffffff;
|
||||||
|
|
||||||
// hysteresis
|
// hysteresis
|
||||||
|
@ -177,18 +177,23 @@ void GateImpl::setThreshold(float threshold) {
|
||||||
void GateImpl::setHold(float hold) {
|
void GateImpl::setHold(float hold) {
|
||||||
|
|
||||||
const double RELEASE = 100.0; // release = 100ms
|
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
|
// pure hold = 1 to 1000ms
|
||||||
hold = MAX(hold, 1.0f);
|
hold = MAX(hold, 1.0f);
|
||||||
hold = MIN(hold, 1000.0f);
|
hold = MIN(hold, 1000.0f);
|
||||||
|
|
||||||
|
// compute final tc
|
||||||
_holdMin = msToTc(RELEASE, _sampleRate);
|
_holdMin = msToTc(RELEASE, _sampleRate);
|
||||||
|
|
||||||
_holdInc = (int32_t)((_holdMin - 0x7fffffff) / (PROGHOLD * _sampleRate));
|
// compute tc increment, to progress from 0x7fffffff to _holdMin in PROGHOLD ms
|
||||||
_holdInc = MIN(_holdInc, -1); // prevent 0 on long releases
|
double progSamples = PROGHOLD/1000.0 * _sampleRate;
|
||||||
|
_holdInc = (uint32_t)((0x7fffffff - _holdMin) / progSamples);
|
||||||
_holdMax = 0x7fffffff - (uint32_t)(_holdInc * (double)hold/1000.0 * _sampleRate);
|
_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
|
// smooth threshold update
|
||||||
_threshAdapt = threshold + MULQ31((_threshAdapt - threshold), tcThreshold);
|
_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) progressive hold
|
||||||
// (_holdRel = _holdMin) release
|
// (_holdRel = _holdMin) release
|
||||||
|
|
||||||
_holdRel += _holdInc; // update progressive hold
|
_holdRel -= _holdInc; // update progressive hold
|
||||||
_holdRel = MAX((uint32_t)_holdRel, (uint32_t)_holdMin); // saturate at final value
|
int32_t tc = MIN(MAX(_holdRel, _holdMin), 0x7fffffff); // saturate to [_holdMin, 0x7fffffff]
|
||||||
|
|
||||||
int32_t tc = MIN((uint32_t)_holdRel, 0x7fffffff);
|
|
||||||
peak += MULQ31((_holdPeak - peak), tc); // apply release
|
peak += MULQ31((_holdPeak - peak), tc); // apply release
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue