Do all the reverb at the input level

This commit is contained in:
Atlante45 2015-02-13 10:17:08 +01:00
parent e79e1a547f
commit 5a81b8a590
2 changed files with 32 additions and 23 deletions

View file

@ -616,9 +616,10 @@ void AudioClient::setReverbOptions(const AudioEffectOptions* options) {
} }
} }
void AudioClient::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { void AudioClient::addReverb(ty_gverb* gverb, int16_t* samplesData, int16_t* reverbAlone, int numSamples,
QAudioFormat& audioFormat, bool noEcho) {
float wetFraction = DB_CO(_reverbOptions->getWetLevel()); float wetFraction = DB_CO(_reverbOptions->getWetLevel());
float dryFraction = (noEcho) ? 0.0f : (1.0f - wetFraction); float dryFraction = 1.0f - wetFraction;
float lValue,rValue; float lValue,rValue;
for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) { for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) {
@ -633,11 +634,19 @@ void AudioClient::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSample
int lResult = glm::clamp((int)(samplesData[j] * dryFraction + lValue * wetFraction), int lResult = glm::clamp((int)(samplesData[j] * dryFraction + lValue * wetFraction),
AudioConstants::MIN_SAMPLE_VALUE, AudioConstants::MAX_SAMPLE_VALUE); AudioConstants::MIN_SAMPLE_VALUE, AudioConstants::MAX_SAMPLE_VALUE);
samplesData[j] = (int16_t)lResult; samplesData[j] = (int16_t)lResult;
if (noEcho) {
reverbAlone[j] = (int16_t)lValue * wetFraction;
}
} else if (j == (sample + 1)) { } else if (j == (sample + 1)) {
// right channel // right channel
int rResult = glm::clamp((int)(samplesData[j] * dryFraction + rValue * wetFraction), int rResult = glm::clamp((int)(samplesData[j] * dryFraction + rValue * wetFraction),
AudioConstants::MIN_SAMPLE_VALUE, AudioConstants::MAX_SAMPLE_VALUE); AudioConstants::MIN_SAMPLE_VALUE, AudioConstants::MAX_SAMPLE_VALUE);
samplesData[j] = (int16_t)rResult; samplesData[j] = (int16_t)rResult;
if (noEcho) {
reverbAlone[j] = (int16_t)rValue * wetFraction;
}
} else { } else {
// ignore channels above 2 // ignore channels above 2
} }
@ -647,9 +656,8 @@ void AudioClient::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSample
void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
// If there is server echo, reverb will be applied to the recieved audio stream so no need to have it here. // If there is server echo, reverb will be applied to the recieved audio stream so no need to have it here.
bool hasLocalReverb = (_reverb || _receivedAudioStream.hasReverb()) && bool hasReverb = _reverb || _receivedAudioStream.hasReverb();
!_shouldEchoToServer; if (_muted || !_audioOutput || (!_shouldEchoLocally && !hasReverb)) {
if (_muted || !_audioOutput || (!_shouldEchoLocally && !hasLocalReverb)) {
return; return;
} }
@ -671,24 +679,30 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
} }
} }
static QByteArray loopBackByteArray; int numInputSamples = inputByteArray.size() / sizeof(int16_t);
loopBackByteArray.resize(numDestinationSamplesRequired(_inputFormat, _outputFormat, int16_t* inputSamples = reinterpret_cast<int16_t*>(inputByteArray.data());
inputByteArray.size() / sizeof(int16_t)) * sizeof(int16_t));
possibleResampling(_loopbackResampler, static QByteArray reverbAlone;
reinterpret_cast<int16_t*>(inputByteArray.data()), reverbAlone.resize(inputByteArray.size());
reinterpret_cast<int16_t*>(loopBackByteArray.data()), int16_t* reverbAloneSamples = reinterpret_cast<int16_t*>(reverbAlone.data());
inputByteArray.size() / sizeof(int16_t), loopBackByteArray.size() / sizeof(int16_t),
_inputFormat, _outputFormat);
if (hasLocalReverb) { if (hasReverb) {
int16_t* loopbackSamples = reinterpret_cast<int16_t*>(loopBackByteArray.data());
int numLoopbackSamples = loopBackByteArray.size() / sizeof(int16_t);
updateGverbOptions(); updateGverbOptions();
addReverb(_gverbLocal, loopbackSamples, numLoopbackSamples, _outputFormat, !_shouldEchoLocally); addReverb(_gverbLocal, inputSamples, reverbAloneSamples, numInputSamples,
_outputFormat, !_shouldEchoLocally);
} }
if (_loopbackOutputDevice) { if (_loopbackOutputDevice) {
static QByteArray loopBackByteArray;
int numLoopbackSamples = numDestinationSamplesRequired(_inputFormat, _outputFormat, numInputSamples);
loopBackByteArray.resize(numLoopbackSamples * sizeof(int16_t));
possibleResampling(_loopbackResampler,
(_shouldEchoLocally) ? inputSamples : reverbAloneSamples,
reinterpret_cast<int16_t*>(loopBackByteArray.data()),
numInputSamples, numLoopbackSamples,
_inputFormat, _outputFormat);
_loopbackOutputDevice->write(loopBackByteArray); _loopbackOutputDevice->write(loopBackByteArray);
} }
} }
@ -884,11 +898,6 @@ void AudioClient::processReceivedSamples(const QByteArray& inputBuffer, QByteArr
reinterpret_cast<int16_t*>(outputBuffer.data()), reinterpret_cast<int16_t*>(outputBuffer.data()),
numNetworkOutputSamples, numDeviceOutputSamples, numNetworkOutputSamples, numDeviceOutputSamples,
_desiredOutputFormat, _outputFormat); _desiredOutputFormat, _outputFormat);
if(_reverb || _receivedAudioStream.hasReverb()) {
updateGverbOptions();
addReverb(_gverb, (int16_t*)outputBuffer.data(), numDeviceOutputSamples, _outputFormat);
}
} }
void AudioClient::sendMuteEnvironmentPacket() { void AudioClient::sendMuteEnvironmentPacket() {

View file

@ -251,7 +251,7 @@ private:
ty_gverb* createGverbFilter(); ty_gverb* createGverbFilter();
void configureGverbFilter(ty_gverb* filter); void configureGverbFilter(ty_gverb* filter);
void updateGverbOptions(); void updateGverbOptions();
void addReverb(ty_gverb* gverb, int16_t* samples, int numSamples, QAudioFormat& format, bool noEcho = false); void addReverb(ty_gverb* gverb, int16_t* samples, int16_t* reverbAlone, int numSamples, QAudioFormat& format, bool noEcho = false);
void handleLocalEchoAndReverb(QByteArray& inputByteArray); void handleLocalEchoAndReverb(QByteArray& inputByteArray);