From 7639b277ceb6f14b3a2d87dfc6aca78d59f2b731 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sun, 5 Feb 2017 21:51:50 -0800 Subject: [PATCH] UI: Add audio monitoring to settings/adv audio props. Adds audio monitoring selection to advanced audio properties, and adds the ability to select the device in advanced settings. --- UI/adv-audio-control.cpp | 47 ++++++++++++++++++++--- UI/adv-audio-control.hpp | 3 ++ UI/data/locale/en-US.ini | 6 +++ UI/forms/OBSBasicSettings.ui | 31 +++++++++++++-- UI/volume-control.cpp | 1 + UI/window-basic-adv-audio.cpp | 18 ++++++--- UI/window-basic-main.cpp | 5 +++ UI/window-basic-settings.cpp | 71 ++++++++++++++++++++++++++++++++++- UI/window-basic-settings.hpp | 1 + 9 files changed, 166 insertions(+), 17 deletions(-) diff --git a/UI/adv-audio-control.cpp b/UI/adv-audio-control.cpp index 6ac4a5ade..deadbedc9 100644 --- a/UI/adv-audio-control.cpp +++ b/UI/adv-audio-control.cpp @@ -2,9 +2,11 @@ #include #include #include +#include #include #include #include "qt-wrappers.hpp" +#include "obs-app.hpp" #include "adv-audio-control.hpp" #ifndef NSEC_PER_MSEC @@ -30,6 +32,9 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_) volume = new QSpinBox(); forceMono = new QCheckBox(); panning = new QSlider(Qt::Horizontal); +#if defined(_WIN32) || defined(__APPLE__) + monitoringType = new QComboBox(); +#endif syncOffset = new QSpinBox(); mixer1 = new QCheckBox(); mixer2 = new QCheckBox(); @@ -87,6 +92,19 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_) syncOffset->setMaximum(20000); syncOffset->setValue(int(cur_sync / NSEC_PER_MSEC)); + int idx; +#if defined(_WIN32) || defined(__APPLE__) + monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.None"), + (int)OBS_MONITORING_TYPE_NONE); + monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.MonitorOnly"), + (int)OBS_MONITORING_TYPE_MONITOR_ONLY); + monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.Both"), + (int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); + int mt = (int)obs_source_get_monitoring_type(source); + idx = monitoringType->findData(mt); + monitoringType->setCurrentIndex(idx); +#endif + mixer1->setText("1"); mixer1->setChecked(mixers & (1<<0)); mixer2->setText("2"); @@ -120,6 +138,10 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_) this, SLOT(panningChanged(int))); QWidget::connect(syncOffset, SIGNAL(valueChanged(int)), this, SLOT(syncOffsetChanged(int))); +#if defined(_WIN32) || defined(__APPLE__) + QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)), + this, SLOT(monitoringTypeChanged(int))); +#endif QWidget::connect(mixer1, SIGNAL(clicked(bool)), this, SLOT(mixer1Changed(bool))); QWidget::connect(mixer2, SIGNAL(clicked(bool)), @@ -135,12 +157,16 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_) int lastRow = layout->rowCount(); - layout->addWidget(nameLabel, lastRow, 0); - layout->addWidget(volume, lastRow, 1); - layout->addWidget(forceMonoContainer, lastRow, 2); - layout->addWidget(panningContainer, lastRow, 3); - layout->addWidget(syncOffset, lastRow, 4); - layout->addWidget(mixerContainer, lastRow, 5); + idx = 0; + layout->addWidget(nameLabel, lastRow, idx++); + layout->addWidget(volume, lastRow, idx++); + layout->addWidget(forceMonoContainer, lastRow, idx++); + layout->addWidget(panningContainer, lastRow, idx++); + layout->addWidget(syncOffset, lastRow, idx++); +#if defined(_WIN32) || defined(__APPLE__) + layout->addWidget(monitoringType, lastRow, idx++); +#endif + layout->addWidget(mixerContainer, lastRow, idx++); layout->layout()->setAlignment(mixerContainer, Qt::AlignHCenter | Qt::AlignVCenter); } @@ -152,6 +178,9 @@ OBSAdvAudioCtrl::~OBSAdvAudioCtrl() forceMonoContainer->deleteLater(); panningContainer->deleteLater(); syncOffset->deleteLater(); +#if defined(_WIN32) || defined(__APPLE__) + monitoringType->deleteLater(); +#endif mixerContainer->deleteLater(); } @@ -264,6 +293,12 @@ void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds) int64_t(milliseconds) * NSEC_PER_MSEC); } +void OBSAdvAudioCtrl::monitoringTypeChanged(int index) +{ + int mt = monitoringType->itemData(index).toInt(); + obs_source_set_monitoring_type(source, (obs_monitoring_type)mt); +} + static inline void setMixer(obs_source_t *source, const int mixerIdx, const bool checked) { diff --git a/UI/adv-audio-control.hpp b/UI/adv-audio-control.hpp index 3efad2dfd..38d760823 100644 --- a/UI/adv-audio-control.hpp +++ b/UI/adv-audio-control.hpp @@ -9,6 +9,7 @@ class QLabel; class QSpinBox; class QCheckBox; class QSlider; +class QComboBox; class OBSAdvAudioCtrl : public QObject { Q_OBJECT @@ -27,6 +28,7 @@ private: QPointer labelL; QPointer labelR; QPointer syncOffset; + QPointer monitoringType; QPointer mixer1; QPointer mixer2; QPointer mixer3; @@ -60,6 +62,7 @@ public slots: void downmixMonoChanged(bool checked); void panningChanged(int val); void syncOffsetChanged(int milliseconds); + void monitoringTypeChanged(int index); void mixer1Changed(bool checked); void mixer2Changed(bool checked); void mixer3Changed(bool checked); diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index 38b4ee0e4..e53e836fe 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -569,6 +569,8 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV Color Space" Basic.Settings.Advanced.Video.ColorRange="YUV Color Range" Basic.Settings.Advanced.Video.ColorRange.Partial="Partial" Basic.Settings.Advanced.Video.ColorRange.Full="Full" +Basic.Settings.Advanced.Audio.MonitoringDevice="Audio Monitoring Device" +Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Default" Basic.Settings.Advanced.StreamDelay="Stream Delay" Basic.Settings.Advanced.StreamDelay.Duration="Duration (seconds)" Basic.Settings.Advanced.StreamDelay.Preserve="Preserve cutoff point (increase delay) when reconnecting" @@ -583,6 +585,10 @@ Basic.AdvAudio.Volume="Volume (%)" Basic.AdvAudio.Mono="Downmix to Mono" Basic.AdvAudio.Panning="Panning" Basic.AdvAudio.SyncOffset="Sync Offset (ms)" +Basic.AdvAudio.Monitoring="Audio Monitoring" +Basic.AdvAudio.Monitoring.None="Monitor Off" +Basic.AdvAudio.Monitoring.MonitorOnly="Monitor Only (mute output)" +Basic.AdvAudio.Monitoring.Both="Monitor and Output" Basic.AdvAudio.AudioTracks="Tracks" # basic mode 'hotkeys' settings diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui index 801bdcae5..21c4cb363 100644 --- a/UI/forms/OBSBasicSettings.ui +++ b/UI/forms/OBSBasicSettings.ui @@ -2936,8 +2936,8 @@ 0 0 - 80 - 16 + 98 + 28 @@ -3255,8 +3255,8 @@ 0 0 - 818 - 697 + 98 + 28 @@ -3531,6 +3531,28 @@ + + + + Basic.Settings.Audio + + + + + + Basic.Settings.Advanced.Audio.MonitoringDevice + + + monitoringDevice + + + + + + + + + @@ -3974,6 +3996,7 @@ colorRange disableOSXVSync resetOSXVSync + monitoringDevice filenameFormatting overwriteIfExists simpleRBPrefix diff --git a/UI/volume-control.cpp b/UI/volume-control.cpp index 02456a48e..f930c7da8 100644 --- a/UI/volume-control.cpp +++ b/UI/volume-control.cpp @@ -3,6 +3,7 @@ #include "mute-checkbox.hpp" #include "slider-absoluteset-style.hpp" #include +#include #include #include #include diff --git a/UI/window-basic-adv-audio.cpp b/UI/window-basic-adv-audio.cpp index e983b51bf..ad3977d61 100644 --- a/UI/window-basic-adv-audio.cpp +++ b/UI/window-basic-adv-audio.cpp @@ -22,26 +22,32 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent) QWidget *widget; QLabel *label; + int idx = 0; mainLayout = new QGridLayout; mainLayout->setContentsMargins(0, 0, 0, 0); label = new QLabel(QTStr("Basic.AdvAudio.Name")); label->setAlignment(Qt::AlignHCenter); - mainLayout->addWidget(label, 0, 0); + mainLayout->addWidget(label, 0, idx++); label = new QLabel(QTStr("Basic.AdvAudio.Volume")); label->setAlignment(Qt::AlignHCenter); - mainLayout->addWidget(label, 0, 1); + mainLayout->addWidget(label, 0, idx++); label = new QLabel(QTStr("Basic.AdvAudio.Mono")); label->setAlignment(Qt::AlignHCenter); - mainLayout->addWidget(label, 0, 2); + mainLayout->addWidget(label, 0, idx++); label = new QLabel(QTStr("Basic.AdvAudio.Panning")); label->setAlignment(Qt::AlignHCenter); - mainLayout->addWidget(label, 0, 3); + mainLayout->addWidget(label, 0, idx++); label = new QLabel(QTStr("Basic.AdvAudio.SyncOffset")); label->setAlignment(Qt::AlignHCenter); - mainLayout->addWidget(label, 0, 4); + mainLayout->addWidget(label, 0, idx++); +#if defined(_WIN32) || defined(__APPLE__) + label = new QLabel(QTStr("Basic.AdvAudio.Monitoring")); + label->setAlignment(Qt::AlignHCenter); + mainLayout->addWidget(label, 0, idx++); +#endif label = new QLabel(QTStr("Basic.AdvAudio.AudioTracks")); label->setAlignment(Qt::AlignHCenter); - mainLayout->addWidget(label, 0, 5); + mainLayout->addWidget(label, 0, idx++); controlArea = new QWidget; controlArea->setLayout(mainLayout); diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 1945d9a3c..7f4b10631 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -1024,6 +1024,11 @@ bool OBSBasic::InitBasicConfigDefaults() config_set_default_string(basicConfig, "Video", "ColorRange", "Partial"); + config_set_default_string(basicConfig, "Audio", "MonitoringDeviceId", + "default"); + config_set_default_string(basicConfig, "Audio", "MonitoringDeviceName", + Str("Basic.Settings.Advanced.Audio.MonitoringDevice" + ".Default")); config_set_default_uint (basicConfig, "Audio", "SampleRate", 44100); config_set_default_string(basicConfig, "Audio", "ChannelSetup", "Stereo"); diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp index fa02af3b9..18080f091 100644 --- a/UI/window-basic-settings.cpp +++ b/UI/window-basic-settings.cpp @@ -387,6 +387,9 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->colorRange, COMBO_CHANGED, ADV_CHANGED); HookWidget(ui->disableOSXVSync, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->resetOSXVSync, CHECK_CHANGED, ADV_CHANGED); +#if defined(_WIN32) || defined(__APPLE__) + HookWidget(ui->monitoringDevice, COMBO_CHANGED, ADV_CHANGED); +#endif HookWidget(ui->filenameFormatting, EDIT_CHANGED, ADV_CHANGED); HookWidget(ui->overwriteIfExists, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->simpleRBPrefix, EDIT_CHANGED, ADV_CHANGED); @@ -400,6 +403,15 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->processPriority, COMBO_CHANGED, ADV_CHANGED); HookWidget(ui->bindToIP, COMBO_CHANGED, ADV_CHANGED); +#if !defined(_WIN32) && !defined(__APPLE__) + delete ui->monitoringDevice; + delete ui->monitoringDeviceLabel; + delete ui->advAudioGroupBox; + ui->monitoringDevice = nullptr; + ui->monitoringDeviceLabel = nullptr; + ui->advAudioGroupBox = nullptr; +#endif + #ifdef _WIN32 uint32_t winVer = GetWindowsVersion(); if (winVer > 0 && winVer < 0x602) { @@ -531,6 +543,9 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) FillSimpleRecordingValues(); FillSimpleStreamingValues(); +#if defined(_WIN32) || defined(__APPLE__) + FillAudioMonitoringDevices(); +#endif connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), this, SLOT(SimpleRecordingQualityChanged())); @@ -1918,6 +1933,12 @@ void OBSBasicSettings::LoadAdvancedSettings() "Video", "ColorSpace"); const char *videoColorRange = config_get_string(main->Config(), "Video", "ColorRange"); +#if defined(_WIN32) || defined(__APPLE__) + const char *monDevName = config_get_string(main->Config(), "Audio", + "MonitoringDeviceName"); + const char *monDevId = config_get_string(main->Config(), "Audio", + "MonitoringDeviceId"); +#endif bool enableDelay = config_get_bool(main->Config(), "Output", "DelayEnable"); int delaySec = config_get_int(main->Config(), "Output", @@ -1940,11 +1961,31 @@ void OBSBasicSettings::LoadAdvancedSettings() "RecRBPrefix"); const char *rbSuffix = config_get_string(main->Config(), "SimpleOutput", "RecRBSuffix"); + int idx; loading = true; LoadRendererList(); +#if defined(_WIN32) || defined(__APPLE__) + QComboBox *cb = ui->monitoringDevice; + idx = cb->findData(monDevId); + if (idx == -1) { + cb->insertItem(0, monDevName, monDevId); + + QStandardItemModel *model = + dynamic_cast(cb->model()); + if (!model) + return; + + QStandardItem *item = model->item(0); + item->setFlags(Qt::NoItemFlags); + + idx = 0; + } + cb->setCurrentIndex(idx); +#endif + ui->filenameFormatting->setText(filename); ui->overwriteIfExists->setChecked(overwriteIfExists); ui->simpleRBPrefix->setText(rbPrefix); @@ -1979,7 +2020,7 @@ void OBSBasicSettings::LoadAdvancedSettings() #elif _WIN32 const char *processPriority = config_get_string(App()->GlobalConfig(), "General", "ProcessPriority"); - int idx = ui->processPriority->findData(processPriority); + idx = ui->processPriority->findData(processPriority); if (idx == -1) idx = ui->processPriority->findData("Normal"); ui->processPriority->setCurrentIndex(idx); @@ -2473,6 +2514,10 @@ void OBSBasicSettings::SaveAdvancedSettings() SaveCombo(ui->colorFormat, "Video", "ColorFormat"); SaveCombo(ui->colorSpace, "Video", "ColorSpace"); SaveComboData(ui->colorRange, "Video", "ColorRange"); +#if defined(_WIN32) || defined(__APPLE__) + SaveCombo(ui->monitoringDevice, "Audio", "MonitoringDeviceName"); + SaveComboData(ui->monitoringDevice, "Audio", "MonitoringDeviceId"); +#endif SaveEdit(ui->filenameFormatting, "Output", "FilenameFormatting"); SaveEdit(ui->simpleRBPrefix, "SimpleOutput", "RecRBPrefix"); SaveEdit(ui->simpleRBSuffix, "SimpleOutput", "RecRBSuffix"); @@ -2484,6 +2529,13 @@ void OBSBasicSettings::SaveAdvancedSettings() SaveSpinBox(ui->reconnectRetryDelay, "Output", "RetryDelay"); SaveSpinBox(ui->reconnectMaxRetries, "Output", "MaxRetries"); SaveComboData(ui->bindToIP, "Output", "BindIP"); + +#if defined(_WIN32) || defined(__APPLE__) + obs_set_audio_monitoring_device( + QT_TO_UTF8(ui->monitoringDevice->currentText()), + QT_TO_UTF8(ui->monitoringDevice->currentData() + .toString())); +#endif } static inline const char *OutputModeFromIdx(int idx) @@ -3429,6 +3481,23 @@ void OBSBasicSettings::FillSimpleStreamingValues() #undef ENCODER_STR } +void OBSBasicSettings::FillAudioMonitoringDevices() +{ + QComboBox *cb = ui->monitoringDevice; + + auto enum_devices = [] (void *param, const char *name, const char *id) + { + QComboBox *cb = (QComboBox*)param; + cb->addItem(name, id); + return true; + }; + + cb->addItem(QTStr("Basic.Settings.Advanced.Audio.MonitoringDevice" + ".Default"), "default"); + + obs_enum_audio_monitoring_devices(enum_devices, cb); +} + void OBSBasicSettings::SimpleRecordingQualityChanged() { QString qual = ui->simpleOutRecQuality->currentData().toString(); diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp index ee76167fe..2064fd4bf 100644 --- a/UI/window-basic-settings.hpp +++ b/UI/window-basic-settings.hpp @@ -240,6 +240,7 @@ private: void FillSimpleRecordingValues(); void FillSimpleStreamingValues(); + void FillAudioMonitoringDevices(); void RecalcOutputResPixels(const char *resText);