diff --git a/docs/sphinx/reference-sources.rst b/docs/sphinx/reference-sources.rst index 6b91e34c477e5e..8dbfee582732c7 100644 --- a/docs/sphinx/reference-sources.rst +++ b/docs/sphinx/reference-sources.rst @@ -1210,6 +1210,9 @@ General Source Functions .. function:: void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type) enum obs_monitoring_type obs_source_get_monitoring_type(obs_source_t *source) + .. deprecated:: 33.0 + Use :c:func:`obs_source_set_monitoring_enabled` and :c:func:`obs_source_get_monitoring_enabled` instead. + Sets/gets the desktop audio monitoring type. :param order: | OBS_MONITORING_TYPE_NONE - Do not monitor @@ -1218,6 +1221,16 @@ General Source Functions --------------------- +.. function:: void obs_source_set_monitoring_enabled(obs_source_t *source, bool enable) + bool obs_source_get_monitoring_enabled(const obs_source_t *source) + + + Sets/gets the audio monitoring enabled state for the source. + + .. versionadded:: 33.0 + +--------------------- + .. function:: void obs_source_set_audio_active(obs_source_t *source, bool active) bool obs_source_audio_active(const obs_source_t *source) diff --git a/frontend/components/OBSAdvAudioCtrl.cpp b/frontend/components/OBSAdvAudioCtrl.cpp index 2f3766f4e5fd7b..1266c3a8a17e7d 100644 --- a/frontend/components/OBSAdvAudioCtrl.cpp +++ b/frontend/components/OBSAdvAudioCtrl.cpp @@ -40,9 +40,8 @@ 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(); - } + monitoringCheckBox = new QCheckBox(); + syncOffset = new QSpinBox(); mixer1 = new QCheckBox(); mixer2 = new QCheckBox(); @@ -58,9 +57,7 @@ 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, "monitor", OBSSourceMonitoringChanged, this); sigs.emplace_back(handler, "audio_mixers", OBSSourceMixersChanged, this); sigs.emplace_back(handler, "audio_balance", OBSSourceBalanceChanged, this); sigs.emplace_back(handler, "rename", OBSSourceRenamed, this); @@ -152,19 +149,11 @@ 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); - } + monitoringCheckBox->setEnabled(obs_audio_monitoring_available()); + monitoringCheckBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + monitoringCheckBox->setText(QTStr("Enable")); + monitoringCheckBox->setChecked(obs_source_get_monitoring_enabled(source)); + monitoringCheckBox->setAccessibleName(QTStr("Basic.AdvAudio.MonitoringSource").arg(sourceName)); mixer1->setText("1"); mixer1->setChecked(mixers & (1 << 0)); @@ -209,9 +198,7 @@ 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); - } + connect(monitoringCheckBox, &QCheckBox::toggled, this, &OBSAdvAudioCtrl::monitoringChanged); auto connectMixer = [this](QCheckBox *mixer, int num) { connect(mixer, &QCheckBox::clicked, this, @@ -236,9 +223,7 @@ OBSAdvAudioCtrl::~OBSAdvAudioCtrl() forceMono->deleteLater(); balanceContainer->deleteLater(); syncOffset->deleteLater(); - if (obs_audio_monitoring_available()) { - monitoringType->deleteLater(); - } + monitoringCheckBox->deleteLater(); mixerContainer->deleteLater(); } @@ -254,9 +239,7 @@ 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(monitoringCheckBox, lastRow, idx++); layout->addWidget(mixerContainer, lastRow, idx++); layout->layout()->setAlignment(mixerContainer, Qt::AlignVCenter); layout->setHorizontalSpacing(15); @@ -293,11 +276,11 @@ void OBSAdvAudioCtrl::OBSSourceSyncChanged(void *param, calldata_t *calldata) QMetaObject::invokeMethod(static_cast(param), "SourceSyncChanged", Q_ARG(int64_t, offset)); } -void OBSAdvAudioCtrl::OBSSourceMonitoringTypeChanged(void *param, calldata_t *calldata) +void OBSAdvAudioCtrl::OBSSourceMonitoringChanged(void *param, calldata_t *calldata) { - int type = calldata_int(calldata, "type"); - QMetaObject::invokeMethod(static_cast(param), "SourceMonitoringTypeChanged", - Q_ARG(int, type)); + bool enabled = calldata_bool(calldata, "monitor"); + QMetaObject::invokeMethod(static_cast(param), "SourceMonitoringChanged", + Q_ARG(bool, enabled)); } void OBSAdvAudioCtrl::OBSSourceMixersChanged(void *param, calldata_t *calldata) @@ -371,12 +354,11 @@ void OBSAdvAudioCtrl::SourceSyncChanged(int64_t offset) syncOffset->blockSignals(false); } -void OBSAdvAudioCtrl::SourceMonitoringTypeChanged(int type) +void OBSAdvAudioCtrl::SourceMonitoringChanged(bool enabled) { - int idx = monitoringType->findData(type); - monitoringType->blockSignals(true); - monitoringType->setCurrentIndex(idx); - monitoringType->blockSignals(false); + monitoringCheckBox->blockSignals(true); + monitoringCheckBox->setChecked(enabled); + monitoringCheckBox->blockSignals(false); } void OBSAdvAudioCtrl::SourceMixersChanged(uint32_t mixers) @@ -531,39 +513,25 @@ void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds) std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid, true); } -void OBSAdvAudioCtrl::monitoringTypeChanged(int index) +void OBSAdvAudioCtrl::monitoringChanged(bool enabled) { - obs_monitoring_type prev = obs_source_get_monitoring_type(source); + bool prev = obs_source_get_monitoring_enabled(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; - } + obs_source_set_monitoring_enabled(source, enabled); const char *name = obs_source_get_name(source); - blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s", name ? name : "(null)", type); + blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s", name ? name : "(null)", + enabled ? "true" : " false"); - auto undo_redo = [](const std::string &uuid, obs_monitoring_type val) { + auto undo_redo = [](const std::string &uuid, bool val) { OBSSourceAutoRelease source = obs_get_source_by_uuid(uuid.c_str()); - obs_source_set_monitoring_type(source, val); + obs_source_set_monitoring_enabled(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); + std::bind(undo_redo, std::placeholders::_1, enabled), uuid, uuid); } static inline void setMixer(obs_source_t *source, const int mixerIdx, const bool checked) diff --git a/frontend/components/OBSAdvAudioCtrl.hpp b/frontend/components/OBSAdvAudioCtrl.hpp index 6d12b3044b010f..e194088a4f31c3 100644 --- a/frontend/components/OBSAdvAudioCtrl.hpp +++ b/frontend/components/OBSAdvAudioCtrl.hpp @@ -40,7 +40,7 @@ class OBSAdvAudioCtrl : public QObject { QPointer labelL; QPointer labelR; QPointer syncOffset; - QPointer monitoringType; + QPointer monitoringCheckBox; QPointer mixer1; QPointer mixer2; QPointer mixer3; @@ -55,7 +55,7 @@ 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 OBSSourceMonitoringChanged(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); @@ -75,7 +75,7 @@ public slots: void SourceFlagsChanged(uint32_t flags); void SourceVolumeChanged(float volume); void SourceSyncChanged(int64_t offset); - void SourceMonitoringTypeChanged(int type); + void SourceMonitoringChanged(bool enabled); void SourceMixersChanged(uint32_t mixers); void SourceBalanceChanged(int balance); void SetSourceName(QString newName); @@ -85,6 +85,6 @@ public slots: void downmixMonoChanged(bool checked); void balanceChanged(int val); void syncOffsetChanged(int milliseconds); - void monitoringTypeChanged(int index); + void monitoringChanged(bool enabled); void ResetBalance(); }; diff --git a/frontend/components/VolumeControl.cpp b/frontend/components/VolumeControl.cpp index 57a881df7c9599..f569f5b5409564 100644 --- a/frontend/components/VolumeControl.cpp +++ b/frontend/components/VolumeControl.cpp @@ -16,9 +16,8 @@ namespace { bool isSourceUnassigned(obs_source_t *source) { uint32_t mixes = (obs_source_get_audio_mixers(source) & ((1 << MAX_AUDIO_MIXES) - 1)); - obs_monitoring_type mt = obs_source_get_monitoring_type(source); - return mixes == 0 && mt != OBS_MONITORING_TYPE_MONITOR_ONLY; + return mixes == 0; } void showUnassignedWarning(const char *name) @@ -97,7 +96,7 @@ VolumeControl::VolumeControl(obs_source_t *source, QWidget *parent, bool vertica obsMuted = obs_source_muted(source); bool unassigned = isSourceUnassigned(source); - obsMonitoringType = obs_source_get_monitoring_type(source); + obsMonitoring = obs_source_get_monitoring_enabled(source); volumeMeter->setMuted(obsMuted || unassigned); @@ -109,7 +108,7 @@ VolumeControl::VolumeControl(obs_source_t *source, QWidget *parent, bool vertica obsSignals.reserve(9); obsSignals.emplace_back(obs_source_get_signal_handler(source), "mute", obsVolumeMuted, this); obsSignals.emplace_back(obs_source_get_signal_handler(source), "audio_mixers", obsMixersChanged, this); - obsSignals.emplace_back(obs_source_get_signal_handler(source), "audio_monitoring", obsMonitoringChanged, this); + obsSignals.emplace_back(obs_source_get_signal_handler(source), "monitor", obsMonitoringChanged, this); obsSignals.emplace_back(obs_source_get_signal_handler(source), "activate", VolumeControl::obsSourceActivated, this); obsSignals.emplace_back(obs_source_get_signal_handler(source), "deactivate", @@ -218,9 +217,9 @@ void VolumeControl::obsMixersChanged(void *data, calldata_t *) void VolumeControl::obsMonitoringChanged(void *data, calldata_t *params) { VolumeControl *volControl = static_cast(data); - auto type = static_cast(calldata_int(params, "type")); + bool enable = calldata_bool(params, "monitor"); - QMetaObject::invokeMethod(volControl, "onMonitoringChanged", Qt::QueuedConnection, Q_ARG(int, type)); + QMetaObject::invokeMethod(volControl, "onMonitoringChanged", Qt::QueuedConnection, Q_ARG(bool, enable)); } void VolumeControl::obsSourceActivated(void *data, calldata_t *) @@ -608,9 +607,9 @@ void VolumeControl::onMuteChanged(bool muted) processMixerState(); } -void VolumeControl::onMonitoringChanged(int type) +void VolumeControl::onMonitoringChanged(bool enabled) { - obsMonitoringType = static_cast(type); + obsMonitoring = enabled; processMixerState(); } @@ -719,27 +718,26 @@ void VolumeControl::setMuted(bool mute) std::bind(undo_redo, std::placeholders::_1, mute), uuid, uuid); } -void VolumeControl::setMonitoring(obs_monitoring_type type) +void VolumeControl::setMonitoring(bool enabled) { OBSSource source = OBSGetStrongRef(weakSource()); if (!source) { return; } - obs_monitoring_type prevMonitoringType = obs_source_get_monitoring_type(source); - obs_source_set_monitoring_type(source, type); + bool prevMonitoring = obs_source_get_monitoring_enabled(source); + obs_source_set_monitoring_enabled(source, enabled); - auto undo_redo = [](const std::string &uuid, obs_monitoring_type val) { + auto undo_redo = [](const std::string &uuid, bool val) { OBSSourceAutoRelease source = obs_get_source_by_uuid(uuid.c_str()); - obs_source_set_monitoring_type(source, val); + obs_source_set_monitoring_enabled(source, val); }; QString text = QTStr("Undo.MonitoringType.Change"); const char *name = obs_source_get_name(source); - OBSBasic::Get()->undo_s.add_action(text.arg(name), - std::bind(undo_redo, std::placeholders::_1, prevMonitoringType), - std::bind(undo_redo, std::placeholders::_1, type), uuid, uuid); + OBSBasic::Get()->undo_s.add_action(text.arg(name), std::bind(undo_redo, std::placeholders::_1, prevMonitoring), + std::bind(undo_redo, std::placeholders::_1, enabled), uuid, uuid); } void VolumeControl::onSourceActiveChanged(bool active) @@ -770,8 +768,8 @@ void VolumeControl::processMixerState() QSignalBlocker blockMute(muteButton); QSignalBlocker blockMonitor(monitorButton); - bool showAsMuted = obsMuted || obsMonitoringType == OBS_MONITORING_TYPE_MONITOR_ONLY; - bool showAsMonitored = obsMonitoringType != OBS_MONITORING_TYPE_NONE; + bool showAsMuted = obsMuted; + bool showAsMonitored = obsMonitoring; bool showAsUnassigned = !obsMuted && unassigned; volumeMeter->setMuted((showAsMuted || showAsUnassigned) && !showAsMonitored); @@ -817,28 +815,11 @@ void VolumeControl::processMixerState() void VolumeControl::handleMuteButton(bool mute) { setMuted(mute); - - if (obsMonitoringType != OBS_MONITORING_TYPE_NONE) { - if (mute) { - setMonitoring(OBS_MONITORING_TYPE_MONITOR_ONLY); - } else { - setMonitoring(OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); - } - } } void VolumeControl::handleMonitorButton(bool enableMonitoring) { - if (!enableMonitoring) { - setMonitoring(OBS_MONITORING_TYPE_NONE); - return; - } - - if (obsMuted) { - setMonitoring(OBS_MONITORING_TYPE_MONITOR_ONLY); - } else { - setMonitoring(OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); - } + setMonitoring(enableMonitoring); } void VolumeControl::sliderChanged(int vol) diff --git a/frontend/components/VolumeControl.hpp b/frontend/components/VolumeControl.hpp index 3b81899e181fff..29c898c32e586d 100644 --- a/frontend/components/VolumeControl.hpp +++ b/frontend/components/VolumeControl.hpp @@ -71,7 +71,7 @@ class VolumeControl : public QFrame { OBSWeakSource weakSource_; const char *uuid; std::vector obsSignals; - obs_monitoring_type obsMonitoringType; + bool obsMonitoring; bool obsMuted; QBoxLayout *mainLayout; @@ -112,7 +112,7 @@ class VolumeControl : public QFrame { void updatePeakMeterType(); void setMuted(bool mute); - void setMonitoring(obs_monitoring_type type); + void setMonitoring(bool enabled); public slots: void setUseDisabledColors(bool greyscale); @@ -131,7 +131,7 @@ private slots: void onSourceActiveChanged(bool active); void onMuteChanged(bool muted); - void onMonitoringChanged(int type); + void onMonitoringChanged(bool enabled); void onSourceDestroyed() { deleteLater(); } signals: diff --git a/frontend/data/locale/en-US.ini b/frontend/data/locale/en-US.ini index 51ea30b4aa1186..df4ffcc12cfab8 100644 --- a/frontend/data/locale/en-US.ini +++ b/frontend/data/locale/en-US.ini @@ -1452,6 +1452,8 @@ Mute="Mute" Unmute="Unmute" Push-to-mute="Push-to-mute" Push-to-talk="Push-to-talk" +MonitorOn="Enable Monitoring" +MonitorOff="Disable Monitoring" # scene item hotkeys SceneItemShow="Show '%1'" diff --git a/frontend/widgets/OBSBasic_Hotkeys.cpp b/frontend/widgets/OBSBasic_Hotkeys.cpp index c18e7a45987fcb..f549c97d9d86c1 100644 --- a/frontend/widgets/OBSBasic_Hotkeys.cpp +++ b/frontend/widgets/OBSBasic_Hotkeys.cpp @@ -67,8 +67,8 @@ void OBSBasic::InitHotkeys() t.escape = Str("Hotkeys.Escape"); obs_hotkeys_set_translations(&t); - obs_hotkeys_set_audio_hotkeys_translations(Str("Mute"), Str("Unmute"), Str("Push-to-mute"), - Str("Push-to-talk")); + obs_hotkeys_set_audio_hotkeys_translations(Str("Mute"), Str("Unmute"), Str("Push-to-mute"), Str("Push-to-talk"), + Str("MonitorOn"), Str("MonitorOff")); obs_hotkeys_set_sceneitem_hotkeys_translations(Str("SceneItemShow"), Str("SceneItemHide")); diff --git a/frontend/widgets/OBSBasic_SceneCollections.cpp b/frontend/widgets/OBSBasic_SceneCollections.cpp index fbbcc37b5d9725..a8c21b2004e234 100644 --- a/frontend/widgets/OBSBasic_SceneCollections.cpp +++ b/frontend/widgets/OBSBasic_SceneCollections.cpp @@ -1021,12 +1021,9 @@ static void LoadAudioDevice(const char *name, int channel, obs_data_t *parent) const char *source_name = obs_source_get_name(source); blog(LOG_INFO, "[Loaded global audio device]: '%s'", source_name); obs_source_enum_filters(source, LogFilter, (void *)(intptr_t)1); - obs_monitoring_type monitoring_type = obs_source_get_monitoring_type(source); - if (monitoring_type != OBS_MONITORING_TYPE_NONE) { - const char *type = (monitoring_type == OBS_MONITORING_TYPE_MONITOR_ONLY) ? "monitor only" - : "monitor and output"; - - blog(LOG_INFO, " - monitoring: %s", type); + bool monitoring = obs_source_get_monitoring_enabled(source); + if (monitoring) { + blog(LOG_INFO, " - monitoring: enabled"); } } @@ -1081,13 +1078,10 @@ static bool LogSceneItem(obs_scene_t *, obs_sceneitem_t *item, void *v_val) blog(LOG_INFO, "%s- source: '%s' (%s)", indent.c_str(), name, id); - obs_monitoring_type monitoring_type = obs_source_get_monitoring_type(source); - - if (monitoring_type != OBS_MONITORING_TYPE_NONE) { - const char *type = (monitoring_type == OBS_MONITORING_TYPE_MONITOR_ONLY) ? "monitor only" - : "monitor and output"; + bool monitoring = obs_source_get_monitoring_enabled(source); - blog(LOG_INFO, " %s- monitoring: %s", indent.c_str(), type); + if (monitoring) { + blog(LOG_INFO, " %s- monitoring: enabled", indent.c_str()); } int child_indent = 1 + indent_count; obs_source_enum_filters(source, LogFilter, (void *)(intptr_t)child_indent); diff --git a/libobs/obs-audio.c b/libobs/obs-audio.c index f016c0505e4800..3b6c0c96e3dd26 100644 --- a/libobs/obs-audio.c +++ b/libobs/obs-audio.c @@ -517,15 +517,11 @@ static inline bool should_silence_monitored_source(obs_source_t *source, struct if (!dup_src || !obs_source_active(dup_src)) return false; - if (dup_src->monitoring_type == OBS_MONITORING_TYPE_MONITOR_ONLY) - return false; - bool fader_muted = close_float(audio->monitoring_duplicating_source->volume, 0.0f, 0.0001f); bool output_capture_unmuted = !audio->monitoring_duplicating_source->muted && !fader_muted; if (output_capture_unmuted) { - if (source->monitoring_type == OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT && - source != audio->monitoring_duplicating_source) { + if (source->monitoring_enabled && source != audio->monitoring_duplicating_source) { return true; } } diff --git a/libobs/obs-hotkey.c b/libobs/obs-hotkey.c index 0503b303390409..dd89db079ceb37 100644 --- a/libobs/obs-hotkey.c +++ b/libobs/obs-hotkey.c @@ -1374,7 +1374,8 @@ void obs_hotkey_update_atomic(obs_hotkey_atomic_update_func func, void *data) } void obs_hotkeys_set_audio_hotkeys_translations(const char *mute, const char *unmute, const char *push_to_mute, - const char *push_to_talk) + const char *push_to_talk, const char *monitor_on, + const char *monitor_off) { #define SET_T(n) \ bfree(obs->hotkeys.n); \ @@ -1383,6 +1384,8 @@ void obs_hotkeys_set_audio_hotkeys_translations(const char *mute, const char *un SET_T(unmute); SET_T(push_to_mute); SET_T(push_to_talk); + SET_T(monitor_on); + SET_T(monitor_off); #undef SET_T } diff --git a/libobs/obs-hotkey.h b/libobs/obs-hotkey.h index 0fa6ccc45dd8d2..12e6faa58f2acc 100644 --- a/libobs/obs-hotkey.h +++ b/libobs/obs-hotkey.h @@ -134,7 +134,8 @@ EXPORT void obs_hotkeys_set_translations_s(struct obs_hotkeys_translations *tran obs_hotkeys_set_translations_s(translations, sizeof(struct obs_hotkeys_translations)) EXPORT void obs_hotkeys_set_audio_hotkeys_translations(const char *mute, const char *unmute, const char *push_to_mute, - const char *push_to_talk); + const char *push_to_talk, const char *monitor_on, + const char *monitor_off); EXPORT void obs_hotkeys_set_sceneitem_hotkeys_translations(const char *show, const char *hide); diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index ca5bdac88afdf5..5af83c710b3383 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -537,6 +537,8 @@ struct obs_core_hotkeys { char *push_to_talk; char *sceneitem_show; char *sceneitem_hide; + char *monitor_on; + char *monitor_off; }; typedef DARRAY(struct obs_source_info) obs_source_info_array_t; @@ -991,6 +993,8 @@ struct obs_source { /* audio monitoring */ struct audio_monitor *monitor; enum obs_monitoring_type monitoring_type; + bool monitoring_enabled; + obs_hotkey_pair_id monitor_on_off_key; /* media action queue */ DARRAY(struct media_action) media_actions; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 2e99d9f6d080e6..d659b0b5f08299 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -96,6 +96,7 @@ static const char *source_signals[] = { "void audio_balance(ptr source, in out float balance)", "void audio_mixers(ptr source, in out int mixers)", "void audio_monitoring(ptr source, int type)", + "void monitor(ptr source, bool monitor)", "void audio_activate(ptr source)", "void audio_deactivate(ptr source)", "void filter_add(ptr source, ptr filter)", @@ -348,10 +349,40 @@ static void obs_source_hotkey_push_to_talk(void *data, obs_hotkey_id id, obs_hot source->user_push_to_talk_pressed = pressed; } +static bool obs_source_hotkey_monitor_on(void *data, obs_hotkey_pair_id id, obs_hotkey_t *key, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(key); + + struct obs_source *source = data; + + if (!pressed || obs_source_get_monitoring_enabled(source)) + return false; + + obs_source_set_monitoring_enabled(source, true); + return true; +} + +static bool obs_source_hotkey_monitor_off(void *data, obs_hotkey_pair_id id, obs_hotkey_t *key, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(key); + + struct obs_source *source = data; + + if (!pressed || !obs_source_get_monitoring_enabled(source)) + return false; + + obs_source_set_monitoring_enabled(source, false); + return true; +} + static void obs_source_init_audio_hotkeys(struct obs_source *source) { if (!(source->info.output_flags & OBS_SOURCE_AUDIO) || source->info.type != OBS_SOURCE_TYPE_INPUT) { - source->mute_unmute_key = OBS_INVALID_HOTKEY_ID; + source->mute_unmute_key = OBS_INVALID_HOTKEY_PAIR_ID; + source->monitor_on_off_key = OBS_INVALID_HOTKEY_PAIR_ID; + source->push_to_mute_key = OBS_INVALID_HOTKEY_ID; source->push_to_talk_key = OBS_INVALID_HOTKEY_ID; return; } @@ -361,6 +392,10 @@ static void obs_source_init_audio_hotkeys(struct obs_source *source) obs_source_hotkey_mute, obs_source_hotkey_unmute, source, source); + source->monitor_on_off_key = obs_hotkey_pair_register_source( + source, "libobs.monitor-on", obs->hotkeys.monitor_on, "libobs.monitor-off", obs->hotkeys.monitor_off, + obs_source_hotkey_monitor_on, obs_source_hotkey_monitor_off, source, source); + source->push_to_mute_key = obs_hotkey_register_source(source, "libobs.push-to-mute", obs->hotkeys.push_to_mute, obs_source_hotkey_push_to_mute, source); @@ -458,6 +493,7 @@ static obs_source_t *obs_source_create_internal(const char *id, const char *name } source->mute_unmute_key = OBS_INVALID_HOTKEY_PAIR_ID; + source->monitor_on_off_key = OBS_INVALID_HOTKEY_PAIR_ID; source->push_to_mute_key = OBS_INVALID_HOTKEY_ID; source->push_to_talk_key = OBS_INVALID_HOTKEY_ID; source->last_obs_ver = last_obs_ver; @@ -784,6 +820,7 @@ static void obs_source_destroy_defer(struct obs_source *source) obs_hotkey_unregister(source->push_to_talk_key); obs_hotkey_unregister(source->push_to_mute_key); obs_hotkey_pair_unregister(source->mute_unmute_key); + obs_hotkey_pair_unregister(source->monitor_on_off_key); for (i = 0; i < source->async_cache.num; i++) obs_source_frame_decref(source->async_cache.array[i].frame); @@ -5556,28 +5593,38 @@ void obs_source_remove_audio_capture_callback(obs_source_t *source, obs_source_a pthread_mutex_unlock(&source->audio_cb_mutex); } -void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type) +void obs_source_set_monitoring_enabled(obs_source_t *source, bool enabled) { struct calldata data; + struct calldata compat_data; uint8_t stack[128]; + enum obs_monitoring_type compat_type; bool was_on; - bool now_on; - if (!obs_source_valid(source, "obs_source_set_monitoring_type")) + if (!obs_source_valid(source, "obs_source_set_monitoring_enabled")) return; - if (source->monitoring_type == type) + + if (source->monitoring_enabled == enabled) return; + compat_type = enabled ? OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT : OBS_MONITORING_TYPE_NONE; + calldata_init_fixed(&data, stack, sizeof(stack)); calldata_set_ptr(&data, "source", source); - calldata_set_int(&data, "type", type); + calldata_set_bool(&data, "monitor", enabled); + + calldata_init_fixed(&compat_data, stack, sizeof(stack)); + calldata_set_ptr(&compat_data, "source", source); + calldata_set_int(&compat_data, "type", compat_type); - signal_handler_signal(source->context.signals, "audio_monitoring", &data); + signal_handler_signal(source->context.signals, "monitor", &data); + signal_handler_signal(source->context.signals, "audio_monitoring", &compat_data); - was_on = source->monitoring_type != OBS_MONITORING_TYPE_NONE; - now_on = type != OBS_MONITORING_TYPE_NONE; + was_on = source->monitoring_enabled; + source->monitoring_enabled = enabled; + source->monitoring_type = compat_type; - if (was_on != now_on) { + if (was_on != enabled) { if (!was_on) { source->monitor = audio_monitor_create(source); } else { @@ -5585,12 +5632,29 @@ void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_ty source->monitor = NULL; } } +} - source->monitoring_type = type; +bool obs_source_get_monitoring_enabled(const obs_source_t *source) +{ + return obs_source_valid(source, "obs_source_get_monitoring_enabled") ? source->monitoring_enabled : false; +} + +void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type) +{ + if (!obs_source_valid(source, "obs_source_set_monitoring_type")) + return; + + blog(LOG_WARNING, + "obs_source_set_monitoring_type is deprecated. Use obs_source_set_monitoring_enabled instead."); + + obs_source_set_monitoring_enabled(source, type != OBS_MONITORING_TYPE_NONE); } enum obs_monitoring_type obs_source_get_monitoring_type(const obs_source_t *source) { + blog(LOG_WARNING, + "obs_source_get_monitoring_type is deprecated. Use obs_source_get_monitoring_enabled instead."); + return obs_source_valid(source, "obs_source_get_monitoring_type") ? source->monitoring_type : OBS_MONITORING_TYPE_NONE; } diff --git a/libobs/obs.c b/libobs/obs.c index ba53eecef92836..3e2dac574bd179 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -2354,7 +2354,12 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data, bool is_priva obs_source_set_audio_mixers(source, 0x3F); } } - obs_source_set_monitoring_type(source, (enum obs_monitoring_type)monitoring_type); + + obs_data_set_default_bool(source_data, "monitoring", false); + if (prev_ver < MAKE_SEMANTIC_VERSION(33, 0, 0)) { + obs_data_set_bool(source_data, "monitoring", monitoring_type != OBS_MONITORING_TYPE_NONE); + } + obs_source_set_monitoring_enabled(source, obs_data_get_bool(source_data, "monitoring")); obs_data_release(source->private_settings); source->private_settings = obs_data_get_obj(source_data, "private_settings"); @@ -2456,7 +2461,7 @@ obs_data_t *obs_save_source(obs_source_t *source) uint64_t ptm_delay = obs_source_get_push_to_mute_delay(source); bool push_to_talk = obs_source_push_to_talk_enabled(source); uint64_t ptt_delay = obs_source_get_push_to_talk_delay(source); - int m_type = (int)obs_source_get_monitoring_type(source); + bool monitoring = obs_source_get_monitoring_enabled(source); int di_mode = (int)obs_source_get_deinterlace_mode(source); int di_order = (int)obs_source_get_deinterlace_field_order(source); obs_canvas_t *canvas = obs_source_get_canvas(source); @@ -2492,7 +2497,9 @@ obs_data_t *obs_save_source(obs_source_t *source) obs_data_set_obj(source_data, "hotkeys", hotkey_data); obs_data_set_int(source_data, "deinterlace_mode", di_mode); obs_data_set_int(source_data, "deinterlace_field_order", di_order); - obs_data_set_int(source_data, "monitoring_type", m_type); + obs_data_set_int(source_data, "monitoring_type", + monitoring ? (int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT : (int)OBS_MONITORING_TYPE_NONE); + obs_data_set_int(source_data, "monitoring_enabled", monitoring); if (canvas) { obs_data_set_string(source_data, "canvas_uuid", obs_canvas_get_uuid(canvas)); diff --git a/libobs/obs.h b/libobs/obs.h index 4e51eb4488a0ca..a4c8ffd1a0dc2d 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -1363,8 +1363,11 @@ enum obs_monitoring_type { OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT, }; -EXPORT void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type); -EXPORT enum obs_monitoring_type obs_source_get_monitoring_type(const obs_source_t *source); +EXPORT void obs_source_set_monitoring_enabled(obs_source_t *source, bool enabled); +EXPORT bool obs_source_get_monitoring_enabled(const obs_source_t *source); + +OBS_DEPRECATED EXPORT void obs_source_set_monitoring_type(obs_source_t *source, enum obs_monitoring_type type); +OBS_DEPRECATED EXPORT enum obs_monitoring_type obs_source_get_monitoring_type(const obs_source_t *source); /** Gets private front-end settings data. This data is saved/loaded * automatically. Returns an incremented reference. */ diff --git a/plugins/obs-transitions/transition-stinger.c b/plugins/obs-transitions/transition-stinger.c index fddeb9302055aa..323bfabd077c1f 100644 --- a/plugins/obs-transitions/transition-stinger.c +++ b/plugins/obs-transitions/transition-stinger.c @@ -29,7 +29,7 @@ struct stinger_info { float transition_b_mul; bool transitioning; bool transition_point_is_frame; - int monitoring_type; + bool monitoring; enum fade_style fade_style; bool track_matte_enabled; @@ -136,8 +136,8 @@ static void stinger_update(void *data, obs_data_t *settings) obs_source_set_muted(s->matte_source, true); } - s->monitoring_type = (int)obs_data_get_int(settings, "audio_monitoring"); - obs_source_set_monitoring_type(s->media_source, s->monitoring_type); + s->monitoring = obs_data_get_bool(settings, "enable_monitoring"); + obs_source_set_monitoring_enabled(s->media_source, s->monitoring); s->fade_style = (enum fade_style)obs_data_get_int(settings, "audio_fade_style"); @@ -729,14 +729,7 @@ static obs_properties_t *stinger_properties(void *data) dstr_free(&filter); // audio output settings - obs_property_t *monitor_list = obs_properties_add_list(ppts, "audio_monitoring", - obs_module_text("AudioMonitoring"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(monitor_list, obs_module_text("AudioMonitoring.None"), OBS_MONITORING_TYPE_NONE); - obs_property_list_add_int(monitor_list, obs_module_text("AudioMonitoring.MonitorOnly"), - OBS_MONITORING_TYPE_MONITOR_ONLY); - obs_property_list_add_int(monitor_list, obs_module_text("AudioMonitoring.Both"), - OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); + obs_properties_add_bool(ppts, "enable_monitoring", obs_module_text("AudioMonitoring")); // audio fade settings obs_property_t *audio_fade_style = obs_properties_add_list(