clean AudioNoiseGate

This commit is contained in:
Zach Pomerantz 2017-03-13 18:56:54 -04:00
parent 0abcda86a8
commit f43706dfe1
2 changed files with 13 additions and 36 deletions

View file

@ -19,19 +19,13 @@
const float AudioNoiseGate::CLIPPING_THRESHOLD = 0.90f; const float AudioNoiseGate::CLIPPING_THRESHOLD = 0.90f;
AudioNoiseGate::AudioNoiseGate() : AudioNoiseGate::AudioNoiseGate() :
_inputBlockCounter(0),
_lastLoudness(0.0f), _lastLoudness(0.0f),
_quietestBlock(std::numeric_limits<float>::max()),
_loudestBlock(0.0f),
_didClipInLastBlock(false), _didClipInLastBlock(false),
_dcOffset(0.0f), _dcOffset(0.0f),
_measuredFloor(0.0f), _measuredFloor(0.0f),
_sampleCounter(0), _sampleCounter(0),
_isOpen(false), _isOpen(false),
_blocksToClose(0) _blocksToClose(0) {}
{
}
void AudioNoiseGate::removeDCOffset(int16_t* samples, int numSamples) { void AudioNoiseGate::removeDCOffset(int16_t* samples, int numSamples) {
// //
@ -80,7 +74,7 @@ void AudioNoiseGate::gateSamples(int16_t* samples, int numSamples) {
float loudness = 0; float loudness = 0;
int thisSample = 0; int thisSample = 0;
int samplesOverNoiseGate = 0; int samplesOverNoiseGate = 0;
const float NOISE_GATE_HEIGHT = 7.0f; const float NOISE_GATE_HEIGHT = 7.0f;
const int NOISE_GATE_WIDTH = 5; const int NOISE_GATE_WIDTH = 5;
const int NOISE_GATE_CLOSE_BLOCK_DELAY = 5; const int NOISE_GATE_CLOSE_BLOCK_DELAY = 5;
@ -88,36 +82,22 @@ void AudioNoiseGate::gateSamples(int16_t* samples, int numSamples) {
// Check clipping, and check if should open noise gate // Check clipping, and check if should open noise gate
_didClipInLastBlock = false; _didClipInLastBlock = false;
for (int i = 0; i < numSamples; i++) { for (int i = 0; i < numSamples; i++) {
thisSample = std::abs(samples[i]); thisSample = std::abs(samples[i]);
if (thisSample >= ((float) AudioConstants::MAX_SAMPLE_VALUE * CLIPPING_THRESHOLD)) { if (thisSample >= ((float) AudioConstants::MAX_SAMPLE_VALUE * CLIPPING_THRESHOLD)) {
_didClipInLastBlock = true; _didClipInLastBlock = true;
} }
loudness += thisSample; loudness += thisSample;
// Noise Reduction: Count peaks above the average loudness // Noise Reduction: Count peaks above the average loudness
if (thisSample > (_measuredFloor * NOISE_GATE_HEIGHT)) { if (thisSample > (_measuredFloor * NOISE_GATE_HEIGHT)) {
samplesOverNoiseGate++; samplesOverNoiseGate++;
} }
} }
_lastLoudness = fabs(loudness / numSamples); _lastLoudness = fabs(loudness / numSamples);
if (_quietestBlock > _lastLoudness) {
_quietestBlock = _lastLoudness;
}
if (_loudestBlock < _lastLoudness) {
_loudestBlock = _lastLoudness;
}
const int FRAMES_FOR_NOISE_DETECTION = 400;
if (_inputBlockCounter++ > FRAMES_FOR_NOISE_DETECTION) {
_quietestBlock = std::numeric_limits<float>::max();
_loudestBlock = 0.0f;
_inputBlockCounter = 0;
}
// If Noise Gate is enabled, check and turn the gate on and off // If Noise Gate is enabled, check and turn the gate on and off
float averageOfAllSampleBlocks = 0.0f; float averageOfAllSampleBlocks = 0.0f;
_sampleBlocks[_sampleCounter++] = _lastLoudness; _sampleBlocks[_sampleCounter++] = _lastLoudness;
@ -130,7 +110,7 @@ void AudioNoiseGate::gateSamples(int16_t* samples, int numSamples) {
averageOfAllSampleBlocks += _sampleBlocks[j]; averageOfAllSampleBlocks += _sampleBlocks[j];
} }
thisAverage /= NOISE_GATE_BLOCKS_TO_AVERAGE; thisAverage /= NOISE_GATE_BLOCKS_TO_AVERAGE;
if (thisAverage < smallestSample) { if (thisAverage < smallestSample) {
smallestSample = thisAverage; smallestSample = thisAverage;
} }
@ -138,7 +118,7 @@ void AudioNoiseGate::gateSamples(int16_t* samples, int numSamples) {
averageOfAllSampleBlocks /= NUMBER_OF_NOISE_SAMPLE_BLOCKS; averageOfAllSampleBlocks /= NUMBER_OF_NOISE_SAMPLE_BLOCKS;
_measuredFloor = smallestSample; _measuredFloor = smallestSample;
_sampleCounter = 0; _sampleCounter = 0;
} }
_closedInLastBlock = false; _closedInLastBlock = false;
@ -156,7 +136,7 @@ void AudioNoiseGate::gateSamples(int16_t* samples, int numSamples) {
} }
if (!_isOpen) { if (!_isOpen) {
// First block after being closed gets faded to silence, we fade across // First block after being closed gets faded to silence, we fade across
// the entire block on fading out. All subsequent blocks are muted by being slammed // the entire block on fading out. All subsequent blocks are muted by being slammed
// to zeros // to zeros
if (_closedInLastBlock) { if (_closedInLastBlock) {
float fadeSlope = (1.0f / numSamples); float fadeSlope = (1.0f / numSamples);

View file

@ -19,24 +19,21 @@ const int NUMBER_OF_NOISE_SAMPLE_BLOCKS = 300;
class AudioNoiseGate { class AudioNoiseGate {
public: public:
AudioNoiseGate(); AudioNoiseGate();
void gateSamples(int16_t* samples, int numSamples); void gateSamples(int16_t* samples, int numSamples);
void removeDCOffset(int16_t* samples, int numSamples); void removeDCOffset(int16_t* samples, int numSamples);
bool clippedInLastBlock() const { return _didClipInLastBlock; } bool clippedInLastBlock() const { return _didClipInLastBlock; }
bool closedInLastBlock() const { return _closedInLastBlock; } bool closedInLastBlock() const { return _closedInLastBlock; }
bool openedInLastBlock() const { return _openedInLastBlock; } bool openedInLastBlock() const { return _openedInLastBlock; }
bool isOpen() const { return _isOpen; } bool isOpen() const { return _isOpen; }
float getMeasuredFloor() const { return _measuredFloor; } float getMeasuredFloor() const { return _measuredFloor; }
float getLastLoudness() const { return _lastLoudness; } float getLastLoudness() const { return _lastLoudness; }
static const float CLIPPING_THRESHOLD; static const float CLIPPING_THRESHOLD;
private: private:
int _inputBlockCounter;
float _lastLoudness; float _lastLoudness;
float _quietestBlock;
float _loudestBlock;
bool _didClipInLastBlock; bool _didClipInLastBlock;
float _dcOffset; float _dcOffset;
float _measuredFloor; float _measuredFloor;