Add Audio Noise Reduction

This commit is contained in:
Philip Rosedale 2014-02-08 16:35:37 -08:00
parent f5bbdc2c65
commit 03bc5adf64
5 changed files with 53 additions and 6 deletions

View file

@ -65,6 +65,10 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* p
_measuredJitter(0),
_jitterBufferSamples(initialJitterBufferSamples),
_lastInputLoudness(0),
_averageInputLoudness(0),
_noiseGateOpen(false),
_noiseGateEnabled(true),
_noiseGateFramesToClose(0),
_lastVelocity(0),
_lastAcceleration(0),
_totalPacketsReceived(0),
@ -348,12 +352,40 @@ void Audio::handleAudioInput() {
_inputFormat, _desiredInputFormat);
float loudness = 0;
float thisSample = 0;
int samplesOverNoiseGate = 0;
const float NOISE_GATE_HEIGHT = 3.f;
const int NOISE_GATE_WIDTH = 5;
const int NOISE_GATE_CLOSE_FRAME_DELAY = 30;
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
loudness += fabsf(monoAudioSamples[i]);
thisSample = fabsf(monoAudioSamples[i]);
loudness += thisSample;
// Noise Reduction: Count peaks above the average loudness
if (thisSample > (_averageInputLoudness * NOISE_GATE_HEIGHT)) {
samplesOverNoiseGate++;
}
}
_lastInputLoudness = loudness / NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
const float LOUDNESS_AVERAGING_FRAMES = 1000.f; // This will be about 10 seconds
_averageInputLoudness = (1.f - 1.f / LOUDNESS_AVERAGING_FRAMES) * _averageInputLoudness + (1.f / LOUDNESS_AVERAGING_FRAMES) * _lastInputLoudness;
if (_noiseGateEnabled) {
if (samplesOverNoiseGate > NOISE_GATE_WIDTH) {
_noiseGateOpen = true;
_noiseGateFramesToClose = NOISE_GATE_CLOSE_FRAME_DELAY;
} else {
if (--_noiseGateFramesToClose == 0) {
_noiseGateOpen = false;
}
}
if (!_noiseGateOpen) {
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
monoAudioSamples[i] = 0;
}
}
}
// add input data just written to the scope
QMetaObject::invokeMethod(_scope, "addSamples", Qt::QueuedConnection,
@ -524,6 +556,10 @@ void Audio::toggleMute() {
muteToggled();
}
void Audio::toggleAudioNoiseReduction() {
_noiseGateEnabled = !_noiseGateEnabled;
}
void Audio::render(int screenWidth, int screenHeight) {
if (_audioInput && _audioOutput) {
glLineWidth(2.0);

View file

@ -45,7 +45,9 @@ public:
void render(int screenWidth, int screenHeight);
float getLastInputLoudness() const { return _lastInputLoudness; }
float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _averageInputLoudness, 0.f); }
void setNoiseGateEnabled(bool noiseGateEnabled) { _noiseGateEnabled = noiseGateEnabled; }
void setLastAcceleration(const glm::vec3 lastAcceleration) { _lastAcceleration = lastAcceleration; }
void setLastVelocity(const glm::vec3 lastVelocity) { _lastVelocity = lastVelocity; }
@ -73,6 +75,7 @@ public slots:
void handleAudioInput();
void reset();
void toggleMute();
void toggleAudioNoiseReduction();
virtual void handleAudioByteArray(const QByteArray& audioByteArray);
@ -106,6 +109,10 @@ private:
float _measuredJitter;
int16_t _jitterBufferSamples;
float _lastInputLoudness;
float _averageInputLoudness;
bool _noiseGateOpen;
bool _noiseGateEnabled;
int _noiseGateFramesToClose;
glm::vec3 _lastVelocity;
glm::vec3 _lastAcceleration;
int _totalPacketsReceived;

View file

@ -457,6 +457,11 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction,
0,
true,
appInstance->getAudio(),
SLOT(toggleAudioNoiseReduction()));
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio,

View file

@ -187,6 +187,7 @@ namespace MenuOption {
const QString Enable3DTVMode = "Enable 3DTV Mode";
const QString EnableOcclusionCulling = "Enable Occlusion Culling";
const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression";
const QString AudioNoiseReduction = "Audio Noise Reduction";
const QString EchoServerAudio = "Echo Server Audio";
const QString EchoLocalAudio = "Echo Local Audio";
const QString MuteAudio = "Mute Microphone";

View file

@ -107,7 +107,6 @@ QByteArray AvatarData::toByteArray() {
destinationBuffer += sizeof(_headData->_lookAtPosition);
// Instantaneous audio loudness (used to drive facial animation)
//destinationBuffer += packFloatToByte(destinationBuffer, std::min(MAX_AUDIO_LOUDNESS, _audioLoudness), MAX_AUDIO_LOUDNESS);
memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float));
destinationBuffer += sizeof(float);
@ -215,7 +214,6 @@ int AvatarData::parseData(const QByteArray& packet) {
sourceBuffer += sizeof(_headData->_lookAtPosition);
// Instantaneous audio loudness (used to drive facial animation)
//sourceBuffer += unpackFloatFromByte(sourceBuffer, _audioLoudness, MAX_AUDIO_LOUDNESS);
memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float);