Browse Source

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.
jp9000 8 years ago
parent
commit
7639b277ce

+ 41 - 6
UI/adv-audio-control.cpp

@@ -2,9 +2,11 @@
 #include <QGridLayout>
 #include <QLabel>
 #include <QSpinBox>
+#include <QComboBox>
 #include <QCheckBox>
 #include <QSlider>
 #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)
 {

+ 3 - 0
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<QLabel>       labelL;
 	QPointer<QLabel>       labelR;
 	QPointer<QSpinBox>     syncOffset;
+	QPointer<QComboBox>    monitoringType;
 	QPointer<QCheckBox>    mixer1;
 	QPointer<QCheckBox>    mixer2;
 	QPointer<QCheckBox>    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);

+ 6 - 0
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

+ 27 - 4
UI/forms/OBSBasicSettings.ui

@@ -2936,8 +2936,8 @@
              <rect>
               <x>0</x>
               <y>0</y>
-              <width>80</width>
-              <height>16</height>
+              <width>98</width>
+              <height>28</height>
              </rect>
             </property>
            </widget>
@@ -3255,8 +3255,8 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>818</width>
-           <height>697</height>
+           <width>98</width>
+           <height>28</height>
           </rect>
          </property>
          <layout class="QFormLayout" name="hotkeyLayout">
@@ -3531,6 +3531,28 @@
                   </layout>
                  </widget>
                 </item>
+                <item>
+                 <widget class="QGroupBox" name="advAudioGroupBox">
+                  <property name="title">
+                   <string>Basic.Settings.Audio</string>
+                  </property>
+                  <layout class="QFormLayout" name="formLayout_27">
+                   <item row="0" column="0">
+                    <widget class="QLabel" name="monitoringDeviceLabel">
+                     <property name="text">
+                      <string>Basic.Settings.Advanced.Audio.MonitoringDevice</string>
+                     </property>
+                     <property name="buddy">
+                      <cstring>monitoringDevice</cstring>
+                     </property>
+                    </widget>
+                   </item>
+                   <item row="0" column="1">
+                    <widget class="QComboBox" name="monitoringDevice"/>
+                   </item>
+                  </layout>
+                 </widget>
+                </item>
                 <item>
                  <widget class="QGroupBox" name="groupBox_6">
                   <property name="title">
@@ -3974,6 +3996,7 @@
   <tabstop>colorRange</tabstop>
   <tabstop>disableOSXVSync</tabstop>
   <tabstop>resetOSXVSync</tabstop>
+  <tabstop>monitoringDevice</tabstop>
   <tabstop>filenameFormatting</tabstop>
   <tabstop>overwriteIfExists</tabstop>
   <tabstop>simpleRBPrefix</tabstop>

+ 1 - 0
UI/volume-control.cpp

@@ -3,6 +3,7 @@
 #include "mute-checkbox.hpp"
 #include "slider-absoluteset-style.hpp"
 #include <util/platform.h>
+#include <util/threading.h>
 #include <QHBoxLayout>
 #include <QVBoxLayout>
 #include <QPushButton>

+ 12 - 6
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);

+ 5 - 0
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");

+ 70 - 1
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<QStandardItemModel*>(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();

+ 1 - 0
UI/window-basic-settings.hpp

@@ -240,6 +240,7 @@ private:
 
 	void FillSimpleRecordingValues();
 	void FillSimpleStreamingValues();
+	void FillAudioMonitoringDevices();
 
 	void RecalcOutputResPixels(const char *resText);