Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/sphinx/reference-sources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,10 @@ The following signals are defined for every source type:

Called when the source is muted/unmuted.

**monitor_enable** (ptr source, bool enabled)

Called when the source audio monitor is enabled/disabled.

**push_to_mute_changed** (ptr source, bool enabled)

Called when push-to-mute has been enabled/disabled.
Expand Down Expand Up @@ -1166,6 +1170,13 @@ General Source Functions

---------------------

.. function:: bool obs_source_monitor_enabled(const obs_source_t *source)
void obs_source_set_monitor_enabled(obs_source_t *source, bool muted)

Sets/gets whether the source's audio monitor is enabled.

---------------------

.. function:: enum speaker_layout obs_source_get_speaker_layout(obs_source_t *source)

Gets the current speaker layout.
Expand Down
74 changes: 0 additions & 74 deletions frontend/components/OBSAdvAudioCtrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) : source(
percent = new QSpinBox();
forceMono = new QCheckBox();
balance = new BalanceSlider();
if (obs_audio_monitoring_available())
monitoringType = new QComboBox();
syncOffset = new QSpinBox();
mixer1 = new QCheckBox();
mixer2 = new QCheckBox();
Expand All @@ -56,8 +54,6 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) : source(
sigs.emplace_back(handler, "volume", OBSSourceVolumeChanged, this);
sigs.emplace_back(handler, "audio_sync", OBSSourceSyncChanged, this);
sigs.emplace_back(handler, "update_flags", OBSSourceFlagsChanged, this);
if (obs_audio_monitoring_available())
sigs.emplace_back(handler, "audio_monitoring", OBSSourceMonitoringTypeChanged, this);
sigs.emplace_back(handler, "audio_mixers", OBSSourceMixersChanged, this);
sigs.emplace_back(handler, "audio_balance", OBSSourceBalanceChanged, this);
sigs.emplace_back(handler, "rename", OBSSourceRenamed, this);
Expand Down Expand Up @@ -147,20 +143,6 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) : source(
syncOffset->setFixedWidth(100);
syncOffset->setAccessibleName(QTStr("Basic.AdvAudio.SyncOffsetSource").arg(sourceName));

int idx;
if (obs_audio_monitoring_available()) {
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);
monitoringType->setAccessibleName(QTStr("Basic.AdvAudio.MonitoringSource").arg(sourceName));
monitoringType->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
}

mixer1->setText("1");
mixer1->setChecked(mixers & (1 << 0));
mixer1->setAccessibleName(QTStr("Basic.Settings.Output.Adv.Audio.Track1"));
Expand Down Expand Up @@ -203,8 +185,6 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) : source(
connect(balance, &BalanceSlider::valueChanged, this, &OBSAdvAudioCtrl::balanceChanged);
connect(balance, &BalanceSlider::doubleClicked, this, &OBSAdvAudioCtrl::ResetBalance);
connect(syncOffset, &QSpinBox::valueChanged, this, &OBSAdvAudioCtrl::syncOffsetChanged);
if (obs_audio_monitoring_available())
connect(monitoringType, &QComboBox::currentIndexChanged, this, &OBSAdvAudioCtrl::monitoringTypeChanged);

auto connectMixer = [this](QCheckBox *mixer, int num) {
connect(mixer, &QCheckBox::clicked, [this, num](bool checked) { setMixer(source, num, checked); });
Expand All @@ -228,8 +208,6 @@ OBSAdvAudioCtrl::~OBSAdvAudioCtrl()
forceMono->deleteLater();
balanceContainer->deleteLater();
syncOffset->deleteLater();
if (obs_audio_monitoring_available())
monitoringType->deleteLater();
mixerContainer->deleteLater();
}

Expand All @@ -245,8 +223,6 @@ void OBSAdvAudioCtrl::ShowAudioControl(QGridLayout *layout)
layout->addWidget(forceMono, lastRow, idx++);
layout->addWidget(balanceContainer, lastRow, idx++);
layout->addWidget(syncOffset, lastRow, idx++);
if (obs_audio_monitoring_available())
layout->addWidget(monitoringType, lastRow, idx++);
layout->addWidget(mixerContainer, lastRow, idx++);
layout->layout()->setAlignment(mixerContainer, Qt::AlignVCenter);
layout->setHorizontalSpacing(15);
Expand Down Expand Up @@ -283,13 +259,6 @@ void OBSAdvAudioCtrl::OBSSourceSyncChanged(void *param, calldata_t *calldata)
QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceSyncChanged", Q_ARG(int64_t, offset));
}

void OBSAdvAudioCtrl::OBSSourceMonitoringTypeChanged(void *param, calldata_t *calldata)
{
int type = calldata_int(calldata, "type");
QMetaObject::invokeMethod(static_cast<OBSAdvAudioCtrl *>(param), "SourceMonitoringTypeChanged",
Q_ARG(int, type));
}

void OBSAdvAudioCtrl::OBSSourceMixersChanged(void *param, calldata_t *calldata)
{
uint32_t mixers = (uint32_t)calldata_int(calldata, "mixers");
Expand Down Expand Up @@ -361,14 +330,6 @@ void OBSAdvAudioCtrl::SourceSyncChanged(int64_t offset)
syncOffset->blockSignals(false);
}

void OBSAdvAudioCtrl::SourceMonitoringTypeChanged(int type)
{
int idx = monitoringType->findData(type);
monitoringType->blockSignals(true);
monitoringType->setCurrentIndex(idx);
monitoringType->blockSignals(false);
}

void OBSAdvAudioCtrl::SourceMixersChanged(uint32_t mixers)
{
setCheckboxState(mixer1, mixers & (1 << 0));
Expand Down Expand Up @@ -517,41 +478,6 @@ void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds)
std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid, true);
}

void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
{
obs_monitoring_type prev = obs_source_get_monitoring_type(source);

obs_monitoring_type mt = (obs_monitoring_type)monitoringType->itemData(index).toInt();
obs_source_set_monitoring_type(source, mt);

const char *type = nullptr;

switch (mt) {
case OBS_MONITORING_TYPE_NONE:
type = "none";
break;
case OBS_MONITORING_TYPE_MONITOR_ONLY:
type = "monitor only";
break;
case OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT:
type = "monitor and output";
break;
}

const char *name = obs_source_get_name(source);
blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s", name ? name : "(null)", type);

auto undo_redo = [](const std::string &uuid, obs_monitoring_type val) {
OBSSourceAutoRelease source = obs_get_source_by_uuid(uuid.c_str());
obs_source_set_monitoring_type(source, val);
};

const char *uuid = obs_source_get_uuid(source);
OBSBasic::Get()->undo_s.add_action(QTStr("Undo.MonitoringType.Change").arg(name),
std::bind(undo_redo, std::placeholders::_1, prev),
std::bind(undo_redo, std::placeholders::_1, mt), uuid, uuid);
}

static inline void setMixer(obs_source_t *source, const int mixerIdx, const bool checked)
{
uint32_t mixers = obs_source_get_audio_mixers(source);
Expand Down
4 changes: 0 additions & 4 deletions frontend/components/OBSAdvAudioCtrl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class OBSAdvAudioCtrl : public QObject {
QPointer<QLabel> labelL;
QPointer<QLabel> labelR;
QPointer<QSpinBox> syncOffset;
QPointer<QComboBox> monitoringType;
QPointer<QCheckBox> mixer1;
QPointer<QCheckBox> mixer2;
QPointer<QCheckBox> mixer3;
Expand All @@ -55,7 +54,6 @@ class OBSAdvAudioCtrl : public QObject {
static void OBSSourceFlagsChanged(void *param, calldata_t *calldata);
static void OBSSourceVolumeChanged(void *param, calldata_t *calldata);
static void OBSSourceSyncChanged(void *param, calldata_t *calldata);
static void OBSSourceMonitoringTypeChanged(void *param, calldata_t *calldata);
static void OBSSourceMixersChanged(void *param, calldata_t *calldata);
static void OBSSourceBalanceChanged(void *param, calldata_t *calldata);
static void OBSSourceRenamed(void *param, calldata_t *calldata);
Expand All @@ -75,7 +73,6 @@ public slots:
void SourceFlagsChanged(uint32_t flags);
void SourceVolumeChanged(float volume);
void SourceSyncChanged(int64_t offset);
void SourceMonitoringTypeChanged(int type);
void SourceMixersChanged(uint32_t mixers);
void SourceBalanceChanged(int balance);
void SetSourceName(QString newName);
Expand All @@ -85,6 +82,5 @@ public slots:
void downmixMonoChanged(bool checked);
void balanceChanged(int val);
void syncOffsetChanged(int milliseconds);
void monitoringTypeChanged(int index);
void ResetBalance();
};
3 changes: 3 additions & 0 deletions frontend/data/locale/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ Undo.Transform.HCenter="Horizontal Center to Screen in '%1'"
Undo.Volume.Change="Volume Change on '%1'"
Undo.Volume.Mute="Mute '%1'"
Undo.Volume.Unmute="Unmute '%1'"
Undo.Monitor.Enable="Enable Audio Monitor '%1'"
Undo.Monitor.Disable="Disable Audio Monitor '%1'"
Undo.Balance.Change="Audio Balance Change on '%1'"
Undo.SyncOffset.Change="Audio Sync Offset Change on '%1'"
Undo.MonitoringType.Change="Change Audio Monitoring on '%1'"
Expand Down Expand Up @@ -594,6 +596,7 @@ VolControl.Mute="Mute '%1'"
VolControl.Properties="Properties for '%1'"
VolControl.UnassignedWarning.Title="Unassigned Audio Source"
VolControl.UnassignedWarning.Text="\"%1\" is not assigned to any audio tracks and it will not be audible in streams or recordings.\n\nTo assign an audio source to a track, open the Advanced Audio Properties via the right-click menu or the cog button in the mixer dock toolbar."
VolControl.Monitor="Set audio monitor for '%1'"

# add scene dialog
Basic.Main.AddSceneDlg.Title="Add Scene"
Expand Down
4 changes: 4 additions & 0 deletions frontend/data/themes/Dark/headphones-on.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions frontend/data/themes/Light/headphones-on.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions frontend/data/themes/System.obt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@
image: url(:/settings/images/settings/audio.svg);
}

.indicator-headphones {
outline: none;
}

.indicator-headphones::indicator:checked {
image: url(:/res/images/headphones-on.svg);
}

.indicator-headphones::indicator:unchecked {
image: url(:/res/images/headphones-off.svg);
}

.indicator-expand {
background: transparent;
outline: none;
Expand Down
65 changes: 65 additions & 0 deletions frontend/data/themes/Yami.obt
Original file line number Diff line number Diff line change
Expand Up @@ -1834,6 +1834,71 @@ QTableView::indicator:unchecked:disabled {
image: url(theme:Dark/settings/audio.svg);
}

/* Headphone CheckBox */

.indicator-headphones {
outline: none;
}

.indicator-headphones::indicator,
.indicator-headphones::indicator:unchecked {
width: var(--icon_base);
height: var(--icon_base);
background-color: var(--button_bg);
padding: var(--padding_base_border) var(--padding_base_border);
margin: 0px;
border: var(--highlight_width) solid var(--button_border);
border-radius: var(--border_radius);
icon-size: var(--icon_base);
}

.indicator-headphones::indicator:hover,
.indicator-headphones::indicator:unchecked:hover {
background-color: var(--button_bg_hover);
padding: var(--padding_base_border) var(--padding_base_border);
margin: 0px;
border: var(--highlight_width) solid var(--button_border_hover);
icon-size: var(--icon_base);
}

.indicator-headphones::indicator:pressed,
.indicator-headphones::indicator:pressed:hover {
background-color: var(--button_bg_down);
border-color: var(--button_border);
}

.indicator-headphones::indicator:checked {
image: url(theme:Dark/headphones-on.svg);
}

.indicator-headphones::indicator:unchecked {
image: url(:/res/images/headphones-off.svg);
}

.indicator-headphones::indicator:unchecked:hover {
image: url(:/res/images/headphones-off.svg);
}

.indicator-headphones::indicator:unchecked:focus {
image: url(:/res/images/headphones-off.svg);
}

.indicator-headphones::indicator:checked:hover {
image: url(theme:Dark/headphones-on.svg);
}

.indicator-headphones::indicator:checked:focus {
image: url(theme:Dark/headphones-on.svg);
}

.indicator-headphones::indicator:checked:disabled {
image: url(theme:Dark/headphones-on.svg);
}

.indicator-headphones::indicator:unchecked:disabled {
image: url(:/res/images/headphones-off.svg);
}

#hotkeyFilterReset {
margin-top: 0px;
}
Expand Down
32 changes: 32 additions & 0 deletions frontend/data/themes/Yami_Light.ovt
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,38 @@ QTableView::indicator:unchecked:disabled {
image: url(theme:Light/settings/audio.svg);
}

.indicator-headphones::indicator:checked {
image: url(theme:Light/headphones-on.svg);
}

.indicator-headphones::indicator:unchecked {
image: url(:/res/images/headphones-off.svg);
}

.indicator-headphones::indicator:unchecked:hover {
image: url(:/res/images/headphones-off.svg);
}

.indicator-headphones::indicator:unchecked:focus {
image: url(:/res/images/headphones-off.svg);
}

.indicator-headphones::indicator:checked:hover {
image: url(theme:Light/headphones-on.svg);
}

.indicator-headphones::indicator:checked:focus {
image: url(theme:Light/headphones-on.svg);
}

.indicator-headphones::indicator:checked:disabled {
image: url(theme:Light/headphones-on.svg);
}

.indicator-headphones::indicator:unchecked:disabled {
image: url(:/res/images/headphones-off.svg);
}

.indicator-expand::indicator:checked,
.indicator-expand::indicator:checked:hover {
image: url(theme:Light/expand.svg);
Expand Down
Loading
Loading