10 #include <QStringLiteral>
11 #include <QToolButton>
14 #include "ui_audiodevicevolumesetupcomponent.h"
28 using namespace swift::core::afv::audio;
29 using namespace swift::core::afv::clients;
30 using namespace swift::core::context;
32 using namespace swift::misc::aviation;
33 using namespace swift::misc::audio;
34 using namespace swift::misc::physical_quantities;
35 using namespace swift::misc::simulation;
39 CAudioDeviceVolumeSetupComponent::CAudioDeviceVolumeSetupComponent(QWidget *parent)
43 connect(ui->hs_VolumeIn, &QSlider::valueChanged,
this,
44 &CAudioDeviceVolumeSetupComponent::onVolumeSliderChanged);
45 connect(ui->hs_VolumeOut, &QSlider::valueChanged,
this,
46 &CAudioDeviceVolumeSetupComponent::onVolumeSliderChanged);
47 connect(ui->hs_VolumeOutCom1, &QSlider::valueChanged,
this,
48 &CAudioDeviceVolumeSetupComponent::onVolumeSliderChanged);
49 connect(ui->hs_VolumeOutCom2, &QSlider::valueChanged,
this,
50 &CAudioDeviceVolumeSetupComponent::onVolumeSliderChanged);
51 connect(ui->tb_RefreshInDevice, &QToolButton::released,
this,
52 &CAudioDeviceVolumeSetupComponent::onReloadDevices, Qt::QueuedConnection);
53 connect(ui->tb_RefreshOutDevice, &QToolButton::released,
this,
54 &CAudioDeviceVolumeSetupComponent::onReloadDevices, Qt::QueuedConnection);
55 connect(ui->tb_ResetInVolume, &QToolButton::released,
this, &CAudioDeviceVolumeSetupComponent::onResetVolumeIn,
56 Qt::QueuedConnection);
57 connect(ui->tb_ResetOutVolume, &QToolButton::released,
this,
58 &CAudioDeviceVolumeSetupComponent::onResetVolumeOut, Qt::QueuedConnection);
59 connect(ui->tb_ResetOutVolumeCom1, &QToolButton::released,
this,
60 &CAudioDeviceVolumeSetupComponent::onResetVolumeOutCom1, Qt::QueuedConnection);
61 connect(ui->tb_ResetOutVolumeCom2, &QToolButton::released,
this,
62 &CAudioDeviceVolumeSetupComponent::onResetVolumeOutCom2, Qt::QueuedConnection);
64 connect(ui->cb_1Tx, &QCheckBox::toggled,
this, &CAudioDeviceVolumeSetupComponent::onRxTxChanged,
65 Qt::QueuedConnection);
66 connect(ui->cb_2Tx, &QCheckBox::toggled,
this, &CAudioDeviceVolumeSetupComponent::onRxTxChanged,
67 Qt::QueuedConnection);
68 connect(ui->cb_1Rec, &QCheckBox::toggled,
this, &CAudioDeviceVolumeSetupComponent::onRxTxChanged,
69 Qt::QueuedConnection);
70 connect(ui->cb_2Rec, &QCheckBox::toggled,
this, &CAudioDeviceVolumeSetupComponent::onRxTxChanged,
71 Qt::QueuedConnection);
73 ui->hs_VolumeIn->setMaximum(CSettings::InMax);
74 ui->hs_VolumeIn->setMinimum(CSettings::InMin);
75 ui->hs_VolumeOut->setMaximum(CSettings::OutMax);
76 ui->hs_VolumeOut->setMinimum(CSettings::OutMin);
77 ui->hs_VolumeOutCom1->setMaximum(CSettings::OutMax);
78 ui->hs_VolumeOutCom1->setMinimum(CSettings::OutMin);
79 ui->hs_VolumeOutCom2->setMaximum(CSettings::OutMax);
80 ui->hs_VolumeOutCom2->setMinimum(CSettings::OutMin);
87 ui->hs_VolumeIn->setValue(i);
88 ui->hs_VolumeOut->setValue(o);
89 ui->hs_VolumeOutCom1->setValue(o1);
90 ui->hs_VolumeOutCom2->setValue(o2);
91 ui->cb_SetupAudioLoopback->setChecked(
false);
94 ui->led_AudioConnected->setToolTips(
"Voice on and authenticated",
"Voice off");
95 ui->led_AudioConnected->setShape(CLedWidget::Rounded);
96 ui->led_Rx1->setToolTips(
"COM1 receiving",
"COM1 idle");
97 ui->led_Rx1->setShape(CLedWidget::Rounded);
98 ui->led_Rx2->setToolTips(
"COM2 receiving",
"COM2 idle");
99 ui->led_Rx2->setShape(CLedWidget::Rounded);
104 QPointer<CAudioDeviceVolumeSetupComponent> myself(
this);
110 this->setCheckBoxesReadOnly(this->isComIntegrated());
111 this->setVolumeSlidersReadOnly(this->isComIntegrated());
114 void CAudioDeviceVolumeSetupComponent::init()
119 const bool audio = this->hasAudio();
120 this->setEnabled(audio);
121 this->reloadSettings();
123 bool c = connect(ui->cb_SetupAudioLoopback, &QCheckBox::toggled,
this,
124 &CAudioDeviceVolumeSetupComponent::onLoopbackToggled);
126 c = connect(ui->cb_DisableAudioEffects, &QCheckBox::toggled,
this,
127 &CAudioDeviceVolumeSetupComponent::onDisableAudioEffectsToggled);
133 &CAudioDeviceVolumeSetupComponent::simulatorSettingsChanged);
139 this->setAudioRunsWhere();
140 this->initAudioDeviceLists();
146 c = connect(ui->cb_SetupAudioInputDevice, qOverload<int>(&QComboBox::currentIndexChanged),
this,
147 &CAudioDeviceVolumeSetupComponent::onAudioDeviceSelected, Qt::QueuedConnection);
149 c = connect(ui->cb_SetupAudioOutputDevice, qOverload<int>(&QComboBox::currentIndexChanged),
this,
150 &CAudioDeviceVolumeSetupComponent::onAudioDeviceSelected, Qt::QueuedConnection);
155 &CAudioDeviceVolumeSetupComponent::onAudioDevicesChanged, Qt::QueuedConnection);
158 &CAudioDeviceVolumeSetupComponent::onAudioStarted, Qt::QueuedConnection);
161 &CAudioDeviceVolumeSetupComponent::onAudioStopped, Qt::QueuedConnection);
164 this->initWithAfvClient();
170 void CAudioDeviceVolumeSetupComponent::initWithAfvClient()
172 if (!afvClient()) {
return; }
177 const Qt::ConnectionType ct = Qt::QueuedConnection;
178 QMetaObject::Connection c;
179 c = connect(afv, &CAfvClient::outputVolumePeakVU,
this, &CAudioDeviceVolumeSetupComponent::onOutputVU, ct);
181 m_afvConnections.
append(c);
182 c = connect(afv, &CAfvClient::inputVolumePeakVU,
this, &CAudioDeviceVolumeSetupComponent::onInputVU, ct);
184 m_afvConnections.
append(c);
185 c = connect(afv, &CAfvClient::receivedCallsignsChanged,
this,
186 &CAudioDeviceVolumeSetupComponent::onReceivingCallsignsChanged, ct);
188 m_afvConnections.
append(c);
189 c = connect(afv, &CAfvClient::updatedFromOwnAircraftCockpit,
this,
190 &CAudioDeviceVolumeSetupComponent::onUpdatedClientWithCockpitData, ct);
192 m_afvConnections.
append(c);
195 afv->
setRxTx(
true,
true,
true,
false);
197 QPointer<CAudioDeviceVolumeSetupComponent> myself(
this);
199 afv, &CAfvClient::connectionStatusChanged,
this,
202 myself->setTransmitReceiveInUiFromVoiceClient();
207 m_afvConnections.
append(c);
209 this->setTransmitReceiveInUiFromVoiceClient();
216 const double r = ui->hs_VolumeIn->maximum() - ui->hs_VolumeIn->minimum();
217 const double tr = to - from;
218 return qRound(ui->hs_VolumeIn->value() / r * tr);
223 const double r = ui->hs_VolumeOut->maximum() - ui->hs_VolumeOut->minimum();
224 const double tr = to - from;
225 return qRound(ui->hs_VolumeOut->value() / r * tr);
230 const double r = ui->hs_VolumeOutCom1->maximum() - ui->hs_VolumeOutCom1->minimum();
231 const double tr = to - from;
232 return qRound(ui->hs_VolumeOutCom1->value() / r * tr);
237 const double r = ui->hs_VolumeOutCom2->maximum() - ui->hs_VolumeOutCom2->minimum();
238 const double tr = to - from;
239 return qRound(ui->hs_VolumeOutCom2->value() / r * tr);
244 if (value > to) { value = to; }
245 else if (value < from) { value = from; }
246 const double r = ui->hs_VolumeIn->maximum() - ui->hs_VolumeIn->minimum();
247 const double tr = to - from;
248 ui->hs_VolumeIn->setValue(qRound(value / tr * r));
253 if (value > to) { value = to; }
254 else if (value < from) { value = from; }
255 const double r = ui->hs_VolumeOut->maximum() - ui->hs_VolumeOut->minimum();
256 const double tr = to - from;
257 ui->hs_VolumeOut->setValue(qRound(value / tr * r));
262 if (value > to) { value = to; }
263 else if (value < from) { value = from; }
264 const double r = ui->hs_VolumeOutCom1->maximum() - ui->hs_VolumeOutCom1->minimum();
265 const double tr = to - from;
266 ui->hs_VolumeOutCom1->setValue(qRound(value / tr * r));
271 if (value > to) { value = to; }
272 else if (value < from) { value = from; }
273 const double r = ui->hs_VolumeOutCom2->maximum() - ui->hs_VolumeOutCom2->minimum();
274 const double tr = to - from;
275 ui->hs_VolumeOutCom2->setValue(qRound(value / tr * r));
280 if (value > 1.0) { value = 1.0; }
281 else if (value < 0.0) { value = 0.0; }
282 ui->wip_InLevelMeter->levelChanged(value);
287 if (value > 1.0) { value = 1.0; }
288 else if (value < 0.0) { value = 0.0; }
289 ui->wip_OutLevelMeter->levelChanged(value);
294 ui->le_Info->setText(info);
295 ui->le_Info->setToolTip(info);
298 void CAudioDeviceVolumeSetupComponent::setTransmitReceiveInUi(
bool tx1,
bool rec1,
bool tx2,
bool rec2,
301 this->setRxTxCheckboxes(rec1, tx1, rec2, tx2);
302 this->setCheckBoxesReadOnly(integrated);
303 this->setVolumeSlidersReadOnly(integrated);
306 void CAudioDeviceVolumeSetupComponent::setTransmitReceiveInUiFromVoiceClient()
308 if (!this->hasAudio())
310 ui->led_AudioConnected->setOn(
false);
315 ui->led_AudioConnected->setOn(on);
324 const bool com1Rx = com1Enabled;
325 const bool com2Rx = com2Enabled;
327 const bool integrated = this->isComIntegrated();
328 this->setTransmitReceiveInUi(com1Tx, com1Rx, com2Tx, com2Rx, integrated);
335 ui->hs_VolumeOutCom1->setValue(vol1);
336 ui->hs_VolumeOutCom2->setValue(vol2);
340 void CAudioDeviceVolumeSetupComponent::setCheckBoxesReadOnly(
bool readonly)
349 void CAudioDeviceVolumeSetupComponent::setVolumeSlidersReadOnly(
bool readonly)
351 ui->hs_VolumeOutCom1->setDisabled(readonly);
352 ui->hs_VolumeOutCom2->setDisabled(readonly);
356 ui->hs_VolumeOutCom1->setStyleSheet(
"background: rgb(40,40,40)");
357 ui->hs_VolumeOutCom2->setStyleSheet(
"background: rgb(40,40,40)");
361 ui->hs_VolumeOutCom1->setStyleSheet(
"");
362 ui->hs_VolumeOutCom2->setStyleSheet(
"");
366 CAfvClient *CAudioDeviceVolumeSetupComponent::afvClient()
372 void CAudioDeviceVolumeSetupComponent::reloadSettings()
375 ui->cb_DisableAudioEffects->setChecked(!as.isAudioEffectsEnabled());
382 void CAudioDeviceVolumeSetupComponent::initAudioDeviceLists()
384 if (!this->hasAudio()) {
return; }
386 if (!changed) {
return; }
396 void CAudioDeviceVolumeSetupComponent::onVolumeSliderChanged(
int v)
402 void CAudioDeviceVolumeSetupComponent::saveVolumes()
409 if (as.getInVolume() == i && o == as.getOutVolume() && as.getOutVolumeCom1() == o1 &&
410 as.getOutVolumeCom2() == o2)
416 as.setOutVolumeCom1(o1);
417 as.setOutVolumeCom2(o2);
421 void CAudioDeviceVolumeSetupComponent::onOutputVU(
double vu) { this->
setOutLevel(vu); }
423 void CAudioDeviceVolumeSetupComponent::onInputVU(
double vu) { this->
setInLevel(vu); }
425 void CAudioDeviceVolumeSetupComponent::onReloadDevices()
427 if (!hasAudio()) {
return; }
428 this->initAudioDeviceLists();
434 void CAudioDeviceVolumeSetupComponent::onResetVolumeIn()
436 ui->hs_VolumeIn->setValue((ui->hs_VolumeIn->maximum() - ui->hs_VolumeIn->minimum()) / 2);
439 void CAudioDeviceVolumeSetupComponent::onResetVolumeOut()
441 ui->hs_VolumeOut->setValue((ui->hs_VolumeOut->maximum() - ui->hs_VolumeOut->minimum()) / 2);
444 void CAudioDeviceVolumeSetupComponent::onResetVolumeOutCom1()
446 ui->hs_VolumeOutCom1->setValue(ui->hs_VolumeOutCom1->maximum());
449 void CAudioDeviceVolumeSetupComponent::onResetVolumeOutCom2()
451 ui->hs_VolumeOutCom2->setValue(ui->hs_VolumeOutCom2->maximum());
454 void CAudioDeviceVolumeSetupComponent::setAudioRunsWhere()
456 if (!this->hasAudio()) {
return; }
458 ui->le_Info->setPlaceholderText(ai);
461 void CAudioDeviceVolumeSetupComponent::simulatorSettingsChanged()
463 const bool integrated = this->isComIntegrated();
464 setCheckBoxesReadOnly(integrated);
465 setVolumeSlidersReadOnly(integrated);
468 bool CAudioDeviceVolumeSetupComponent::isComIntegrated()
const
470 if (!this->hasSimulator()) {
return false; }
476 void CAudioDeviceVolumeSetupComponent::onRxTxChanged(
bool checked)
478 if (!this->hasAudio()) {
return; }
479 if (this->isComIntegrated()) {
return; }
482 const bool rx1 = ui->cb_1Rec->isChecked();
483 const bool rx2 = ui->cb_2Rec->isChecked();
486 const bool tx1 = rx1 && ui->cb_1Tx->isChecked();
487 const bool tx2 = rx2 && ui->cb_2Tx->isChecked();
491 QPointer<CAudioDeviceVolumeSetupComponent> myself(
this);
494 if (!myself) {
return; }
495 this->setRxTxCheckboxes(rx1, tx1, rx2, tx2);
499 void CAudioDeviceVolumeSetupComponent::setRxTxCheckboxes(
bool rx1,
bool tx1,
bool rx2,
bool tx2)
501 if (ui->cb_1Tx->isChecked() != tx1) { ui->cb_1Tx->setChecked(tx1); }
502 if (ui->cb_2Tx->isChecked() != tx2) { ui->cb_2Tx->setChecked(tx2); }
503 if (ui->cb_1Rec->isChecked() != rx1) { ui->cb_1Rec->setChecked(rx1); }
504 if (ui->cb_2Rec->isChecked() != rx2) { ui->cb_2Rec->setChecked(rx2); }
507 void CAudioDeviceVolumeSetupComponent::onReceivingCallsignsChanged(
const CCallsignSet &com1Callsigns,
511 (com1Callsigns.
isEmpty() ? QString() : QStringLiteral(
"COM1: ") % com1Callsigns.getCallsignsAsString()) %
512 (!com1Callsigns.isEmpty() && !com2Callsigns.isEmpty() ? QStringLiteral(
" | ") : QString()) %
513 (com2Callsigns.isEmpty() ? QString() : QStringLiteral(
"COM2: ") % com2Callsigns.getCallsignsAsString());
515 ui->led_Rx1->setOn(!com1Callsigns.
isEmpty());
516 ui->led_Rx2->setOn(!com2Callsigns.
isEmpty());
520 void CAudioDeviceVolumeSetupComponent::onUpdatedClientWithCockpitData()
522 this->setTransmitReceiveInUiFromVoiceClient();
525 CAudioDeviceInfo CAudioDeviceVolumeSetupComponent::getSelectedInputDevice()
const
529 return devices.
findByName(ui->cb_SetupAudioInputDevice->currentText());
532 CAudioDeviceInfo CAudioDeviceVolumeSetupComponent::getSelectedOutputDevice()
const
536 return devices.
findByName(ui->cb_SetupAudioOutputDevice->currentText());
539 void CAudioDeviceVolumeSetupComponent::onAudioDeviceSelected(
int index)
542 if (index < 0) {
return; }
551 if (!afvClient()) {
return; }
552 if (m_afvConnections.
isEmpty() && m_init) { this->initWithAfvClient(); }
554 ui->cb_SetupAudioInputDevice->setCurrentText(input.
toQString(
true));
555 ui->cb_SetupAudioOutputDevice->setCurrentText(output.
toQString(
true));
556 this->setAudioRunsWhere();
559 void CAudioDeviceVolumeSetupComponent::onAudioStopped()
561 this->setAudioRunsWhere();
565 bool CAudioDeviceVolumeSetupComponent::onAudioDevicesChanged(
const CAudioDeviceInfoList &devices)
568 m_cbDevices = devices;
570 this->setAudioRunsWhere();
571 ui->cb_SetupAudioOutputDevice->clear();
572 ui->cb_SetupAudioInputDevice->clear();
574 const QString i = ui->cb_SetupAudioInputDevice->currentText();
575 const QString o = ui->cb_SetupAudioOutputDevice->currentText();
579 if (device.getType() == CAudioDeviceInfo::InputDevice)
581 ui->cb_SetupAudioInputDevice->addItem(device.toQString(
true));
583 else if (device.getType() == CAudioDeviceInfo::OutputDevice)
585 ui->cb_SetupAudioOutputDevice->addItem(device.toQString(
true));
589 if (!i.isEmpty()) { ui->cb_SetupAudioInputDevice->setCurrentText(i); }
590 if (!o.isEmpty()) { ui->cb_SetupAudioOutputDevice->setCurrentText(o); }
595 void CAudioDeviceVolumeSetupComponent::onLoopbackToggled(
bool loopback)
602 void CAudioDeviceVolumeSetupComponent::onDisableAudioEffectsToggled(
bool disabled)
606 const bool enabled = !disabled;
607 if (as.isAudioEffectsEnabled() == enabled) {
return; }
608 as.setAudioEffectsEnabled(enabled);
const context::IContextAudio * getIContextAudio() const
Direct access to contexts if a CCoreFacade has been initialized.
bool isShuttingDown() const
Is application shutting down?
const context::IContextSimulator * getIContextSimulator() const
Direct access to contexts if a CCoreFacade has been initialized.
const context::CContextAudioBase * getCContextAudioBase() const
Direct access to contexts if a CCoreFacade has been initialized.
ConnectionStatus
Connection status.
void setRxTx(bool rx1, bool tx1, bool rx2, bool tx2)
Simplified enable/disable.
bool isAudioLoopbackEnabled() const
Loopback.
bool isAudioConnected() const
Is audio connected?
void enableAudioLoopback(bool enable=true)
Loopback.
swift::misc::audio::CAudioDeviceInfoList getAudioOutputDevices() const
Audio devices.
bool isTransmittingComUnit(swift::misc::aviation::CComSystem::ComUnit comUnit) const
Is COM unit transmitting?
swift::misc::audio::CAudioDeviceInfoList getAudioDevices() const
Audio devices.
void setCurrentAudioDevices(const swift::misc::audio::CAudioDeviceInfo &inputDevice, const swift::misc::audio::CAudioDeviceInfo &outputDevice)
Set current audio devices.
QString audioRunsWhereInfo() const
Info string about audio.
swift::misc::audio::CAudioDeviceInfoList getCurrentAudioDevices() const
Get current audio device.
int getComOutputVolume(swift::misc::aviation::CComSystem::ComUnit comUnit) const
Volume.
bool isEnabledComUnit(swift::misc::aviation::CComSystem::ComUnit comUnit) const
Is COM unit enabled?
void setRxTx(bool rx1, bool tx1, bool rx2, bool tx2)
Receive/transmit.
afv::clients::CAfvClient * afvClient() const
swift::misc::audio::CAudioDeviceInfoList getAudioInputDevices() const
Audio devices.
virtual swift::misc::simulation::settings::CSimulatorSettings getSimulatorSettings() const =0
Get the current simulator settings.
static void checkBoxReadOnly(QCheckBox *checkBox, bool readOnly)
Pseudo readonly state for checkbox.
Audio setup such as input / output devices.
void setOutValueCom1(int value, int from=swift::misc::audio::CSettings::OutMin, int to=swift::misc::audio::CSettings::OutMax)
Set input and output volume values.
int getInValue(int from=swift::misc::audio::CSettings::InMin, int to=swift::misc::audio::CSettings::InMax) const
Get input and output volume values.
virtual ~CAudioDeviceVolumeSetupComponent()
Destructor.
int getOutValueCom2(int from=swift::misc::audio::CSettings::OutMin, int to=swift::misc::audio::CSettings::OutMax) const
Get input and output volume values.
int getOutValue(int from=swift::misc::audio::CSettings::OutMin, int to=swift::misc::audio::CSettings::OutMax) const
Get input and output volume values.
int getOutValueCom1(int from=swift::misc::audio::CSettings::OutMin, int to=swift::misc::audio::CSettings::OutMax) const
Get input and output volume values.
void setOutValueCom2(int value, int from=swift::misc::audio::CSettings::OutMin, int to=swift::misc::audio::CSettings::OutMax)
Set input and output volume values.
void setInValue(int value, int from=swift::misc::audio::CSettings::InMin, int to=swift::misc::audio::CSettings::InMax)
Set input and output volume values.
void setInLevel(double value)
Set input and output level values 0..1.
void setOutLevel(double value)
Set input and output level values 0..1.
void setInfo(const QString &info)
Info string.
void setOutValue(int value, int from=swift::misc::audio::CSettings::InMin, int to=swift::misc::audio::CSettings::InMax)
Set input and output volume values.
CStatusMessage setAndSave(const T &value, qint64 timestamp=0)
Write and save in the same step. Must be called from the thread in which the owner lives.
const T & getThreadLocal() const
Read the current value.
bool isEmpty() const
Synonym for empty.
bool append(const QMetaObject::Connection &connection)
Add connection.
int disconnectAll()
Disconnect all.
bool isEmpty() const
Empty.
void inputSignal()
Received input signal, or manually trigger.
const_reference frontOrDefault() const
Access the first element, or a default-initialized value if the sequence is empty.
Value object encapsulating information of a audio device.
Value object encapsulating a list of audio devices.
CAudioDeviceInfoList getOutputDevices() const
Get output devices in that list.
CAudioDeviceInfoList getInputDevices() const
Get output devices in that list.
bool hasSameDevices(const CAudioDeviceInfoList &compareDevices) const
Has same devices.
CAudioDeviceInfo findByName(const QString &name, bool strict=false) const
Find by name.
Value object encapsulating information of audio related settings.
bool isAudioEffectsEnabled() const
Audio effects enabled?
Value object for a set of callsigns.
QString toQString(bool i18n=false) const
Cast as QString.
Settings for simulator Driver independent parts (such as directories), also used in model loaders.
bool isComIntegrated() const
COM unit integration.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
Backend services of the swift project, like dealing with the network or the simulators.
High level reusable GUI components.
Free functions in swift::misc.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...