mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
feat(audio): add real gain control of the input device
The gain can be set now in dB values, providing acceptable results for a wide range of setups. note: also introduces const-correctness and some minor cleanup.
This commit is contained in:
parent
9de833ad39
commit
f72baa613f
|
@ -27,6 +27,7 @@
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QtMath>
|
||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -35,6 +36,49 @@
|
||||||
#include "audiofilterer.h"
|
#include "audiofilterer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
@internal
|
||||||
|
|
||||||
|
@class Audio::Private
|
||||||
|
|
||||||
|
@brief Encapsulates private audio framework from public qTox Audio API.
|
||||||
|
*/
|
||||||
|
class Audio::Private
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Private()
|
||||||
|
: minInputGain{-30.0}
|
||||||
|
, maxInputGain{30.0}
|
||||||
|
, gain{0.0}
|
||||||
|
, gainFactor{0.0}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal inputGain() const
|
||||||
|
{
|
||||||
|
return gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal inputGainFactor() const
|
||||||
|
{
|
||||||
|
return gainFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setInputGain(qreal dB)
|
||||||
|
{
|
||||||
|
gain = qBound(minInputGain, dB, maxInputGain);
|
||||||
|
gainFactor = qPow(10.0, (gain / 20.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
qreal minInputGain;
|
||||||
|
qreal maxInputGain;
|
||||||
|
|
||||||
|
private:
|
||||||
|
qreal gain;
|
||||||
|
qreal gainFactor;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the singleton instance.
|
Returns the singleton instance.
|
||||||
*/
|
*/
|
||||||
|
@ -45,15 +89,15 @@ Audio& Audio::getInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
Audio::Audio()
|
Audio::Audio()
|
||||||
: audioThread(new QThread)
|
: d{new Private}
|
||||||
, alInDev(nullptr)
|
, audioThread{new QThread}
|
||||||
, inGain{1.f}
|
, alInDev{nullptr}
|
||||||
, inSubscriptions(0)
|
, inSubscriptions{0}
|
||||||
, alOutDev(nullptr)
|
, alOutDev{nullptr}
|
||||||
, alOutContext(nullptr)
|
, alOutContext{nullptr}
|
||||||
, alMainSource(0)
|
, alMainSource{0}
|
||||||
, alMainBuffer(0)
|
, alMainBuffer{0}
|
||||||
, outputInitialized(false)
|
, outputInitialized{false}
|
||||||
{
|
{
|
||||||
// initialize OpenAL error stack
|
// initialize OpenAL error stack
|
||||||
alGetError();
|
alGetError();
|
||||||
|
@ -87,6 +131,7 @@ Audio::~Audio()
|
||||||
#ifdef QTOX_FILTER_AUDIO
|
#ifdef QTOX_FILTER_AUDIO
|
||||||
filterer.closeFilter();
|
filterer.closeFilter();
|
||||||
#endif
|
#endif
|
||||||
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::checkAlError() noexcept
|
void Audio::checkAlError() noexcept
|
||||||
|
@ -106,13 +151,14 @@ void Audio::checkAlcError(ALCdevice *device) noexcept
|
||||||
/**
|
/**
|
||||||
Returns the current output volume (between 0 and 1)
|
Returns the current output volume (between 0 and 1)
|
||||||
*/
|
*/
|
||||||
ALfloat Audio::outputVolume()
|
qreal Audio::outputVolume() const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&audioLock);
|
QMutexLocker locker(&audioLock);
|
||||||
|
|
||||||
ALfloat volume = 0.0;
|
ALfloat volume = 0.0;
|
||||||
|
|
||||||
if (alOutDev) {
|
if (alOutDev)
|
||||||
|
{
|
||||||
alGetListenerf(AL_GAIN, &volume);
|
alGetListenerf(AL_GAIN, &volume);
|
||||||
checkAlError();
|
checkAlError();
|
||||||
}
|
}
|
||||||
|
@ -125,28 +171,78 @@ Set the master output volume.
|
||||||
|
|
||||||
@param[in] volume the master volume (between 0 and 1)
|
@param[in] volume the master volume (between 0 and 1)
|
||||||
*/
|
*/
|
||||||
void Audio::setOutputVolume(ALfloat volume)
|
void Audio::setOutputVolume(qreal volume)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&audioLock);
|
QMutexLocker locker(&audioLock);
|
||||||
|
|
||||||
volume = std::max(0.f, std::min(volume, 1.f));
|
volume = std::max(0.0, std::min(volume, 1.0));
|
||||||
|
|
||||||
alListenerf(AL_GAIN, volume);
|
alListenerf(AL_GAIN, static_cast<ALfloat>(volume));
|
||||||
checkAlError();
|
checkAlError();
|
||||||
}
|
}
|
||||||
|
|
||||||
ALfloat Audio::inputVolume()
|
/**
|
||||||
|
@brief The minimum gain value for an input device.
|
||||||
|
|
||||||
|
@return minimum gain value in dB
|
||||||
|
*/
|
||||||
|
qreal Audio::minInputGain() const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&audioLock);
|
QMutexLocker locker(&audioLock);
|
||||||
|
return d->minInputGain;
|
||||||
return inGain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::setInputVolume(ALfloat volume)
|
/**
|
||||||
|
@brief Set the minimum allowed gain value in dB.
|
||||||
|
|
||||||
|
@note Default is -30dB; usually you don't need to alter this value;
|
||||||
|
*/
|
||||||
|
void Audio::setMinInputGain(qreal dB)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&audioLock);
|
QMutexLocker locker(&audioLock);
|
||||||
|
d->minInputGain = dB;
|
||||||
|
}
|
||||||
|
|
||||||
inGain = std::max(0.f, std::min(volume, 1.f));
|
/**
|
||||||
|
@brief The maximum gain value for an input device.
|
||||||
|
|
||||||
|
@return maximum gain value in dB
|
||||||
|
*/
|
||||||
|
qreal Audio::maxInputGain() const
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&audioLock);
|
||||||
|
return d->maxInputGain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Set the maximum allowed gain value in dB.
|
||||||
|
|
||||||
|
@note Default is 30dB; usually you don't need to alter this value.
|
||||||
|
*/
|
||||||
|
void Audio::setMaxInputGain(qreal dB)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&audioLock);
|
||||||
|
d->maxInputGain = dB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The dB gain value.
|
||||||
|
|
||||||
|
@return the gain value in dB
|
||||||
|
*/
|
||||||
|
qreal Audio::inputGain() const
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&audioLock);
|
||||||
|
return d->inputGain();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the input gain dB level.
|
||||||
|
*/
|
||||||
|
void Audio::setInputGain(qreal dB)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&audioLock);
|
||||||
|
d->setInputGain(dB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::reinitInput(const QString& inDevDesc)
|
void Audio::reinitInput(const QString& inDevDesc)
|
||||||
|
@ -172,7 +268,8 @@ void Audio::subscribeInput()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&audioLock);
|
QMutexLocker locker(&audioLock);
|
||||||
|
|
||||||
if (!autoInitInput()) {
|
if (!autoInitInput())
|
||||||
|
{
|
||||||
qWarning("Failed to subscribe to audio input device.");
|
qWarning("Failed to subscribe to audio input device.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +332,8 @@ bool Audio::initInput(QString inDevDescr)
|
||||||
const uint16_t frameDuration = AUDIO_FRAME_DURATION;
|
const uint16_t frameDuration = AUDIO_FRAME_DURATION;
|
||||||
const uint32_t chnls = AUDIO_CHANNELS;
|
const uint32_t chnls = AUDIO_CHANNELS;
|
||||||
const ALCsizei bufSize = (frameDuration * sampleRate * 4) / 1000 * chnls;
|
const ALCsizei bufSize = (frameDuration * sampleRate * 4) / 1000 * chnls;
|
||||||
if (inDevDescr.isEmpty()) {
|
if (inDevDescr.isEmpty())
|
||||||
|
{
|
||||||
const ALchar *pDeviceList = Audio::inDeviceNames();
|
const ALchar *pDeviceList = Audio::inDeviceNames();
|
||||||
if (pDeviceList)
|
if (pDeviceList)
|
||||||
inDevDescr = QString::fromUtf8(pDeviceList, strlen(pDeviceList));
|
inDevDescr = QString::fromUtf8(pDeviceList, strlen(pDeviceList));
|
||||||
|
@ -246,11 +344,14 @@ bool Audio::initInput(QString inDevDescr)
|
||||||
sampleRate, stereoFlag, bufSize);
|
sampleRate, stereoFlag, bufSize);
|
||||||
|
|
||||||
// Restart the capture if necessary
|
// Restart the capture if necessary
|
||||||
if (!alInDev) {
|
if (!alInDev)
|
||||||
|
{
|
||||||
qWarning() << "Failed to initialize audio input device:" << inDevDescr;
|
qWarning() << "Failed to initialize audio input device:" << inDevDescr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d->setInputGain(Settings::getInstance().getAudioInGain());
|
||||||
|
|
||||||
qDebug() << "Opened audio input" << inDevDescr;
|
qDebug() << "Opened audio input" << inDevDescr;
|
||||||
alcCaptureStart(alInDev);
|
alcCaptureStart(alInDev);
|
||||||
|
|
||||||
|
@ -273,7 +374,8 @@ bool Audio::initOutput(QString outDevDescr)
|
||||||
|
|
||||||
assert(!alOutDev);
|
assert(!alOutDev);
|
||||||
|
|
||||||
if (outDevDescr.isEmpty()) {
|
if (outDevDescr.isEmpty())
|
||||||
|
{
|
||||||
// default to the first available audio device.
|
// default to the first available audio device.
|
||||||
const ALchar *pDeviceList = Audio::outDeviceNames();
|
const ALchar *pDeviceList = Audio::outDeviceNames();
|
||||||
if (pDeviceList)
|
if (pDeviceList)
|
||||||
|
@ -293,7 +395,8 @@ bool Audio::initOutput(QString outDevDescr)
|
||||||
alOutContext = alcCreateContext(alOutDev, nullptr);
|
alOutContext = alcCreateContext(alOutDev, nullptr);
|
||||||
checkAlcError(alOutDev);
|
checkAlcError(alOutDev);
|
||||||
|
|
||||||
if (!alcMakeContextCurrent(alOutContext)) {
|
if (!alcMakeContextCurrent(alOutContext))
|
||||||
|
{
|
||||||
qWarning() << "Cannot create output audio context";
|
qWarning() << "Cannot create output audio context";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +409,8 @@ bool Audio::initOutput(QString outDevDescr)
|
||||||
checkAlError();
|
checkAlError();
|
||||||
|
|
||||||
Core* core = Core::getInstance();
|
Core* core = Core::getInstance();
|
||||||
if (core) {
|
if (core)
|
||||||
|
{
|
||||||
// reset each call's audio source
|
// reset each call's audio source
|
||||||
core->getAv()->invalidateCallSources();
|
core->getAv()->invalidateCallSources();
|
||||||
}
|
}
|
||||||
|
@ -421,7 +525,8 @@ void Audio::cleanupOutput()
|
||||||
{
|
{
|
||||||
outputInitialized = false;
|
outputInitialized = false;
|
||||||
|
|
||||||
if (alOutDev) {
|
if (alOutDev)
|
||||||
|
{
|
||||||
alSourcei(alMainSource, AL_LOOPING, AL_FALSE);
|
alSourcei(alMainSource, AL_LOOPING, AL_FALSE);
|
||||||
alSourceStop(alMainSource);
|
alSourceStop(alMainSource);
|
||||||
alDeleteSources(1, &alMainSource);
|
alDeleteSources(1, &alMainSource);
|
||||||
|
@ -486,8 +591,15 @@ void Audio::doCapture()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (size_t i = 0; i < AUDIO_FRAME_SAMPLE_COUNT * AUDIO_CHANNELS; ++i)
|
for (quint32 i = 0; i < AUDIO_FRAME_SAMPLE_COUNT * AUDIO_CHANNELS; ++i)
|
||||||
buf[i] *= inGain;
|
{
|
||||||
|
// gain amplification with clipping to 16-bit boundaries
|
||||||
|
int ampPCM = qBound<int>(std::numeric_limits<int16_t>::min(),
|
||||||
|
qRound(buf[i] * d->inputGainFactor()),
|
||||||
|
std::numeric_limits<int16_t>::max());
|
||||||
|
|
||||||
|
buf[i] = static_cast<int16_t>(ampPCM);
|
||||||
|
}
|
||||||
|
|
||||||
emit frameAvailable(buf, AUDIO_FRAME_SAMPLE_COUNT, AUDIO_CHANNELS, AUDIO_SAMPLE_RATE);
|
emit frameAvailable(buf, AUDIO_FRAME_SAMPLE_COUNT, AUDIO_CHANNELS, AUDIO_SAMPLE_RATE);
|
||||||
}
|
}
|
||||||
|
@ -495,7 +607,7 @@ void Audio::doCapture()
|
||||||
/**
|
/**
|
||||||
Returns true if the input device is open and suscribed to
|
Returns true if the input device is open and suscribed to
|
||||||
*/
|
*/
|
||||||
bool Audio::isInputReady()
|
bool Audio::isInputReady() const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&audioLock);
|
QMutexLocker locker(&audioLock);
|
||||||
return alInDev && inSubscriptions;
|
return alInDev && inSubscriptions;
|
||||||
|
@ -504,7 +616,7 @@ bool Audio::isInputReady()
|
||||||
/**
|
/**
|
||||||
Returns true if the output device is open
|
Returns true if the output device is open
|
||||||
*/
|
*/
|
||||||
bool Audio::isOutputReady()
|
bool Audio::isOutputReady() const
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&audioLock);
|
QMutexLocker locker(&audioLock);
|
||||||
return alOutDev && outputInitialized;
|
return alOutDev && outputInitialized;
|
||||||
|
@ -530,12 +642,14 @@ void Audio::subscribeOutput(ALuint& sid)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&audioLock);
|
QMutexLocker locker(&audioLock);
|
||||||
|
|
||||||
if (!autoInitOutput()) {
|
if (!autoInitOutput())
|
||||||
|
{
|
||||||
qWarning("Failed to subscribe to audio output device.");
|
qWarning("Failed to subscribe to audio output device.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!alcMakeContextCurrent(alOutContext)) {
|
if (!alcMakeContextCurrent(alOutContext))
|
||||||
|
{
|
||||||
qWarning("Failed to activate output context.");
|
qWarning("Failed to activate output context.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -554,8 +668,10 @@ void Audio::unsubscribeOutput(ALuint &sid)
|
||||||
|
|
||||||
outSources.removeAll(sid);
|
outSources.removeAll(sid);
|
||||||
|
|
||||||
if (sid) {
|
if (sid)
|
||||||
if (alIsSource(sid)) {
|
{
|
||||||
|
if (alIsSource(sid))
|
||||||
|
{
|
||||||
alDeleteSources(1, &sid);
|
alDeleteSources(1, &sid);
|
||||||
qDebug() << "Audio source" << sid << "deleted. Sources active:"
|
qDebug() << "Audio source" << sid << "deleted. Sources active:"
|
||||||
<< outSources.size();
|
<< outSources.size();
|
||||||
|
|
|
@ -56,20 +56,26 @@ class Audio : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
class Private;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Audio& getInstance();
|
static Audio& getInstance();
|
||||||
|
|
||||||
ALfloat outputVolume();
|
qreal outputVolume() const;
|
||||||
void setOutputVolume(ALfloat volume);
|
void setOutputVolume(qreal volume);
|
||||||
|
|
||||||
ALfloat inputVolume();
|
qreal minInputGain() const;
|
||||||
void setInputVolume(ALfloat volume);
|
void setMinInputGain(qreal dB);
|
||||||
|
qreal maxInputGain() const;
|
||||||
|
void setMaxInputGain(qreal dB);
|
||||||
|
qreal inputGain() const;
|
||||||
|
void setInputGain(qreal dB);
|
||||||
|
|
||||||
void reinitInput(const QString& inDevDesc);
|
void reinitInput(const QString& inDevDesc);
|
||||||
bool reinitOutput(const QString& outDevDesc);
|
bool reinitOutput(const QString& outDevDesc);
|
||||||
|
|
||||||
bool isInputReady();
|
bool isInputReady() const;
|
||||||
bool isOutputReady();
|
bool isOutputReady() const;
|
||||||
|
|
||||||
static const char* outDeviceNames();
|
static const char* outDeviceNames();
|
||||||
static const char* inDeviceNames();
|
static const char* inDeviceNames();
|
||||||
|
@ -113,12 +119,14 @@ private:
|
||||||
void getEchoesToFilter(AudioFilterer* filter, int samples);
|
void getEchoesToFilter(AudioFilterer* filter, int samples);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
Private* d;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QThread* audioThread;
|
QThread* audioThread;
|
||||||
QMutex audioLock;
|
mutable QMutex audioLock;
|
||||||
|
|
||||||
ALCdevice* alInDev;
|
ALCdevice* alInDev;
|
||||||
ALfloat inGain;
|
|
||||||
quint32 inSubscriptions;
|
quint32 inSubscriptions;
|
||||||
QTimer captureTimer, playMono16Timer;
|
QTimer captureTimer, playMono16Timer;
|
||||||
|
|
||||||
|
|
|
@ -236,7 +236,7 @@ void Settings::loadGlobal()
|
||||||
s.beginGroup("Audio");
|
s.beginGroup("Audio");
|
||||||
inDev = s.value("inDev", "").toString();
|
inDev = s.value("inDev", "").toString();
|
||||||
outDev = s.value("outDev", "").toString();
|
outDev = s.value("outDev", "").toString();
|
||||||
inVolume = s.value("inVolume", 100).toInt();
|
audioInGainDecibel = s.value("inGain", 0).toReal();
|
||||||
outVolume = s.value("outVolume", 100).toInt();
|
outVolume = s.value("outVolume", 100).toInt();
|
||||||
filterAudio = s.value("filterAudio", false).toBool();
|
filterAudio = s.value("filterAudio", false).toBool();
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
@ -467,7 +467,7 @@ void Settings::saveGlobal()
|
||||||
s.beginGroup("Audio");
|
s.beginGroup("Audio");
|
||||||
s.setValue("inDev", inDev);
|
s.setValue("inDev", inDev);
|
||||||
s.setValue("outDev", outDev);
|
s.setValue("outDev", outDev);
|
||||||
s.setValue("inVolume", inVolume);
|
s.setValue("inGain", audioInGainDecibel);
|
||||||
s.setValue("outVolume", outVolume);
|
s.setValue("outVolume", outVolume);
|
||||||
s.setValue("filterAudio", filterAudio);
|
s.setValue("filterAudio", filterAudio);
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
@ -1366,16 +1366,16 @@ void Settings::setInDev(const QString& deviceSpecifier)
|
||||||
inDev = deviceSpecifier;
|
inDev = deviceSpecifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Settings::getInVolume() const
|
qreal Settings::getAudioInGain() const
|
||||||
{
|
{
|
||||||
QMutexLocker locker{&bigLock};
|
QMutexLocker locker{&bigLock};
|
||||||
return inVolume;
|
return audioInGainDecibel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::setInVolume(int volume)
|
void Settings::setAudioInGain(qreal dB)
|
||||||
{
|
{
|
||||||
QMutexLocker locker{&bigLock};
|
QMutexLocker locker{&bigLock};
|
||||||
inVolume = volume;
|
audioInGainDecibel = dB;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Settings::getVideoDev() const
|
QString Settings::getVideoDev() const
|
||||||
|
|
|
@ -181,8 +181,8 @@ public:
|
||||||
QString getOutDev() const;
|
QString getOutDev() const;
|
||||||
void setOutDev(const QString& deviceSpecifier);
|
void setOutDev(const QString& deviceSpecifier);
|
||||||
|
|
||||||
int getInVolume() const;
|
qreal getAudioInGain() const;
|
||||||
void setInVolume(int volume);
|
void setAudioInGain(qreal dB);
|
||||||
|
|
||||||
int getOutVolume() const;
|
int getOutVolume() const;
|
||||||
void setOutVolume(int volume);
|
void setOutVolume(int volume);
|
||||||
|
@ -432,7 +432,7 @@ private:
|
||||||
// Audio
|
// Audio
|
||||||
QString inDev;
|
QString inDev;
|
||||||
QString outDev;
|
QString outDev;
|
||||||
int inVolume;
|
qreal audioInGainDecibel;
|
||||||
int outVolume;
|
int outVolume;
|
||||||
bool filterAudio;
|
bool filterAudio;
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,8 @@ AVForm::AVForm() :
|
||||||
bodyUI = new Ui::AVSettings;
|
bodyUI = new Ui::AVSettings;
|
||||||
bodyUI->setupUi(this);
|
bodyUI->setupUi(this);
|
||||||
|
|
||||||
|
const Audio& audio = Audio::getInstance();
|
||||||
|
|
||||||
bodyUI->btnPlayTestSound->setToolTip(
|
bodyUI->btnPlayTestSound->setToolTip(
|
||||||
tr("Play a test sound while changing the output volume."));
|
tr("Play a test sound while changing the output volume."));
|
||||||
|
|
||||||
|
@ -65,6 +67,14 @@ AVForm::AVForm() :
|
||||||
bodyUI->playbackSlider->installEventFilter(this);
|
bodyUI->playbackSlider->installEventFilter(this);
|
||||||
connect(bodyUI->playbackSlider, &QSlider::valueChanged,
|
connect(bodyUI->playbackSlider, &QSlider::valueChanged,
|
||||||
this, &AVForm::onPlaybackValueChanged);
|
this, &AVForm::onPlaybackValueChanged);
|
||||||
|
|
||||||
|
bodyUI->microphoneSlider->setToolTip(
|
||||||
|
tr("Use slider to set the gain of your input device ranging"
|
||||||
|
" from %1dB to %2dB.")
|
||||||
|
.arg(audio.minInputGain())
|
||||||
|
.arg(audio.maxInputGain()));
|
||||||
|
bodyUI->microphoneSlider->setMinimum(qRound(audio.minInputGain()) * 10);
|
||||||
|
bodyUI->microphoneSlider->setMaximum(qRound(audio.maxInputGain()) * 10);
|
||||||
bodyUI->microphoneSlider->setTracking(false);
|
bodyUI->microphoneSlider->setTracking(false);
|
||||||
bodyUI->microphoneSlider->installEventFilter(this);
|
bodyUI->microphoneSlider->installEventFilter(this);
|
||||||
connect(bodyUI->microphoneSlider, &QSlider::valueChanged,
|
connect(bodyUI->microphoneSlider, &QSlider::valueChanged,
|
||||||
|
@ -378,7 +388,7 @@ void AVForm::onInDevChanged(QString deviceDescriptor)
|
||||||
Audio& audio = Audio::getInstance();
|
Audio& audio = Audio::getInstance();
|
||||||
audio.reinitInput(deviceDescriptor);
|
audio.reinitInput(deviceDescriptor);
|
||||||
bodyUI->microphoneSlider->setEnabled(bodyUI->inDevCombobox->currentIndex() != 0);
|
bodyUI->microphoneSlider->setEnabled(bodyUI->inDevCombobox->currentIndex() != 0);
|
||||||
bodyUI->microphoneSlider->setSliderPosition(audio.inputVolume() * 100.f);
|
bodyUI->microphoneSlider->setSliderPosition(qRound(audio.inputGain() * 10.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AVForm::onOutDevChanged(QString deviceDescriptor)
|
void AVForm::onOutDevChanged(QString deviceDescriptor)
|
||||||
|
@ -390,7 +400,7 @@ void AVForm::onOutDevChanged(QString deviceDescriptor)
|
||||||
Audio& audio = Audio::getInstance();
|
Audio& audio = Audio::getInstance();
|
||||||
audio.reinitOutput(deviceDescriptor);
|
audio.reinitOutput(deviceDescriptor);
|
||||||
bodyUI->playbackSlider->setEnabled(audio.isOutputReady());
|
bodyUI->playbackSlider->setEnabled(audio.isOutputReady());
|
||||||
bodyUI->playbackSlider->setSliderPosition(audio.outputVolume() * 100.f);
|
bodyUI->playbackSlider->setSliderPosition(qRound(audio.outputVolume() * 100.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AVForm::onFilterAudioToggled(bool filterAudio)
|
void AVForm::onFilterAudioToggled(bool filterAudio)
|
||||||
|
@ -414,10 +424,10 @@ void AVForm::onPlaybackValueChanged(int value)
|
||||||
|
|
||||||
void AVForm::onMicrophoneValueChanged(int value)
|
void AVForm::onMicrophoneValueChanged(int value)
|
||||||
{
|
{
|
||||||
Settings::getInstance().setInVolume(value);
|
const qreal dB = value / 10.0;
|
||||||
|
|
||||||
const qreal percentage = value / 100.0;
|
Settings::getInstance().setAudioInGain(dB);
|
||||||
Audio::getInstance().setInputVolume(percentage);
|
Audio::getInstance().setInputGain(dB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AVForm::createVideoSurface()
|
void AVForm::createVideoSurface()
|
||||||
|
|
|
@ -46,12 +46,6 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1" colspan="2">
|
<item row="3" column="1" colspan="2">
|
||||||
<widget class="QSlider" name="microphoneSlider">
|
<widget class="QSlider" name="microphoneSlider">
|
||||||
<property name="toolTip">
|
|
||||||
<string>Use slider to set volume of your microphone.</string>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user