26 #include <QDesktopWidget>
30 #include "audio/audio.h"
31 #include "audio/iaudiosettings.h"
32 #include "audio/iaudiosource.h"
43 #ifndef ALC_ALL_DEVICES_SPECIFIER
44 #define ALC_ALL_DEVICES_SPECIFIER ALC_DEVICE_SPECIFIER
52 , audioSettings{audioSettings}
53 , videoSettings{videoSettings}
54 , camVideoSurface(
nullptr)
62 cbEnableTestSound->setChecked(audioSettings->getEnableTestSound());
63 cbEnableTestSound->setToolTip(tr(
"Play a test sound while changing the output volume."));
67 playbackSlider->setTracking(
false);
68 playbackSlider->setMaximum(totalSliderSteps);
69 playbackSlider->setValue(getStepsFromValue(audioSettings->getOutVolume(),
70 audioSettings->getOutVolumeMin(),
71 audioSettings->getOutVolumeMax()));
72 playbackSlider->installEventFilter(
this);
74 microphoneSlider->setToolTip(tr(
"Use slider to set the gain of your input device ranging"
75 " from %1dB to %2dB.")
76 .arg(audio.minInputGain())
77 .arg(audio.maxInputGain()));
78 microphoneSlider->setMaximum(totalSliderSteps);
79 microphoneSlider->setTickPosition(QSlider::TicksBothSides);
80 static const int numTicks = 4;
81 microphoneSlider->setTickInterval(totalSliderSteps / numTicks);
82 microphoneSlider->setTracking(
false);
83 microphoneSlider->installEventFilter(
this);
84 microphoneSlider->setValue(
85 getStepsFromValue(audioSettings->getAudioInGainDecibel(),
87 audio.maxInputGain()));
89 audioThresholdSlider->setToolTip(tr(
"Use slider to set the activation volume for your"
91 audioThresholdSlider->setMaximum(totalSliderSteps);
92 audioThresholdSlider->setValue(getStepsFromValue(audioSettings->getAudioThreshold(),
93 audio.minInputThreshold(),
94 audio.maxInputThreshold()));
95 audioThresholdSlider->setTracking(
false);
96 audioThresholdSlider->installEventFilter(
this);
98 volumeDisplay->setMaximum(totalSliderSteps);
100 fillAudioQualityComboBox();
104 for (QScreen* qScreen : QGuiApplication::screens()) {
107 auto* qGUIApp = qobject_cast<QGuiApplication *>(qApp);
132 GenericForm::hideEvent(event);
151 GenericForm::showEvent(event);
156 QRect rect = mode.
toRect();
180 assert(0 <= index && index <
videoModes.size());
181 int devIndex = videoDevCombobox->currentIndex();
194 auto onGrabbed = [devName,
this](QRect region) {
200 QRect screen = QApplication::primaryScreen()->virtualGeometry();
201 mode.
x += screen.x();
202 mode.
y += screen.y();
214 Qt::QueuedConnection);
225 if (allVideoModes.isEmpty()) {
226 qCritical() <<
"Trying to select best mode from empty modes list";
231 std::map<int, VideoMode> idealModes;
237 idealModes[1080] =
VideoMode(1920, 1080);
238 idealModes[1440] =
VideoMode(2560, 1440);
239 idealModes[2160] =
VideoMode(3840, 2160);
241 std::map<int, int> bestModeInds;
242 for (
int i = 0; i < allVideoModes.size(); ++i) {
249 for (
auto iter = idealModes.begin(); iter != idealModes.end(); ++iter) {
250 int res = iter->first;
257 if (bestModeInds.find(res) == bestModeInds.end()) {
258 bestModeInds[res] = i;
262 int index = bestModeInds[res];
264 if (mode.
norm(idealMode) < best.
norm(idealMode)) {
265 bestModeInds[res] = i;
269 if (mode.
norm(idealMode) == best.
norm(idealMode)) {
271 if (mode.
FPS > best.
FPS) {
272 bestModeInds[res] = i;
277 if (mode.
FPS >= best.
FPS && better)
278 bestModeInds[res] = i;
283 QVector<VideoMode> newVideoModes;
284 for (
auto it = bestModeInds.rbegin(); it != bestModeInds.rend(); ++it) {
285 VideoMode mode = allVideoModes[it->second];
287 if (newVideoModes.empty()) {
288 newVideoModes.push_back(mode);
291 auto result = std::find_if(newVideoModes.cbegin(), newVideoModes.cend(),
292 [size](
VideoMode mode) { return getModeSize(mode) == size; });
294 if (result == newVideoModes.end())
295 newVideoModes.push_back(mode);
298 allVideoModes = newVideoModes;
303 qDebug() <<
"selected Modes:";
304 bool previouslyBlocked = videoModescomboBox->blockSignals(
true);
305 videoModescomboBox->clear();
312 qDebug(
"width: %d, height: %d, FPS: %f, pixel format: %s", mode.
width, mode.
height,
313 mode.
FPS, pixelFormat.c_str());
316 str += QString(
"%1p").arg(mode.
height);
318 str += tr(
"Default resolution");
321 videoModescomboBox->addItem(str);
325 videoModescomboBox->addItem(tr(
"Default resolution"));
327 videoModescomboBox->blockSignals(previouslyBlocked);
337 if (mode.
width == prefRes.width() && mode.
height == prefRes.height()
338 && (qAbs(mode.
FPS - prefFPS) < 0.0001f)) {
348 bool previouslyBlocked = videoModescomboBox->blockSignals(
true);
349 videoModescomboBox->clear();
354 qDebug(
"%dx%d+%d,%d FPS: %f, pixel format: %s\n", mode.
width, mode.
height, mode.
x, mode.
y,
355 mode.
FPS, pixelFormat.c_str());
359 name = tr(
"Screen %1").arg(i + 1);
361 name = tr(
"Select region");
363 videoModescomboBox->addItem(name);
366 videoModescomboBox->blockSignals(previouslyBlocked);
371 const bool previouslyBlocked = audioQualityComboBox->blockSignals(
true);
373 audioQualityComboBox->addItem(tr(
"High (64 kbps)"), 64);
374 audioQualityComboBox->addItem(tr(
"Medium (32 kbps)"), 32);
375 audioQualityComboBox->addItem(tr(
"Low (16 kbps)"), 16);
376 audioQualityComboBox->addItem(tr(
"Very low (8 kbps)"), 8);
379 const int index = audioQualityComboBox->findData(currentBitrate);
381 audioQualityComboBox->setCurrentIndex(index);
382 audioQualityComboBox->blockSignals(previouslyBlocked);
388 qWarning() <<
"Invalid index:" << curIndex;
394 qDebug(
"available Modes:");
408 if (preferedIndex != -1) {
410 videoModescomboBox->blockSignals(
true);
411 videoModescomboBox->setCurrentIndex(preferedIndex);
412 videoModescomboBox->blockSignals(
false);
422 videoModescomboBox->setCurrentIndex(
videoModes.size() - 1);
433 videoModescomboBox->setCurrentIndex(mid);
443 bool previouslyBlocked = videoModescomboBox->blockSignals(
true);
445 videoModescomboBox->blockSignals(previouslyBlocked);
451 int modeIndex = videoModescomboBox->currentIndex();
453 if (0 <= modeIndex && modeIndex <
videoModes.size()) {
465 audioSettings->setAudioBitrate(audioQualityComboBox->currentData().toInt());
471 int videoDevIndex = 0;
474 videoDevCombobox->blockSignals(
true);
475 videoDevCombobox->clear();
477 videoDevCombobox->addItem(device.second);
478 if (device.first == settingsInDev)
479 videoDevIndex = videoDevCombobox->count() - 1;
481 videoDevCombobox->setCurrentIndex(videoDevIndex);
482 videoDevCombobox->blockSignals(
false);
488 return qRound(mode.
height / 120.0) * 120;
493 QStringList deviceNames;
494 deviceNames << tr(
"Disabled") <<
audio.inDeviceNames();
496 inDevCombobox->blockSignals(
true);
497 inDevCombobox->clear();
498 inDevCombobox->addItems(deviceNames);
499 inDevCombobox->blockSignals(
false);
503 if (enabled && deviceNames.size() > 1) {
505 idx = qMax(deviceNames.indexOf(dev), 1);
507 inDevCombobox->setCurrentIndex(idx);
512 QStringList deviceNames;
513 deviceNames << tr(
"Disabled") <<
audio.outDeviceNames();
515 outDevCombobox->blockSignals(
true);
516 outDevCombobox->clear();
517 outDevCombobox->addItems(deviceNames);
518 outDevCombobox->blockSignals(
false);
522 if (enabled && deviceNames.size() > 1) {
524 idx = qMax(deviceNames.indexOf(dev), 1);
526 outDevCombobox->setCurrentIndex(idx);
531 const bool inputEnabled = deviceIndex > 0;
534 QString deviceName{};
536 deviceName = inDevCombobox->itemText(deviceIndex);
540 if (oldName != deviceName) {
542 audio.reinitInput(deviceName);
547 microphoneSlider->setEnabled(inputEnabled);
549 volumeDisplay->setValue(volumeDisplay->minimum());
555 const bool outputEnabled = deviceIndex > 0;
558 QString deviceName{};
560 deviceName = outDevCombobox->itemText(deviceIndex);
565 if (oldName != deviceName) {
567 audio.reinitOutput(deviceName);
571 playbackSlider->setEnabled(outputEnabled);
580 if (
audio.isOutputReady()) {
583 audio.setOutputVolume(volume);
585 if (cbEnableTestSound->isChecked() &&
audioSink) {
586 audioSink->playMono16Sound(IAudioSink::Sound::Test);
593 audioSettings->setEnableTestSound(cbEnableTestSound->isChecked());
595 if (cbEnableTestSound->isChecked() &&
audio.isOutputReady() &&
audioSink) {
596 audioSink->playMono16Sound(IAudioSink::Sound::Test);
604 audio.setInputGain(dB);
609 const qreal normThreshold =
612 audio.setInputThreshold(normThreshold);
632 while ((child = gridLayout->takeAt(0)) !=
nullptr)
642 Ui::AVForm::retranslateUi(
this);
647 const float norm = (val - valMin) / (valMax - valMin);
653 return (
static_cast<float>(steps) /
totalSliderSteps) * (valMax - valMin) + valMin;