From 15d7e2f972c569ba2e7a64028356f0bd5f462218 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Mon, 26 Dec 2022 21:56:59 +0100 Subject: [PATCH] Add option to check audio balance --- data/locale/en-US.ini | 1 + src/macro-core/macro-condition-audio.cpp | 95 +++++++++++++++++------- src/macro-core/macro-condition-audio.hpp | 6 ++ 3 files changed, 77 insertions(+), 25 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 056c80e7..d62e224d 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -115,6 +115,7 @@ AdvSceneSwitcher.condition.audio.type.output="Output volume" AdvSceneSwitcher.condition.audio.type.volume="Configured volume level" AdvSceneSwitcher.condition.audio.type.syncOffset="Sync offset" AdvSceneSwitcher.condition.audio.type.monitor="Audio monitoring" +AdvSceneSwitcher.condition.audio.type.balance="Audio balance" AdvSceneSwitcher.condition.audio.entry="{{checkType}} of {{audioSources}} is {{condition}}{{volume}}{{syncOffset}}{{monitorTypes}}" AdvSceneSwitcher.condition.cursor="Cursor" AdvSceneSwitcher.condition.cursor.type.region="is in region" diff --git a/src/macro-core/macro-condition-audio.cpp b/src/macro-core/macro-condition-audio.cpp index 93b06b73..ab8e3dee 100644 --- a/src/macro-core/macro-condition-audio.cpp +++ b/src/macro-core/macro-condition-audio.cpp @@ -20,6 +20,8 @@ static std::map checkTypes = { "AdvSceneSwitcher.condition.audio.type.syncOffset"}, {MacroConditionAudio::Type::MONITOR, "AdvSceneSwitcher.condition.audio.type.monitor"}, + {MacroConditionAudio::Type::BALANCE, + "AdvSceneSwitcher.condition.audio.type.balance"}, }; static std::map @@ -56,11 +58,11 @@ bool MacroConditionAudio::CheckOutputCondition() auto s = obs_weak_source_get_source(_audioSource); switch (_outputCondition) { - case MacroConditionAudio::OutputCondition::ABOVE: + case OutputCondition::ABOVE: // peak will have a value from -60 db to 0 db ret = ((double)_peak + 60) * 1.7 > _volume; break; - case MacroConditionAudio::OutputCondition::BELOW: + case OutputCondition::BELOW: // peak will have a value from -60 db to 0 db ret = ((double)_peak + 60) * 1.7 < _volume; break; @@ -81,19 +83,19 @@ bool MacroConditionAudio::CheckVolumeCondition() auto s = obs_weak_source_get_source(_audioSource); switch (_volumeCondition) { - case MacroConditionAudio::VolumeCondition::ABOVE: + case VolumeCondition::ABOVE: ret = obs_source_get_volume(s) > _volume / 100.f; break; - case MacroConditionAudio::VolumeCondition::EXACT: + case VolumeCondition::EXACT: ret = obs_source_get_volume(s) == _volume / 100.f; break; - case MacroConditionAudio::VolumeCondition::BELOW: + case VolumeCondition::BELOW: ret = obs_source_get_volume(s) < _volume / 100.f; break; - case MacroConditionAudio::VolumeCondition::MUTE: + case VolumeCondition::MUTE: ret = obs_source_muted(s); break; - case MacroConditionAudio::VolumeCondition::UNMUTE: + case VolumeCondition::UNMUTE: ret = !obs_source_muted(s); break; default: @@ -130,17 +132,36 @@ bool MacroConditionAudio::CheckMonitor() return ret; } +bool MacroConditionAudio::CheckBalance() +{ + if (!_audioSource) { + return false; + } + + bool ret = false; + auto s = obs_weak_source_get_source(_audioSource); + if (_outputCondition == OutputCondition::ABOVE) { + ret = obs_source_get_balance_value(s) > _balance; + } else { + ret = obs_source_get_balance_value(s) < _balance; + } + obs_source_release(s); + return ret; +} + bool MacroConditionAudio::CheckCondition() { switch (_checkType) { - case MacroConditionAudio::Type::OUTPUT_VOLUME: + case Type::OUTPUT_VOLUME: return CheckOutputCondition(); - case MacroConditionAudio::Type::CONFIGURED_VOLUME: + case Type::CONFIGURED_VOLUME: return CheckVolumeCondition(); - case MacroConditionAudio::Type::SYNC_OFFSET: + case Type::SYNC_OFFSET: return CheckSyncOffset(); - case MacroConditionAudio::Type::MONITOR: + case Type::MONITOR: return CheckMonitor(); + case Type::BALANCE: + return CheckBalance(); default: break; } @@ -155,6 +176,7 @@ bool MacroConditionAudio::Save(obs_data_t *obj) const obs_data_set_int(obj, "volume", _volume); obs_data_set_int(obj, "syncOffset", _syncOffset); obs_data_set_int(obj, "monitor", _monitorType); + obs_data_set_double(obj, "balance", _balance); obs_data_set_int(obj, "checkType", static_cast(_checkType)); obs_data_set_int(obj, "outputCondition", static_cast(_outputCondition)); @@ -189,11 +211,11 @@ bool MacroConditionAudio::Load(obs_data_t *obj) _syncOffset = obs_data_get_int(obj, "syncOffset"); _monitorType = static_cast( obs_data_get_int(obj, "monitor")); - _checkType = static_cast( - obs_data_get_int(obj, "checkType")); - _outputCondition = static_cast( + _balance = obs_data_get_double(obj, "balance"); + _checkType = static_cast(obs_data_get_int(obj, "checkType")); + _outputCondition = static_cast( obs_data_get_int(obj, "outputCondition")); - _volumeCondition = static_cast( + _volumeCondition = static_cast( obs_data_get_int(obj, "volumeCondition")); _volmeter = AddVolmeterToSource(this, _audioSource); return true; @@ -272,7 +294,8 @@ MacroConditionAudioEdit::MacroConditionAudioEdit( _condition(new QComboBox()), _volume(new QSpinBox()), _syncOffset(new QSpinBox()), - _monitorTypes(new QComboBox) + _monitorTypes(new QComboBox), + _balance(new SliderSpinBox(0., 1., "")) { _volume->setSuffix("%"); _volume->setMaximum(100); @@ -290,6 +313,8 @@ MacroConditionAudioEdit::MacroConditionAudioEdit( SLOT(SyncOffsetChanged(int))); QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this, SLOT(MonitorTypeChanged(int))); + QWidget::connect(_balance, SIGNAL(DoubleValueChanged(double)), this, + SLOT(BalanceChanged(double))); QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this, SLOT(ConditionChanged(int))); QWidget::connect(_audioSources, @@ -307,15 +332,15 @@ MacroConditionAudioEdit::MacroConditionAudioEdit( {"{{volume}}", _volume}, {"{{syncOffset}}", _syncOffset}, {"{{monitorTypes}}", _monitorTypes}, + {"{{balance}}", _balance}, {"{{condition}}", _condition}, }; placeWidgets(obs_module_text("AdvSceneSwitcher.condition.audio.entry"), switchLayout, widgetPlaceholders); QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addLayout(switchLayout); - + mainLayout->addWidget(_balance); setLayout(mainLayout); _entryData = entryData; @@ -388,6 +413,16 @@ void MacroConditionAudioEdit::MonitorTypeChanged(int value) _entryData->_monitorType = static_cast(value); } +void MacroConditionAudioEdit::BalanceChanged(double value) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_balance = value; +} + void MacroConditionAudioEdit::ConditionChanged(int cond) { if (_loading || !_entryData) { @@ -396,7 +431,8 @@ void MacroConditionAudioEdit::ConditionChanged(int cond) std::lock_guard lock(switcher->m); if (_entryData->_checkType == - MacroConditionAudio::Type::OUTPUT_VOLUME) { + MacroConditionAudio::Type::OUTPUT_VOLUME || + _entryData->_checkType == MacroConditionAudio::Type::BALANCE) { _entryData->_outputCondition = static_cast(cond); } else { @@ -418,7 +454,8 @@ void MacroConditionAudioEdit::CheckTypeChanged(int idx) const QSignalBlocker b(_condition); if (_entryData->_checkType == - MacroConditionAudio::Type::OUTPUT_VOLUME) { + MacroConditionAudio::Type::OUTPUT_VOLUME || + _entryData->_checkType == MacroConditionAudio::Type::BALANCE) { populateOutputConditionSelection(_condition); } else if (_entryData->_checkType == MacroConditionAudio::Type::CONFIGURED_VOLUME) { @@ -438,19 +475,24 @@ void MacroConditionAudioEdit::UpdateEntryData() _volume->setValue(_entryData->_volume); _syncOffset->setValue(_entryData->_syncOffset); _monitorTypes->setCurrentIndex(_entryData->_monitorType); + _balance->SetDoubleValue(_entryData->_balance); _checkTypes->setCurrentIndex(_checkTypes->findData( static_cast(_entryData->_checkType))); - if (_entryData->_checkType == - MacroConditionAudio::Type::OUTPUT_VOLUME) { + + switch (_entryData->_checkType) { + case MacroConditionAudio::Type::OUTPUT_VOLUME: + case MacroConditionAudio::Type::BALANCE: populateOutputConditionSelection(_condition); _condition->setCurrentIndex( static_cast(_entryData->_outputCondition)); - } else if (_entryData->_checkType == - MacroConditionAudio::Type::CONFIGURED_VOLUME) { + break; + case MacroConditionAudio::Type::CONFIGURED_VOLUME: populateVolumeConditionSelection(_condition); _condition->setCurrentIndex( static_cast(_entryData->_volumeCondition)); + break; } + UpdateVolmeterSource(); SetWidgetVisibility(); } @@ -476,11 +518,14 @@ void MacroConditionAudioEdit::SetWidgetVisibility() _entryData->_checkType == MacroConditionAudio::Type::OUTPUT_VOLUME || _entryData->_checkType == - MacroConditionAudio::Type::CONFIGURED_VOLUME); + MacroConditionAudio::Type::CONFIGURED_VOLUME || + _entryData->_checkType == MacroConditionAudio::Type::BALANCE); _syncOffset->setVisible(_entryData->_checkType == MacroConditionAudio::Type::SYNC_OFFSET); _monitorTypes->setVisible(_entryData->_checkType == MacroConditionAudio::Type::MONITOR); + _balance->setVisible(_entryData->_checkType == + MacroConditionAudio::Type::BALANCE); _volMeter->setVisible(_entryData->_checkType == MacroConditionAudio::Type::OUTPUT_VOLUME); adjustSize(); diff --git a/src/macro-core/macro-condition-audio.hpp b/src/macro-core/macro-condition-audio.hpp index 2ef3bb10..11355228 100644 --- a/src/macro-core/macro-condition-audio.hpp +++ b/src/macro-core/macro-condition-audio.hpp @@ -1,6 +1,7 @@ #pragma once #include "macro.hpp" #include "volume-control.hpp" +#include "slider-spinbox.hpp" #include #include #include @@ -30,6 +31,7 @@ public: CONFIGURED_VOLUME, SYNC_OFFSET, MONITOR, + BALANCE, }; enum class OutputCondition { @@ -49,6 +51,7 @@ public: int _volume = 0; int64_t _syncOffset = 0; obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE; + double _balance = 0.5; Type _checkType = Type::OUTPUT_VOLUME; OutputCondition _outputCondition = OutputCondition::ABOVE; VolumeCondition _volumeCondition = VolumeCondition::ABOVE; @@ -59,6 +62,7 @@ private: bool CheckVolumeCondition(); bool CheckSyncOffset(); bool CheckMonitor(); + bool CheckBalance(); float _peak = -std::numeric_limits::infinity(); static bool _registered; @@ -89,6 +93,7 @@ private slots: void CheckTypeChanged(int cond); void SyncOffsetChanged(int value); void MonitorTypeChanged(int value); + void BalanceChanged(double value); signals: void HeaderInfoChanged(const QString &); @@ -100,6 +105,7 @@ protected: QSpinBox *_volume; QSpinBox *_syncOffset; QComboBox *_monitorTypes; + SliderSpinBox *_balance; VolControl *_volMeter = nullptr; std::shared_ptr _entryData;