mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 02:16:51 +02:00
Add Audio Noise Reduction
This commit is contained in:
parent
f5bbdc2c65
commit
03bc5adf64
5 changed files with 53 additions and 6 deletions
|
@ -65,6 +65,10 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* p
|
||||||
_measuredJitter(0),
|
_measuredJitter(0),
|
||||||
_jitterBufferSamples(initialJitterBufferSamples),
|
_jitterBufferSamples(initialJitterBufferSamples),
|
||||||
_lastInputLoudness(0),
|
_lastInputLoudness(0),
|
||||||
|
_averageInputLoudness(0),
|
||||||
|
_noiseGateOpen(false),
|
||||||
|
_noiseGateEnabled(true),
|
||||||
|
_noiseGateFramesToClose(0),
|
||||||
_lastVelocity(0),
|
_lastVelocity(0),
|
||||||
_lastAcceleration(0),
|
_lastAcceleration(0),
|
||||||
_totalPacketsReceived(0),
|
_totalPacketsReceived(0),
|
||||||
|
@ -348,12 +352,40 @@ void Audio::handleAudioInput() {
|
||||||
_inputFormat, _desiredInputFormat);
|
_inputFormat, _desiredInputFormat);
|
||||||
|
|
||||||
float loudness = 0;
|
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++) {
|
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;
|
_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
|
// add input data just written to the scope
|
||||||
QMetaObject::invokeMethod(_scope, "addSamples", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(_scope, "addSamples", Qt::QueuedConnection,
|
||||||
|
@ -524,6 +556,10 @@ void Audio::toggleMute() {
|
||||||
muteToggled();
|
muteToggled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Audio::toggleAudioNoiseReduction() {
|
||||||
|
_noiseGateEnabled = !_noiseGateEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
void Audio::render(int screenWidth, int screenHeight) {
|
void Audio::render(int screenWidth, int screenHeight) {
|
||||||
if (_audioInput && _audioOutput) {
|
if (_audioInput && _audioOutput) {
|
||||||
glLineWidth(2.0);
|
glLineWidth(2.0);
|
||||||
|
|
|
@ -45,7 +45,9 @@ public:
|
||||||
|
|
||||||
void render(int screenWidth, int screenHeight);
|
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 setLastAcceleration(const glm::vec3 lastAcceleration) { _lastAcceleration = lastAcceleration; }
|
||||||
void setLastVelocity(const glm::vec3 lastVelocity) { _lastVelocity = lastVelocity; }
|
void setLastVelocity(const glm::vec3 lastVelocity) { _lastVelocity = lastVelocity; }
|
||||||
|
@ -73,6 +75,7 @@ public slots:
|
||||||
void handleAudioInput();
|
void handleAudioInput();
|
||||||
void reset();
|
void reset();
|
||||||
void toggleMute();
|
void toggleMute();
|
||||||
|
void toggleAudioNoiseReduction();
|
||||||
|
|
||||||
virtual void handleAudioByteArray(const QByteArray& audioByteArray);
|
virtual void handleAudioByteArray(const QByteArray& audioByteArray);
|
||||||
|
|
||||||
|
@ -106,6 +109,10 @@ private:
|
||||||
float _measuredJitter;
|
float _measuredJitter;
|
||||||
int16_t _jitterBufferSamples;
|
int16_t _jitterBufferSamples;
|
||||||
float _lastInputLoudness;
|
float _lastInputLoudness;
|
||||||
|
float _averageInputLoudness;
|
||||||
|
bool _noiseGateOpen;
|
||||||
|
bool _noiseGateEnabled;
|
||||||
|
int _noiseGateFramesToClose;
|
||||||
glm::vec3 _lastVelocity;
|
glm::vec3 _lastVelocity;
|
||||||
glm::vec3 _lastAcceleration;
|
glm::vec3 _lastAcceleration;
|
||||||
int _totalPacketsReceived;
|
int _totalPacketsReceived;
|
||||||
|
|
|
@ -457,6 +457,11 @@ Menu::Menu() :
|
||||||
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
|
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
|
||||||
|
|
||||||
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
|
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
|
||||||
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction,
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
appInstance->getAudio(),
|
||||||
|
SLOT(toggleAudioNoiseReduction()));
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio,
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio,
|
||||||
|
|
|
@ -187,6 +187,7 @@ namespace MenuOption {
|
||||||
const QString Enable3DTVMode = "Enable 3DTV Mode";
|
const QString Enable3DTVMode = "Enable 3DTV Mode";
|
||||||
const QString EnableOcclusionCulling = "Enable Occlusion Culling";
|
const QString EnableOcclusionCulling = "Enable Occlusion Culling";
|
||||||
const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression";
|
const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression";
|
||||||
|
const QString AudioNoiseReduction = "Audio Noise Reduction";
|
||||||
const QString EchoServerAudio = "Echo Server Audio";
|
const QString EchoServerAudio = "Echo Server Audio";
|
||||||
const QString EchoLocalAudio = "Echo Local Audio";
|
const QString EchoLocalAudio = "Echo Local Audio";
|
||||||
const QString MuteAudio = "Mute Microphone";
|
const QString MuteAudio = "Mute Microphone";
|
||||||
|
|
|
@ -107,7 +107,6 @@ QByteArray AvatarData::toByteArray() {
|
||||||
destinationBuffer += sizeof(_headData->_lookAtPosition);
|
destinationBuffer += sizeof(_headData->_lookAtPosition);
|
||||||
|
|
||||||
// Instantaneous audio loudness (used to drive facial animation)
|
// 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));
|
memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float));
|
||||||
destinationBuffer += sizeof(float);
|
destinationBuffer += sizeof(float);
|
||||||
|
|
||||||
|
@ -215,7 +214,6 @@ int AvatarData::parseData(const QByteArray& packet) {
|
||||||
sourceBuffer += sizeof(_headData->_lookAtPosition);
|
sourceBuffer += sizeof(_headData->_lookAtPosition);
|
||||||
|
|
||||||
// Instantaneous audio loudness (used to drive facial animation)
|
// Instantaneous audio loudness (used to drive facial animation)
|
||||||
//sourceBuffer += unpackFloatFromByte(sourceBuffer, _audioLoudness, MAX_AUDIO_LOUDNESS);
|
|
||||||
memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float));
|
memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float));
|
||||||
sourceBuffer += sizeof(float);
|
sourceBuffer += sizeof(float);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue