mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-31 12:55:33 +08:00
* authentication issues in AFV were silently handled * and there was no re-try, which could mean an initial glitch COULD cause AFV not working properly * NOW handling in AFV client and context * also reset connection data so for a new session no old authentication token or check time is used * check for "invalid" QDateTime(s)
534 lines
23 KiB
C++
534 lines
23 KiB
C++
/* Copyright (C) 2019
|
|
* swift project Community / Contributors
|
|
*
|
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
|
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
|
|
* or distributed except according to the terms contained in the LICENSE file.
|
|
*/
|
|
|
|
#include "blackgui/components/audiodevicevolumesetupcomponent.h"
|
|
#include "blackgui/guiapplication.h"
|
|
#include "blackgui/guiutility.h"
|
|
#include "blackcore/afv/clients/afvclient.h"
|
|
#include "blackcore/context/contextsimulator.h"
|
|
#include "blackcore/context/contextaudioimpl.h"
|
|
|
|
#include "blackmisc/simulation/settings/simulatorsettings.h"
|
|
#include "blackmisc/audio/audiodeviceinfo.h"
|
|
#include "blackmisc/audio/notificationsounds.h"
|
|
#include "blackmisc/audio/audiosettings.h"
|
|
#include "blackmisc/sequence.h"
|
|
#include "ui_audiodevicevolumesetupcomponent.h"
|
|
|
|
#include <QCheckBox>
|
|
#include <QComboBox>
|
|
#include <QToolButton>
|
|
#include <QtGlobal>
|
|
#include <QPointer>
|
|
#include <QFileDialog>
|
|
#include <QStringLiteral>
|
|
|
|
using namespace BlackCore;
|
|
using namespace BlackCore::Afv::Audio;
|
|
using namespace BlackCore::Afv::Clients;
|
|
using namespace BlackCore::Context;
|
|
using namespace BlackMisc;
|
|
using namespace BlackMisc::Aviation;
|
|
using namespace BlackMisc::Audio;
|
|
using namespace BlackMisc::PhysicalQuantities;
|
|
using namespace BlackMisc::Simulation;
|
|
|
|
namespace BlackGui
|
|
{
|
|
namespace Components
|
|
{
|
|
CAudioDeviceVolumeSetupComponent::CAudioDeviceVolumeSetupComponent(QWidget *parent) :
|
|
QFrame(parent),
|
|
ui(new Ui::CAudioDeviceVolumeSetupComponent)
|
|
{
|
|
ui->setupUi(this);
|
|
connect(ui->hs_VolumeIn, &QSlider::valueChanged, this, &CAudioDeviceVolumeSetupComponent::onVolumeSliderChanged);
|
|
connect(ui->hs_VolumeOut, &QSlider::valueChanged, this, &CAudioDeviceVolumeSetupComponent::onVolumeSliderChanged);
|
|
connect(ui->tb_RefreshInDevice, &QToolButton::released, this, &CAudioDeviceVolumeSetupComponent::onReloadDevices, Qt::QueuedConnection);
|
|
connect(ui->tb_RefreshOutDevice, &QToolButton::released, this, &CAudioDeviceVolumeSetupComponent::onReloadDevices, Qt::QueuedConnection);
|
|
connect(ui->tb_ResetInVolume, &QToolButton::released, this, &CAudioDeviceVolumeSetupComponent::onResetVolumeIn, Qt::QueuedConnection);
|
|
connect(ui->tb_ResetOutVolume, &QToolButton::released, this, &CAudioDeviceVolumeSetupComponent::onResetVolumeOut, Qt::QueuedConnection);
|
|
|
|
connect(ui->cb_1Tx, &QCheckBox::toggled, this, &CAudioDeviceVolumeSetupComponent::onRxTxChanged, Qt::QueuedConnection);
|
|
connect(ui->cb_2Tx, &QCheckBox::toggled, this, &CAudioDeviceVolumeSetupComponent::onRxTxChanged, Qt::QueuedConnection);
|
|
connect(ui->cb_1Rec, &QCheckBox::toggled, this, &CAudioDeviceVolumeSetupComponent::onRxTxChanged, Qt::QueuedConnection);
|
|
connect(ui->cb_2Rec, &QCheckBox::toggled, this, &CAudioDeviceVolumeSetupComponent::onRxTxChanged, Qt::QueuedConnection);
|
|
connect(ui->cb_IntegratedWithCom, &QCheckBox::toggled, this, &CAudioDeviceVolumeSetupComponent::onIntegratedFlagChanged, Qt::QueuedConnection);
|
|
|
|
ui->hs_VolumeIn->setMaximum(CSettings::InMax);
|
|
ui->hs_VolumeIn->setMinimum(CSettings::InMin);
|
|
ui->hs_VolumeOut->setMaximum(CSettings::OutMax);
|
|
ui->hs_VolumeOut->setMinimum(CSettings::OutMin);
|
|
|
|
const CSettings as(m_audioSettings.getThreadLocal());
|
|
const int i = this->getInValue();
|
|
const int o = this->getOutValue();
|
|
ui->hs_VolumeIn->setValue(i);
|
|
ui->hs_VolumeOut->setValue(o);
|
|
ui->cb_SetupAudioLoopback->setChecked(false);
|
|
ui->cb_DisableAudioEffects->setChecked(!as.isAudioEffectsEnabled());
|
|
|
|
ui->led_AudioConnected->setToolTips("Voice on and authenticated", "Voice off");
|
|
ui->led_AudioConnected->setShape(CLedWidget::Rounded);
|
|
ui->led_Rx1->setToolTips("COM1 receiving", "COM1 idle");
|
|
ui->led_Rx1->setShape(CLedWidget::Rounded);
|
|
ui->led_Rx2->setToolTips("COM2 receiving", "COM2 idle");
|
|
ui->led_Rx2->setShape(CLedWidget::Rounded);
|
|
|
|
// deferred init, because in a distributed swift system
|
|
// it takes a moment until the settings are sychronized
|
|
// this is leading to undesired "save settings" messages and played sounds
|
|
QPointer<CAudioDeviceVolumeSetupComponent> myself(this);
|
|
QTimer::singleShot(2000, this, [ = ]
|
|
{
|
|
if (!myself || !sGui || sGui->isShuttingDown()) { return; }
|
|
this->init();
|
|
});
|
|
|
|
this->setCheckBoxesReadOnly(this->isComIntegrated());
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::init()
|
|
{
|
|
if (!sGui || sGui->isShuttingDown() || !sGui->getCContextAudioBase()) { return; }
|
|
|
|
// audio is optional
|
|
const bool audio = this->hasAudio();
|
|
this->setEnabled(audio);
|
|
this->reloadSettings();
|
|
|
|
bool c = connect(ui->cb_SetupAudioLoopback, &QCheckBox::toggled, this, &CAudioDeviceVolumeSetupComponent::onLoopbackToggled);
|
|
Q_ASSERT(c);
|
|
c = connect(ui->cb_DisableAudioEffects, &QCheckBox::toggled, this, &CAudioDeviceVolumeSetupComponent::onDisableAudioEffectsToggled);
|
|
Q_ASSERT(c);
|
|
|
|
if (audio)
|
|
{
|
|
this->setAudioRunsWhere();
|
|
this->initAudioDeviceLists();
|
|
|
|
// default
|
|
ui->cb_SetupAudioLoopback->setChecked(sGui->getCContextAudioBase()->isAudioLoopbackEnabled());
|
|
|
|
// the connects depend on initAudioDeviceLists
|
|
c = connect(ui->cb_SetupAudioInputDevice, qOverload<int>(&QComboBox::currentIndexChanged), this, &CAudioDeviceVolumeSetupComponent::onAudioDeviceSelected, Qt::QueuedConnection);
|
|
Q_ASSERT(c);
|
|
c = connect(ui->cb_SetupAudioOutputDevice, qOverload<int>(&QComboBox::currentIndexChanged), this, &CAudioDeviceVolumeSetupComponent::onAudioDeviceSelected, Qt::QueuedConnection);
|
|
Q_ASSERT(c);
|
|
|
|
// context
|
|
c = connect(sGui->getCContextAudioBase(), &CContextAudioBase::changedLocalAudioDevices, this, &CAudioDeviceVolumeSetupComponent::onAudioDevicesChanged, Qt::QueuedConnection);
|
|
Q_ASSERT(c);
|
|
c = connect(sGui->getCContextAudioBase(), &CContextAudioBase::startedAudio, this, &CAudioDeviceVolumeSetupComponent::onAudioStarted, Qt::QueuedConnection);
|
|
Q_ASSERT(c);
|
|
c = connect(sGui->getCContextAudioBase(), &CContextAudioBase::stoppedAudio, this, &CAudioDeviceVolumeSetupComponent::onAudioStopped, Qt::QueuedConnection);
|
|
Q_ASSERT(c);
|
|
|
|
this->initWithAfvClient();
|
|
m_init = true;
|
|
}
|
|
Q_UNUSED(c)
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::initWithAfvClient()
|
|
{
|
|
if (!afvClient()) { return; }
|
|
m_afvConnections.disconnectAll();
|
|
|
|
//! \todo Workaround to avoid context signals
|
|
CAfvClient *afv = afvClient();
|
|
const Qt::ConnectionType ct = Qt::QueuedConnection;
|
|
QMetaObject::Connection c;
|
|
c = connect(afv, &CAfvClient::outputVolumePeakVU, this, &CAudioDeviceVolumeSetupComponent::onOutputVU, ct);
|
|
Q_ASSERT(c);
|
|
m_afvConnections.append(c);
|
|
c = connect(afv, &CAfvClient::inputVolumePeakVU, this, &CAudioDeviceVolumeSetupComponent::onInputVU, ct);
|
|
Q_ASSERT(c);
|
|
m_afvConnections.append(c);
|
|
c = connect(afv, &CAfvClient::receivedCallsignsChanged, this, &CAudioDeviceVolumeSetupComponent::onReceivingCallsignsChanged, ct);
|
|
Q_ASSERT(c);
|
|
m_afvConnections.append(c);
|
|
c = connect(afv, &CAfvClient::updatedFromOwnAircraftCockpit, this, &CAudioDeviceVolumeSetupComponent::onUpdatedClientWithCockpitData, ct);
|
|
Q_ASSERT(c);
|
|
m_afvConnections.append(c);
|
|
|
|
// default values for RX/TX
|
|
afv->setRxTx(true, true, true, false);
|
|
|
|
QPointer<CAudioDeviceVolumeSetupComponent> myself(this);
|
|
c = connect(afv, &CAfvClient::connectionStatusChanged, this, [ = ](CAfvClient::ConnectionStatus status)
|
|
{
|
|
if (!myself || !sGui || sGui->isShuttingDown()) { return; }
|
|
myself->setTransmitReceiveInUiFromVoiceClient();
|
|
Q_UNUSED(status)
|
|
}, ct);
|
|
Q_ASSERT(c);
|
|
m_afvConnections.append(c);
|
|
|
|
this->setTransmitReceiveInUiFromVoiceClient();
|
|
}
|
|
|
|
CAudioDeviceVolumeSetupComponent::~CAudioDeviceVolumeSetupComponent()
|
|
{ }
|
|
|
|
int CAudioDeviceVolumeSetupComponent::getInValue(int from, int to) const
|
|
{
|
|
const double r = ui->hs_VolumeIn->maximum() - ui->hs_VolumeIn->minimum();
|
|
const double tr = to - from;
|
|
return qRound(ui->hs_VolumeIn->value() / r * tr);
|
|
}
|
|
|
|
int CAudioDeviceVolumeSetupComponent::getOutValue(int from, int to) const
|
|
{
|
|
const double r = ui->hs_VolumeOut->maximum() - ui->hs_VolumeOut->minimum();
|
|
const double tr = to - from;
|
|
return qRound(ui->hs_VolumeOut->value() / r * tr);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setInValue(int value, int from, int to)
|
|
{
|
|
if (value > to) { value = to; }
|
|
else if (value < from) { value = from; }
|
|
const double r = ui->hs_VolumeIn->maximum() - ui->hs_VolumeIn->minimum();
|
|
const double tr = to - from;
|
|
ui->hs_VolumeIn->setValue(qRound(value / tr * r));
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setOutValue(int value, int from, int to)
|
|
{
|
|
if (value > to) { value = to; }
|
|
else if (value < from) { value = from; }
|
|
const double r = ui->hs_VolumeOut->maximum() - ui->hs_VolumeOut->minimum();
|
|
const double tr = to - from;
|
|
ui->hs_VolumeOut->setValue(qRound(value / tr * r));
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setInLevel(double value)
|
|
{
|
|
if (value > 1.0) { value = 1.0; }
|
|
else if (value < 0.0) { value = 0.0; }
|
|
ui->wip_InLevelMeter->levelChanged(value);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setOutLevel(double value)
|
|
{
|
|
if (value > 1.0) { value = 1.0; }
|
|
else if (value < 0.0) { value = 0.0; }
|
|
ui->wip_OutLevelMeter->levelChanged(value);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setInfo(const QString &info)
|
|
{
|
|
ui->le_Info->setText(info);
|
|
ui->le_Info->setToolTip(info);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setTransmitReceiveInUi(bool tx1, bool rec1, bool tx2, bool rec2, bool integrated)
|
|
{
|
|
this->setRxTxCheckboxes(rec1, tx1, rec2, tx2);
|
|
ui->cb_IntegratedWithCom->setChecked(integrated);
|
|
this->setCheckBoxesReadOnly(integrated);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setTransmitReceiveInUiFromVoiceClient()
|
|
{
|
|
if (!this->hasAudio())
|
|
{
|
|
ui->led_AudioConnected->setOn(false);
|
|
return;
|
|
}
|
|
|
|
const bool on = sGui->getCContextAudioBase()->isAudioConnected();
|
|
ui->led_AudioConnected->setOn(on);
|
|
|
|
const bool com1Enabled = sGui->getCContextAudioBase()->isEnabledComUnit(CComSystem::Com1);
|
|
const bool com2Enabled = sGui->getCContextAudioBase()->isEnabledComUnit(CComSystem::Com2);
|
|
|
|
const bool com1Tx = com1Enabled && sGui->getCContextAudioBase()->isTransmittingComUnit(CComSystem::Com1);
|
|
const bool com2Tx = com2Enabled && sGui->getCContextAudioBase()->isTransmittingComUnit(CComSystem::Com2);
|
|
|
|
// we do not have receiving, so we use enable
|
|
const bool com1Rx = com1Enabled;
|
|
const bool com2Rx = com2Enabled;
|
|
|
|
const bool integrated = this->isComIntegrated();
|
|
this->setTransmitReceiveInUi(com1Tx, com1Rx, com2Tx, com2Rx, integrated);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setCheckBoxesReadOnly(bool readonly)
|
|
{
|
|
// all tx/rec checkboxes
|
|
CGuiUtility::checkBoxReadOnly(ui->cb_1Tx, readonly);
|
|
CGuiUtility::checkBoxReadOnly(ui->cb_2Tx, readonly);
|
|
CGuiUtility::checkBoxReadOnly(ui->cb_1Rec, readonly);
|
|
CGuiUtility::checkBoxReadOnly(ui->cb_2Rec, readonly);
|
|
}
|
|
|
|
CAfvClient *CAudioDeviceVolumeSetupComponent::afvClient()
|
|
{
|
|
if (!sGui || sGui->isShuttingDown() || !sGui->getCContextAudioBase()) { return nullptr; }
|
|
return sGui->getCContextAudioBase()->afvClient();
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::reloadSettings()
|
|
{
|
|
const CSettings as(m_audioSettings.getThreadLocal());
|
|
ui->cb_DisableAudioEffects->setChecked(!as.isAudioEffectsEnabled());
|
|
this->setInValue(as.getInVolume());
|
|
this->setOutValue(as.getOutVolume());
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::initAudioDeviceLists()
|
|
{
|
|
if (!this->hasAudio()) { return; }
|
|
const bool changed = this->onAudioDevicesChanged(sGui->getCContextAudioBase()->getAudioDevicesPlusDefault());
|
|
if (!changed) { return; }
|
|
const CAudioDeviceInfoList currentDevices = sGui->getCContextAudioBase()->getCurrentAudioDevices();
|
|
this->onAudioStarted(currentDevices.getInputDevices().frontOrDefault(), currentDevices.getOutputDevices().frontOrDefault());
|
|
}
|
|
|
|
bool CAudioDeviceVolumeSetupComponent::hasAudio() const
|
|
{
|
|
return sGui && sGui->getCContextAudioBase();
|
|
}
|
|
|
|
bool CAudioDeviceVolumeSetupComponent::hasSimulator() const
|
|
{
|
|
return sGui && sGui->getIContextSimulator();
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onVolumeSliderChanged(int v)
|
|
{
|
|
Q_UNUSED(v)
|
|
m_volumeSliderChanged.inputSignal();
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::saveVolumes()
|
|
{
|
|
CSettings as(m_audioSettings.getThreadLocal());
|
|
const int i = this->getInValue();
|
|
const int o = this->getOutValue();
|
|
if (as.getInVolume() == i && as.getOutVolume() == o) { return; }
|
|
as.setInVolume(i);
|
|
as.setOutVolume(o);
|
|
m_audioSettings.setAndSave(as);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onOutputVU(double vu)
|
|
{
|
|
this->setOutLevel(vu);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onInputVU(double vu)
|
|
{
|
|
this->setInLevel(vu);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onReloadDevices()
|
|
{
|
|
if (!hasAudio()) { return; }
|
|
this->initAudioDeviceLists();
|
|
const CAudioDeviceInfo i = this->getSelectedInputDevice();
|
|
const CAudioDeviceInfo o = this->getSelectedOutputDevice();
|
|
sGui->getCContextAudioBase()->setCurrentAudioDevices(i, o);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onResetVolumeIn()
|
|
{
|
|
ui->hs_VolumeIn->setValue((ui->hs_VolumeIn->maximum() - ui->hs_VolumeIn->minimum()) / 2);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onResetVolumeOut()
|
|
{
|
|
ui->hs_VolumeOut->setValue((ui->hs_VolumeOut->maximum() - ui->hs_VolumeOut->minimum()) / 2);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setAudioRunsWhere()
|
|
{
|
|
if (!this->hasAudio()) { return; }
|
|
const QString ai = sGui->getCContextAudioBase()->audioRunsWhereInfo();
|
|
ui->le_Info->setPlaceholderText(ai);
|
|
}
|
|
|
|
bool CAudioDeviceVolumeSetupComponent::updateIntegrateWithComFlagUi()
|
|
{
|
|
const bool integrate = this->isComIntegrated();
|
|
if (ui->cb_IntegratedWithCom->isChecked() == integrate) { return integrate; }
|
|
ui->cb_IntegratedWithCom->setChecked(integrate);
|
|
this->setCheckBoxesReadOnly(integrate);
|
|
return integrate;
|
|
}
|
|
|
|
bool CAudioDeviceVolumeSetupComponent::isComIntegrated() const
|
|
{
|
|
if (!this->hasSimulator()) { return false; }
|
|
const Simulation::Settings::CSimulatorSettings settings = sGui->getIContextSimulator()->getSimulatorSettings();
|
|
const bool integrate = settings.isComIntegrated();
|
|
return integrate;
|
|
|
|
/*
|
|
if (!this->hasAudio()) { return false; }
|
|
const bool integrated = sGui->getCContextAudioBase()->isComUnitIntegrated();
|
|
*/
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onRxTxChanged(bool checked)
|
|
{
|
|
if (!this->hasAudio()) { return; }
|
|
if (this->isComIntegrated()) { return; }
|
|
|
|
Q_UNUSED(checked)
|
|
const bool rx1 = ui->cb_1Rec->isChecked();
|
|
const bool rx2 = ui->cb_2Rec->isChecked();
|
|
|
|
// no transmit without receiving
|
|
const bool tx1 = rx1 && ui->cb_1Tx->isChecked();
|
|
const bool tx2 = rx2 && ui->cb_2Tx->isChecked();
|
|
|
|
sGui->getCContextAudioBase()->setRxTx(rx1, tx1, rx2, tx2);
|
|
|
|
QPointer<CAudioDeviceVolumeSetupComponent> myself(this);
|
|
QTimer::singleShot(25, this, [ = ]
|
|
{
|
|
// in case UI values are not correct
|
|
if (!myself) { return; }
|
|
this->setRxTxCheckboxes(rx1, tx1, rx2, tx2);
|
|
});
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onIntegratedFlagChanged(bool checked)
|
|
{
|
|
if (!this->hasAudio()) { return; }
|
|
this->setCheckBoxesReadOnly(checked);
|
|
|
|
if (!this->hasSimulator()) { return; }
|
|
if (!sGui->getIContextSimulator()->isSimulatorAvailable()) { return; }
|
|
|
|
const bool s = sGui->getIContextSimulator()->updateCurrentSettingComIntegration(checked);
|
|
Q_UNUSED(s)
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::setRxTxCheckboxes(bool rx1, bool tx1, bool rx2, bool tx2)
|
|
{
|
|
if (ui->cb_1Tx->isChecked() != tx1) { ui->cb_1Tx->setChecked(tx1); }
|
|
if (ui->cb_2Tx->isChecked() != tx2) { ui->cb_2Tx->setChecked(tx2); }
|
|
if (ui->cb_1Rec->isChecked() != rx1) { ui->cb_1Rec->setChecked(rx1); }
|
|
if (ui->cb_2Rec->isChecked() != rx2) { ui->cb_2Rec->setChecked(rx2); }
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onReceivingCallsignsChanged(const CCallsignSet &com1Callsigns, const CCallsignSet &com2Callsigns)
|
|
{
|
|
const QString info = (com1Callsigns.isEmpty() ? QString() : QStringLiteral("COM1: ") % com1Callsigns.getCallsignsAsString()) %
|
|
(!com1Callsigns.isEmpty() && !com2Callsigns.isEmpty() ? QStringLiteral(" | ") : QString()) %
|
|
(com2Callsigns.isEmpty() ? QString() : QStringLiteral("COM2: ") % com2Callsigns.getCallsignsAsString());
|
|
|
|
ui->led_Rx1->setOn(!com1Callsigns.isEmpty());
|
|
ui->led_Rx2->setOn(!com2Callsigns.isEmpty());
|
|
this->setInfo(info);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onUpdatedClientWithCockpitData()
|
|
{
|
|
this->setTransmitReceiveInUiFromVoiceClient();
|
|
}
|
|
|
|
CAudioDeviceInfo CAudioDeviceVolumeSetupComponent::getSelectedInputDevice() const
|
|
{
|
|
if (!hasAudio()) { return CAudioDeviceInfo(); }
|
|
const CAudioDeviceInfoList devices = sGui->getCContextAudioBase()->getAudioInputDevicesPlusDefault();
|
|
return devices.findByName(ui->cb_SetupAudioInputDevice->currentText());
|
|
}
|
|
|
|
CAudioDeviceInfo CAudioDeviceVolumeSetupComponent::getSelectedOutputDevice() const
|
|
{
|
|
if (!hasAudio()) { return CAudioDeviceInfo(); }
|
|
const CAudioDeviceInfoList devices = sGui->getCContextAudioBase()->getAudioOutputDevicesPlusDefault();
|
|
return devices.findByName(ui->cb_SetupAudioOutputDevice->currentText());
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onAudioDeviceSelected(int index)
|
|
{
|
|
if (!sGui || sGui->isShuttingDown() || !sGui->getIContextAudio()) { return; }
|
|
if (index < 0) { return; }
|
|
|
|
const CAudioDeviceInfo in = this->getSelectedInputDevice();
|
|
const CAudioDeviceInfo out = this->getSelectedOutputDevice();
|
|
sGui->getCContextAudioBase()->setCurrentAudioDevices(in, out);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onAudioStarted(const CAudioDeviceInfo &input, const CAudioDeviceInfo &output)
|
|
{
|
|
if (!afvClient()) { return; }
|
|
if (m_afvConnections.isEmpty() && m_init)
|
|
{
|
|
this->initWithAfvClient();
|
|
}
|
|
|
|
ui->cb_SetupAudioInputDevice->setCurrentText(input.toQString(true));
|
|
ui->cb_SetupAudioOutputDevice->setCurrentText(output.toQString(true));
|
|
this->setAudioRunsWhere();
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onAudioStopped()
|
|
{
|
|
this->setAudioRunsWhere();
|
|
if (!afvClient())
|
|
{
|
|
m_afvConnections.disconnectAll();
|
|
}
|
|
}
|
|
|
|
bool CAudioDeviceVolumeSetupComponent::onAudioDevicesChanged(const CAudioDeviceInfoList &devices)
|
|
{
|
|
if (m_cbDevices.hasSameDevices(devices)) { return false; } // avoid numerous follow up actions
|
|
m_cbDevices = devices;
|
|
|
|
this->setAudioRunsWhere();
|
|
ui->cb_SetupAudioOutputDevice->clear();
|
|
ui->cb_SetupAudioInputDevice->clear();
|
|
|
|
const QString i = ui->cb_SetupAudioInputDevice->currentText();
|
|
const QString o = ui->cb_SetupAudioOutputDevice->currentText();
|
|
|
|
for (const CAudioDeviceInfo &device : devices)
|
|
{
|
|
if (device.getType() == CAudioDeviceInfo::InputDevice)
|
|
{
|
|
ui->cb_SetupAudioInputDevice->addItem(device.toQString(true));
|
|
}
|
|
else if (device.getType() == CAudioDeviceInfo::OutputDevice)
|
|
{
|
|
ui->cb_SetupAudioOutputDevice->addItem(device.toQString(true));
|
|
}
|
|
}
|
|
|
|
if (!i.isEmpty()) { ui->cb_SetupAudioInputDevice->setCurrentText(i); }
|
|
if (!o.isEmpty()) { ui->cb_SetupAudioOutputDevice->setCurrentText(o); }
|
|
|
|
return true;
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onLoopbackToggled(bool loopback)
|
|
{
|
|
if (!sGui || sGui->isShuttingDown() || !sGui->getIContextAudio()) { return; }
|
|
if (sGui->getCContextAudioBase()->isAudioLoopbackEnabled() == loopback) { return; }
|
|
sGui->getCContextAudioBase()->enableAudioLoopback(loopback);
|
|
}
|
|
|
|
void CAudioDeviceVolumeSetupComponent::onDisableAudioEffectsToggled(bool disabled)
|
|
{
|
|
if (!sGui || sGui->isShuttingDown() || !sGui->getIContextAudio()) { return; }
|
|
CSettings as(m_audioSettings.getThreadLocal());
|
|
const bool enabled = !disabled;
|
|
if (as.isAudioEffectsEnabled() == enabled) { return; }
|
|
as.setAudioEffectsEnabled(enabled);
|
|
m_audioSettings.setAndSave(as);
|
|
}
|
|
} // namespace
|
|
} // namespace
|