mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 15:02:10 +02:00
Apply variable output gain using cubic smoothing
This commit is contained in:
parent
86f562de1b
commit
85f425a93b
2 changed files with 39 additions and 0 deletions
|
@ -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);
|
||||
|
|
|
@ -395,6 +395,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 };
|
||||
|
|
Loading…
Reference in a new issue