Merge pull request #15534 from kencooke/audio-PTT-output-ducking

Reduce echo when push-to-talk is used
This commit is contained in:
Shannon Romano 2019-05-09 15:54:15 -07:00 committed by GitHub
commit 6aa8dc7c42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 0 deletions

View file

@ -366,8 +366,10 @@ void Audio::onContextChanged() {
void Audio::handlePushedToTalk(bool enabled) {
if (getPTT()) {
if (enabled) {
DependencyManager::get<AudioClient>()->setOutputGain(0.1f); // duck the output by 20dB
setMuted(false);
} else {
DependencyManager::get<AudioClient>()->setOutputGain(1.0f);
setMuted(true);
}
}

View file

@ -221,6 +221,35 @@ static float computeLoudness(int16_t* samples, int numSamples, int numChannels,
return (float)loudness * scale;
}
template <int NUM_CHANNELS>
static void applyGainSmoothing(float* buffer, int numFrames, float gain0, float gain1) {
// fast path for unity gain
if (gain0 == 1.0f && gain1 == 1.0f) {
return;
}
// cubic poly from gain0 to gain1
float c3 = -2.0f * (gain1 - gain0);
float c2 = 3.0f * (gain1 - gain0);
float c0 = gain0;
float t = 0.0f;
float tStep = 1.0f / numFrames;
for (int i = 0; i < numFrames; i++) {
// evaluate poly over t=[0,1)
float gain = (c3 * t + c2) * t * t + c0;
t += tStep;
// apply gain to all channels
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
buffer[NUM_CHANNELS*i + ch] *= gain;
}
}
}
static inline float convertToFloat(int16_t sample) {
return (float)sample * (1 / 32768.0f);
}
@ -2109,6 +2138,14 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
int framesPopped = samplesPopped / AudioConstants::STEREO;
int bytesWritten;
if (samplesPopped > 0) {
// apply output gain
float newGain = _audio->_outputGain.load(std::memory_order_acquire);
float oldGain = _audio->_lastOutputGain;
_audio->_lastOutputGain = newGain;
applyGainSmoothing<OUTPUT_CHANNEL_COUNT>(mixBuffer, framesPopped, oldGain, newGain);
if (deviceChannelCount == OUTPUT_CHANNEL_COUNT) {
// limit the audio
_audio->_audioLimiter.render(mixBuffer, (int16_t*)data, framesPopped);

View file

@ -241,8 +241,10 @@ public slots:
void setInputVolume(float volume, bool emitSignal = true);
void setReverb(bool reverb);
void setReverbOptions(const AudioEffectOptions* options);
void setLocalInjectorGain(float gain) { _localInjectorGain = gain; };
void setSystemInjectorGain(float gain) { _systemInjectorGain = gain; };
void setOutputGain(float gain) { _outputGain = gain; };
void outputNotify();
@ -395,6 +397,8 @@ private:
int _outputPeriod { 0 };
float* _outputMixBuffer { NULL };
int16_t* _outputScratchBuffer { NULL };
std::atomic<float> _outputGain { 1.0f };
float _lastOutputGain { 1.0f };
// for local audio (used by audio injectors thread)
std::atomic<float> _localInjectorGain { 1.0f };