|
|
@ -57,6 +57,9 @@ OpenAL::OpenAL() |
|
|
|
, outputInitialized{false} |
|
|
|
, outputInitialized{false} |
|
|
|
, minInGain{-30} |
|
|
|
, minInGain{-30} |
|
|
|
, maxInGain{30} |
|
|
|
, maxInGain{30} |
|
|
|
|
|
|
|
, minInThreshold{0.0f} |
|
|
|
|
|
|
|
, maxInThreshold{0.4f} |
|
|
|
|
|
|
|
, isActive{false} |
|
|
|
{ |
|
|
|
{ |
|
|
|
// initialize OpenAL error stack
|
|
|
|
// initialize OpenAL error stack
|
|
|
|
alGetError(); |
|
|
|
alGetError(); |
|
|
@ -67,6 +70,10 @@ OpenAL::OpenAL() |
|
|
|
|
|
|
|
|
|
|
|
moveToThread(audioThread); |
|
|
|
moveToThread(audioThread); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
voiceTimer.setSingleShot(true); |
|
|
|
|
|
|
|
connect(this, &Audio::startActive, &voiceTimer, static_cast<void (QTimer::*)(int)>(&QTimer::start)); |
|
|
|
|
|
|
|
connect(&voiceTimer, &QTimer::timeout, this, &Audio::stopActive); |
|
|
|
|
|
|
|
|
|
|
|
connect(&captureTimer, &QTimer::timeout, this, &OpenAL::doCapture); |
|
|
|
connect(&captureTimer, &QTimer::timeout, this, &OpenAL::doCapture); |
|
|
|
captureTimer.setInterval(AUDIO_FRAME_DURATION / 2); |
|
|
|
captureTimer.setInterval(AUDIO_FRAME_DURATION / 2); |
|
|
|
captureTimer.setSingleShot(false); |
|
|
|
captureTimer.setSingleShot(false); |
|
|
@ -175,6 +182,50 @@ void OpenAL::setMaxInputGain(qreal dB) |
|
|
|
maxInGain = dB; |
|
|
|
maxInGain = dB; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief The minimum threshold value for an input device. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @return minimum threshold percentage |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
qreal OpenAL::minInputThreshold() const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QMutexLocker locker(&audioLock); |
|
|
|
|
|
|
|
return minInThreshold; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief Set the minimum allowed threshold percentage |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @note Default is 0%; usually you don't need to alter this value; |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void OpenAL::setMinInputThreshold(qreal percent) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QMutexLocker locker(&audioLock); |
|
|
|
|
|
|
|
minInThreshold = percent; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief The maximum threshold value for an input device. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @return maximum threshold percentage |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
qreal OpenAL::maxInputThreshold() const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QMutexLocker locker(&audioLock); |
|
|
|
|
|
|
|
return maxInThreshold; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief Set the maximum allowed threshold percentage |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @note Default is 40%; usually you don't need to alter this value. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void OpenAL::setMaxInputThreshold(qreal percent) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QMutexLocker locker(&audioLock); |
|
|
|
|
|
|
|
maxInThreshold = percent; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void OpenAL::reinitInput(const QString& inDevDesc) |
|
|
|
void OpenAL::reinitInput(const QString& inDevDesc) |
|
|
|
{ |
|
|
|
{ |
|
|
|
QMutexLocker locker(&audioLock); |
|
|
|
QMutexLocker locker(&audioLock); |
|
|
@ -278,6 +329,7 @@ bool OpenAL::initInput(const QString& deviceName, uint32_t channels) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
setInputGain(Settings::getInstance().getAudioInGainDecibel()); |
|
|
|
setInputGain(Settings::getInstance().getAudioInGainDecibel()); |
|
|
|
|
|
|
|
setInputThreshold(Settings::getInstance().getAudioThreshold()); |
|
|
|
|
|
|
|
|
|
|
|
qDebug() << "Opened audio input" << deviceName; |
|
|
|
qDebug() << "Opened audio input" << deviceName; |
|
|
|
alcCaptureStart(alInDev); |
|
|
|
alcCaptureStart(alInDev); |
|
|
@ -482,6 +534,36 @@ void OpenAL::playMono16SoundCleanup() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief Called by doCapture to calculate volume of the audio buffer |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param[in] buf the current audio buffer |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @return volume in percent of max volume |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
float OpenAL::getVolume(int16_t *buf) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
quint32 samples = AUDIO_FRAME_SAMPLE_COUNT * AUDIO_CHANNELS; |
|
|
|
|
|
|
|
float sum = 0.0; |
|
|
|
|
|
|
|
for (quint32 i = 0; i < samples; i++) { |
|
|
|
|
|
|
|
float sample = (float)buf[i] / (float)std::numeric_limits<int16_t>::max(); |
|
|
|
|
|
|
|
if (sample > 0) { |
|
|
|
|
|
|
|
sum += sample; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
sum -= sample; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return sum/samples; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief Called by voiceTimer's timeout to disable audio broadcasting |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void OpenAL::stopActive() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
isActive = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @brief Called on the captureTimer events to capture audio |
|
|
|
* @brief Called on the captureTimer events to capture audio |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -500,6 +582,19 @@ void OpenAL::doCapture() |
|
|
|
int16_t buf[AUDIO_FRAME_SAMPLE_COUNT * AUDIO_CHANNELS]; |
|
|
|
int16_t buf[AUDIO_FRAME_SAMPLE_COUNT * AUDIO_CHANNELS]; |
|
|
|
alcCaptureSamples(alInDev, buf, AUDIO_FRAME_SAMPLE_COUNT); |
|
|
|
alcCaptureSamples(alInDev, buf, AUDIO_FRAME_SAMPLE_COUNT); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float volume = getVolume(buf); |
|
|
|
|
|
|
|
if (volume >= inputThreshold) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
isActive = true; |
|
|
|
|
|
|
|
emit startActive(voiceHold); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emit Audio::volumeAvailable(volume); |
|
|
|
|
|
|
|
if (!isActive) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (quint32 i = 0; i < AUDIO_FRAME_SAMPLE_COUNT * AUDIO_CHANNELS; ++i) { |
|
|
|
for (quint32 i = 0; i < AUDIO_FRAME_SAMPLE_COUNT * AUDIO_CHANNELS; ++i) { |
|
|
|
// gain amplification with clipping to 16-bit boundaries
|
|
|
|
// gain amplification with clipping to 16-bit boundaries
|
|
|
|
int ampPCM = |
|
|
|
int ampPCM = |
|
|
@ -628,6 +723,11 @@ qreal OpenAL::inputGain() const |
|
|
|
return gain; |
|
|
|
return gain; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
qreal OpenAL::getInputThreshold() const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return inputThreshold; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
qreal OpenAL::inputGainFactor() const |
|
|
|
qreal OpenAL::inputGainFactor() const |
|
|
|
{ |
|
|
|
{ |
|
|
|
return gainFactor; |
|
|
|
return gainFactor; |
|
|
@ -638,3 +738,9 @@ void OpenAL::setInputGain(qreal dB) |
|
|
|
gain = qBound(minInGain, dB, maxInGain); |
|
|
|
gain = qBound(minInGain, dB, maxInGain); |
|
|
|
gainFactor = qPow(10.0, (gain / 20.0)); |
|
|
|
gainFactor = qPow(10.0, (gain / 20.0)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OpenAL::setInputThreshold(qreal percent) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
inputThreshold = percent; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|