mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 11:37:58 +02:00
audio rendering loop now uses input-gain, tone-generator, noise-generator, and post-generator-gain objects / audiobuffer object now shared between all new audio objects / zero buffer copy between new objects / inline tone-generator code removed / new audio options for generators
This commit is contained in:
parent
5bab1ee7f5
commit
7a5ec429d1
2 changed files with 88 additions and 30 deletions
|
@ -40,6 +40,7 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include "Audio.h"
|
#include "Audio.h"
|
||||||
|
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "PositionalAudioStream.h"
|
#include "PositionalAudioStream.h"
|
||||||
|
@ -82,7 +83,7 @@ Audio::Audio(QObject* parent) :
|
||||||
_noiseGateSampleCounter(0),
|
_noiseGateSampleCounter(0),
|
||||||
_noiseGateOpen(false),
|
_noiseGateOpen(false),
|
||||||
_noiseGateEnabled(true),
|
_noiseGateEnabled(true),
|
||||||
_toneInjectionEnabled(false),
|
_audioSourceInjectEnabled(false),
|
||||||
_noiseGateFramesToClose(0),
|
_noiseGateFramesToClose(0),
|
||||||
_totalInputAudioSamples(0),
|
_totalInputAudioSamples(0),
|
||||||
_collisionSoundMagnitude(0.0f),
|
_collisionSoundMagnitude(0.0f),
|
||||||
|
@ -102,6 +103,8 @@ Audio::Audio(QObject* parent) :
|
||||||
_framesPerScope(DEFAULT_FRAMES_PER_SCOPE),
|
_framesPerScope(DEFAULT_FRAMES_PER_SCOPE),
|
||||||
_samplesPerScope(NETWORK_SAMPLES_PER_FRAME * _framesPerScope),
|
_samplesPerScope(NETWORK_SAMPLES_PER_FRAME * _framesPerScope),
|
||||||
_peqEnabled(false),
|
_peqEnabled(false),
|
||||||
|
_noiseSourceEnabled(false),
|
||||||
|
_toneSourceEnabled(true),
|
||||||
_scopeInput(0),
|
_scopeInput(0),
|
||||||
_scopeOutputLeft(0),
|
_scopeOutputLeft(0),
|
||||||
_scopeOutputRight(0),
|
_scopeOutputRight(0),
|
||||||
|
@ -137,6 +140,10 @@ void Audio::reset() {
|
||||||
_receivedAudioStream.reset();
|
_receivedAudioStream.reset();
|
||||||
resetStats();
|
resetStats();
|
||||||
_peq.reset();
|
_peq.reset();
|
||||||
|
_noiseSource.reset();
|
||||||
|
_toneSource.reset();
|
||||||
|
_sourceGain.reset();
|
||||||
|
_inputGain.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::resetStats() {
|
void Audio::resetStats() {
|
||||||
|
@ -424,13 +431,24 @@ void Audio::start() {
|
||||||
qDebug() << "Unable to set up audio output because of a problem with output format.";
|
qDebug() << "Unable to set up audio output because of a problem with output format.";
|
||||||
}
|
}
|
||||||
|
|
||||||
_peq.initialize( _inputFormat.sampleRate(), _audioInput->bufferSize() );
|
_inputFrameBuffer.initialize( _inputFormat.channelCount(), _audioInput->bufferSize() * 2 );
|
||||||
|
_peq.initialize( _inputFormat.sampleRate() );
|
||||||
|
_inputGain.initialize();
|
||||||
|
_sourceGain.initialize();
|
||||||
|
_noiseSource.initialize();
|
||||||
|
_toneSource.initialize();
|
||||||
|
_sourceGain.setParameters(0.25f,0.0f);
|
||||||
|
_inputGain.setParameters(1.0f,0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::stop() {
|
void Audio::stop() {
|
||||||
|
|
||||||
|
_inputFrameBuffer.finalize();
|
||||||
_peq.finalize();
|
_peq.finalize();
|
||||||
|
_inputGain.finalize();
|
||||||
|
_sourceGain.finalize();
|
||||||
|
_noiseSource.finalize();
|
||||||
|
_toneSource.finalize();
|
||||||
|
|
||||||
// "switch" to invalid devices in order to shut down the state
|
// "switch" to invalid devices in order to shut down the state
|
||||||
switchInputToAudioDevice(QAudioDeviceInfo());
|
switchInputToAudioDevice(QAudioDeviceInfo());
|
||||||
|
@ -477,13 +495,29 @@ void Audio::handleAudioInput() {
|
||||||
|
|
||||||
QByteArray inputByteArray = _inputDevice->readAll();
|
QByteArray inputByteArray = _inputDevice->readAll();
|
||||||
|
|
||||||
if (_peqEnabled && !_muted) {
|
int16_t* inputBuffer = (int16_t*)inputByteArray.data();
|
||||||
// we wish to pre-filter our captured input, prior to loopback
|
const int inputFrameCount = inputByteArray.size() / sizeof(int16_t);
|
||||||
|
|
||||||
int16_t* ioBuffer = (int16_t*)inputByteArray.data();
|
_inputFrameBuffer.copyFrames(1, inputFrameCount, inputBuffer, false /*copy in*/);
|
||||||
|
|
||||||
_peq.render(ioBuffer, ioBuffer, inputByteArray.size() / sizeof(int16_t));
|
_inputGain.render(_inputFrameBuffer); // input/mic gain+mute
|
||||||
|
|
||||||
|
// Add audio source injection if enabled
|
||||||
|
if (_audioSourceInjectEnabled && !_muted) {
|
||||||
|
|
||||||
|
if (_toneSourceEnabled) { // sine generator
|
||||||
|
_toneSource.render(_inputFrameBuffer);
|
||||||
}
|
}
|
||||||
|
else if(_noiseSourceEnabled) { // pink noise generator
|
||||||
|
_noiseSource.render(_inputFrameBuffer);
|
||||||
|
}
|
||||||
|
_sourceGain.render(_inputFrameBuffer); // post gain
|
||||||
|
}
|
||||||
|
if (_peqEnabled && !_muted) {
|
||||||
|
_peq.render(_inputFrameBuffer); // 3-band parametric eq
|
||||||
|
}
|
||||||
|
|
||||||
|
_inputFrameBuffer.copyFrames(1, inputFrameCount, inputBuffer, true /*copy out*/);
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio) && !_muted && _audioOutput) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio) && !_muted && _audioOutput) {
|
||||||
// if this person wants local loopback add that to the locally injected audio
|
// if this person wants local loopback add that to the locally injected audio
|
||||||
|
@ -599,20 +633,8 @@ void Audio::handleAudioInput() {
|
||||||
_dcOffset = DC_OFFSET_AVERAGING * _dcOffset + (1.0f - DC_OFFSET_AVERAGING) * measuredDcOffset;
|
_dcOffset = DC_OFFSET_AVERAGING * _dcOffset + (1.0f - DC_OFFSET_AVERAGING) * measuredDcOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add tone injection if enabled
|
|
||||||
const float TONE_FREQ = 220.0f / SAMPLE_RATE * TWO_PI;
|
|
||||||
const float QUARTER_VOLUME = 8192.0f;
|
|
||||||
if (_toneInjectionEnabled) {
|
|
||||||
loudness = 0.0f;
|
|
||||||
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
|
|
||||||
networkAudioSamples[i] = QUARTER_VOLUME * sinf(TONE_FREQ * (float)(i + _proceduralEffectSample));
|
|
||||||
loudness += fabsf(networkAudioSamples[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_lastInputLoudness = fabs(loudness / NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
|
||||||
|
|
||||||
// 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
|
||||||
if (!_toneInjectionEnabled && _noiseGateEnabled) {
|
if (!_audioSourceInjectEnabled && _noiseGateEnabled) {
|
||||||
float averageOfAllSampleFrames = 0.0f;
|
float averageOfAllSampleFrames = 0.0f;
|
||||||
_noiseSampleFrames[_noiseGateSampleCounter++] = _lastInputLoudness;
|
_noiseSampleFrames[_noiseGateSampleCounter++] = _lastInputLoudness;
|
||||||
if (_noiseGateSampleCounter == NUMBER_OF_NOISE_SAMPLE_FRAMES) {
|
if (_noiseGateSampleCounter == NUMBER_OF_NOISE_SAMPLE_FRAMES) {
|
||||||
|
@ -1041,8 +1063,18 @@ void Audio::processProceduralAudio(int16_t* monoInput, int numSamples) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::toggleToneInjection() {
|
void Audio::toggleAudioSourceInject() {
|
||||||
_toneInjectionEnabled = !_toneInjectionEnabled;
|
_audioSourceInjectEnabled = !_audioSourceInjectEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Audio::selectAudioSourcePinkNoise() {
|
||||||
|
_noiseSourceEnabled = Menu::getInstance()->isOptionChecked(MenuOption::AudioSourcePinkNoise);
|
||||||
|
_toneSourceEnabled = !_noiseSourceEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Audio::selectAudioSourceSine440() {
|
||||||
|
_toneSourceEnabled = Menu::getInstance()->isOptionChecked(MenuOption::AudioSourceSine440);
|
||||||
|
_noiseSourceEnabled = !_toneSourceEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::toggleAudioSpatialProcessing() {
|
void Audio::toggleAudioSpatialProcessing() {
|
||||||
|
|
|
@ -20,6 +20,12 @@
|
||||||
#include "Recorder.h"
|
#include "Recorder.h"
|
||||||
#include "RingBufferHistory.h"
|
#include "RingBufferHistory.h"
|
||||||
#include "MovingMinMaxAvg.h"
|
#include "MovingMinMaxAvg.h"
|
||||||
|
#include "AudioRingBuffer.h"
|
||||||
|
#include "AudioFormat.h"
|
||||||
|
#include "AudioBuffer.h"
|
||||||
|
#include "AudioSourceTone.h"
|
||||||
|
#include "AudioSourceNoise.h"
|
||||||
|
#include "AudioGain.h"
|
||||||
#include "AudioFilter.h"
|
#include "AudioFilter.h"
|
||||||
#include "AudioFilterBank.h"
|
#include "AudioFilterBank.h"
|
||||||
|
|
||||||
|
@ -116,7 +122,9 @@ public slots:
|
||||||
void audioMixerKilled();
|
void audioMixerKilled();
|
||||||
void toggleMute();
|
void toggleMute();
|
||||||
void toggleAudioNoiseReduction();
|
void toggleAudioNoiseReduction();
|
||||||
void toggleToneInjection();
|
void toggleAudioSourceInject();
|
||||||
|
void selectAudioSourcePinkNoise();
|
||||||
|
void selectAudioSourceSine440();
|
||||||
void toggleScope();
|
void toggleScope();
|
||||||
void toggleScopePause();
|
void toggleScopePause();
|
||||||
void toggleStats();
|
void toggleStats();
|
||||||
|
@ -199,7 +207,8 @@ private:
|
||||||
int _noiseGateSampleCounter;
|
int _noiseGateSampleCounter;
|
||||||
bool _noiseGateOpen;
|
bool _noiseGateOpen;
|
||||||
bool _noiseGateEnabled;
|
bool _noiseGateEnabled;
|
||||||
bool _toneInjectionEnabled;
|
bool _audioSourceInjectEnabled;
|
||||||
|
|
||||||
int _noiseGateFramesToClose;
|
int _noiseGateFramesToClose;
|
||||||
int _totalInputAudioSamples;
|
int _totalInputAudioSamples;
|
||||||
|
|
||||||
|
@ -282,6 +291,23 @@ private:
|
||||||
int _framesPerScope;
|
int _framesPerScope;
|
||||||
int _samplesPerScope;
|
int _samplesPerScope;
|
||||||
|
|
||||||
|
// Input framebuffer
|
||||||
|
AudioBufferFloat32 _inputFrameBuffer;
|
||||||
|
|
||||||
|
// Input gain
|
||||||
|
AudioGain _inputGain;
|
||||||
|
|
||||||
|
// Post tone/pink noise generator gain
|
||||||
|
AudioGain _sourceGain;
|
||||||
|
|
||||||
|
// Pink noise source
|
||||||
|
bool _noiseSourceEnabled;
|
||||||
|
AudioSourcePinkNoise _noiseSource;
|
||||||
|
|
||||||
|
// Tone source
|
||||||
|
bool _toneSourceEnabled;
|
||||||
|
AudioSourceTone _toneSource;
|
||||||
|
|
||||||
// Multi-band parametric EQ
|
// Multi-band parametric EQ
|
||||||
bool _peqEnabled;
|
bool _peqEnabled;
|
||||||
AudioFilterPEQ3m _peq;
|
AudioFilterPEQ3m _peq;
|
||||||
|
|
Loading…
Reference in a new issue