mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-15 13:53:19 -05:00
Add option to also check for configured volume level
This commit is contained in:
@@ -89,10 +89,13 @@ AdvSceneSwitcher.logic.not="If not"
|
||||
; Macro Conditions
|
||||
AdvSceneSwitcher.condition.audio="Audio"
|
||||
AdvSceneSwitcher.condition.audio.state.below="below"
|
||||
AdvSceneSwitcher.condition.audio.state.exact="exactly"
|
||||
AdvSceneSwitcher.condition.audio.state.above="above"
|
||||
AdvSceneSwitcher.condition.audio.state.mute="muted"
|
||||
AdvSceneSwitcher.condition.audio.state.unmute="unmuted"
|
||||
AdvSceneSwitcher.condition.audio.entry="Volume of {{audioSources}} is {{condition}} {{volume}}"
|
||||
AdvSceneSwitcher.condition.audio.type.output="Output volume"
|
||||
AdvSceneSwitcher.condition.audio.type.volume="Configured volume level"
|
||||
AdvSceneSwitcher.condition.audio.entry="{{checkType}} of {{audioSources}} is {{condition}} {{volume}}"
|
||||
AdvSceneSwitcher.condition.cursor="Cursor"
|
||||
AdvSceneSwitcher.condition.cursor.type.region="is in region"
|
||||
AdvSceneSwitcher.condition.cursor.type.moving="is moving"
|
||||
|
||||
@@ -6,9 +6,23 @@
|
||||
#include <QComboBox>
|
||||
#include <chrono>
|
||||
|
||||
enum class AudioCondition {
|
||||
enum class AudioConditionCheckType {
|
||||
OUTPUT_VOLUME,
|
||||
CONFIGURED_VOLUME,
|
||||
};
|
||||
|
||||
enum class AudioOutputCondition {
|
||||
ABOVE,
|
||||
BELOW,
|
||||
// TODO: To be removed
|
||||
MUTE,
|
||||
UNMUTE,
|
||||
};
|
||||
|
||||
enum class AudioVolumeCondition {
|
||||
ABOVE,
|
||||
EXACT,
|
||||
BELOW,
|
||||
MUTE,
|
||||
UNMUTE,
|
||||
};
|
||||
@@ -34,10 +48,16 @@ public:
|
||||
|
||||
OBSWeakSource _audioSource;
|
||||
int _volume = 0;
|
||||
AudioCondition _condition = AudioCondition::ABOVE;
|
||||
AudioConditionCheckType _checkType =
|
||||
AudioConditionCheckType::OUTPUT_VOLUME;
|
||||
AudioOutputCondition _outputCondition = AudioOutputCondition::ABOVE;
|
||||
AudioVolumeCondition _volumeCondition = AudioVolumeCondition::ABOVE;
|
||||
obs_volmeter_t *_volmeter = nullptr;
|
||||
|
||||
private:
|
||||
bool CheckOutputCondition();
|
||||
bool CheckVolumeCondition();
|
||||
|
||||
float _peak = -std::numeric_limits<float>::infinity();
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
@@ -64,10 +84,13 @@ private slots:
|
||||
void SourceChanged(const QString &text);
|
||||
void VolumeThresholdChanged(int vol);
|
||||
void ConditionChanged(int cond);
|
||||
void CheckTypeChanged(int cond);
|
||||
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
protected:
|
||||
QComboBox *_checkTypes;
|
||||
QComboBox *_audioSources;
|
||||
QComboBox *_condition;
|
||||
QSpinBox *_volume;
|
||||
|
||||
@@ -10,11 +10,23 @@ bool MacroConditionAudio::_registered = MacroConditionFactory::Register(
|
||||
{MacroConditionAudio::Create, MacroConditionAudioEdit::Create,
|
||||
"AdvSceneSwitcher.condition.audio"});
|
||||
|
||||
static std::map<AudioCondition, std::string> audioConditionTypes = {
|
||||
{AudioCondition::ABOVE, "AdvSceneSwitcher.condition.audio.state.above"},
|
||||
{AudioCondition::BELOW, "AdvSceneSwitcher.condition.audio.state.below"},
|
||||
{AudioCondition::MUTE, "AdvSceneSwitcher.condition.audio.state.mute"},
|
||||
{AudioCondition::UNMUTE,
|
||||
static std::map<AudioOutputCondition, std::string> audioOutputConditionTypes = {
|
||||
{AudioOutputCondition::ABOVE,
|
||||
"AdvSceneSwitcher.condition.audio.state.above"},
|
||||
{AudioOutputCondition::BELOW,
|
||||
"AdvSceneSwitcher.condition.audio.state.below"},
|
||||
};
|
||||
|
||||
static std::map<AudioVolumeCondition, std::string> audioVolumeConditionTypes = {
|
||||
{AudioVolumeCondition::ABOVE,
|
||||
"AdvSceneSwitcher.condition.audio.state.above"},
|
||||
{AudioVolumeCondition::EXACT,
|
||||
"AdvSceneSwitcher.condition.audio.state.exact"},
|
||||
{AudioVolumeCondition::BELOW,
|
||||
"AdvSceneSwitcher.condition.audio.state.below"},
|
||||
{AudioVolumeCondition::MUTE,
|
||||
"AdvSceneSwitcher.condition.audio.state.mute"},
|
||||
{AudioVolumeCondition::UNMUTE,
|
||||
"AdvSceneSwitcher.condition.audio.state.unmute"},
|
||||
};
|
||||
|
||||
@@ -24,43 +36,85 @@ MacroConditionAudio::~MacroConditionAudio()
|
||||
obs_volmeter_destroy(_volmeter);
|
||||
}
|
||||
|
||||
bool MacroConditionAudio::CheckCondition()
|
||||
bool MacroConditionAudio::CheckOutputCondition()
|
||||
{
|
||||
bool ret = false;
|
||||
auto s = obs_weak_source_get_source(_audioSource);
|
||||
switch (_condition) {
|
||||
case AudioCondition::ABOVE:
|
||||
|
||||
switch (_outputCondition) {
|
||||
case AudioOutputCondition::ABOVE:
|
||||
// peak will have a value from -60 db to 0 db
|
||||
ret = ((double)_peak + 60) * 1.7 > _volume;
|
||||
break;
|
||||
case AudioCondition::BELOW:
|
||||
case AudioOutputCondition::BELOW:
|
||||
// peak will have a value from -60 db to 0 db
|
||||
ret = ((double)_peak + 60) * 1.7 < _volume;
|
||||
break;
|
||||
case AudioCondition::MUTE:
|
||||
ret = obs_source_muted(s);
|
||||
break;
|
||||
case AudioCondition::UNMUTE:
|
||||
ret = !obs_source_muted(s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset for next check
|
||||
_peak = -std::numeric_limits<float>::infinity();
|
||||
obs_source_release(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool MacroConditionAudio::CheckVolumeCondition()
|
||||
{
|
||||
|
||||
bool ret = false;
|
||||
auto s = obs_weak_source_get_source(_audioSource);
|
||||
|
||||
switch (_volumeCondition) {
|
||||
case AudioVolumeCondition::ABOVE:
|
||||
ret = obs_source_get_volume(s) > _volume / 100.f;
|
||||
break;
|
||||
case AudioVolumeCondition::EXACT:
|
||||
ret = obs_source_get_volume(s) == _volume / 100.f;
|
||||
break;
|
||||
case AudioVolumeCondition::BELOW:
|
||||
ret = obs_source_get_volume(s) < _volume / 100.f;
|
||||
break;
|
||||
case AudioVolumeCondition::MUTE:
|
||||
ret = obs_source_muted(s);
|
||||
break;
|
||||
case AudioVolumeCondition::UNMUTE:
|
||||
ret = !obs_source_muted(s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
obs_source_release(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool MacroConditionAudio::CheckCondition()
|
||||
{
|
||||
switch (_checkType) {
|
||||
case AudioConditionCheckType::OUTPUT_VOLUME:
|
||||
return CheckOutputCondition();
|
||||
case AudioConditionCheckType::CONFIGURED_VOLUME:
|
||||
return CheckVolumeCondition();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MacroConditionAudio::Save(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_string(obj, "audioSource",
|
||||
GetWeakSourceName(_audioSource).c_str());
|
||||
obs_data_set_int(obj, "volume", _volume);
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
obs_data_set_int(obj, "checkType", static_cast<int>(_checkType));
|
||||
obs_data_set_int(obj, "outputCondition",
|
||||
static_cast<int>(_outputCondition));
|
||||
obs_data_set_int(obj, "volumeCondition",
|
||||
static_cast<int>(_volumeCondition));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,14 +135,66 @@ obs_volmeter_t *AddVolmeterToSource(MacroConditionAudio *entry,
|
||||
return volmeter;
|
||||
}
|
||||
|
||||
// TODO: Remove in future version
|
||||
static void convertOldSettingsFormat(obs_data_t *obj)
|
||||
{
|
||||
auto oldCond = static_cast<AudioOutputCondition>(
|
||||
obs_data_get_int(obj, "condition"));
|
||||
switch (oldCond) {
|
||||
case AudioOutputCondition::ABOVE:
|
||||
obs_data_set_int(
|
||||
obj, "checkType",
|
||||
static_cast<int>(
|
||||
AudioConditionCheckType::OUTPUT_VOLUME));
|
||||
obs_data_set_int(obj, "outputCondition",
|
||||
static_cast<int>(AudioOutputCondition::ABOVE));
|
||||
break;
|
||||
case AudioOutputCondition::BELOW:
|
||||
obs_data_set_int(
|
||||
obj, "checkType",
|
||||
static_cast<int>(
|
||||
AudioConditionCheckType::OUTPUT_VOLUME));
|
||||
obs_data_set_int(obj, "outputCondition",
|
||||
static_cast<int>(AudioOutputCondition::BELOW));
|
||||
break;
|
||||
case AudioOutputCondition::MUTE:
|
||||
obs_data_set_int(
|
||||
obj, "checkType",
|
||||
static_cast<int>(
|
||||
AudioConditionCheckType::CONFIGURED_VOLUME));
|
||||
obs_data_set_int(obj, "volumeCondition",
|
||||
static_cast<int>(AudioVolumeCondition::MUTE));
|
||||
break;
|
||||
case AudioOutputCondition::UNMUTE:
|
||||
obs_data_set_int(
|
||||
obj, "checkType",
|
||||
static_cast<int>(
|
||||
AudioConditionCheckType::CONFIGURED_VOLUME));
|
||||
obs_data_set_int(
|
||||
obj, "volumeCondition",
|
||||
static_cast<int>(AudioVolumeCondition::UNMUTE));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool MacroConditionAudio::Load(obs_data_t *obj)
|
||||
{
|
||||
if (!obs_data_has_user_value(obj, "checkType")) {
|
||||
convertOldSettingsFormat(obj);
|
||||
}
|
||||
|
||||
MacroCondition::Load(obj);
|
||||
const char *audioSourceName = obs_data_get_string(obj, "audioSource");
|
||||
_audioSource = GetWeakSourceByName(audioSourceName);
|
||||
_volume = obs_data_get_int(obj, "volume");
|
||||
_condition =
|
||||
static_cast<AudioCondition>(obs_data_get_int(obj, "condition"));
|
||||
_checkType = static_cast<AudioConditionCheckType>(
|
||||
obs_data_get_int(obj, "checkType"));
|
||||
_outputCondition = static_cast<AudioOutputCondition>(
|
||||
obs_data_get_int(obj, "outputCondition"));
|
||||
_volumeCondition = static_cast<AudioVolumeCondition>(
|
||||
obs_data_get_int(obj, "volumeCondition"));
|
||||
_volmeter = AddVolmeterToSource(this, _audioSource);
|
||||
return true;
|
||||
}
|
||||
@@ -122,9 +228,26 @@ void MacroConditionAudio::ResetVolmeter()
|
||||
_volmeter = AddVolmeterToSource(this, _audioSource);
|
||||
}
|
||||
|
||||
static inline void populateConditionSelection(QComboBox *list)
|
||||
static inline void populateCheckTypes(QComboBox *list)
|
||||
{
|
||||
for (auto entry : audioConditionTypes) {
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.audio.type.output"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.audio.type.volume"));
|
||||
}
|
||||
|
||||
static inline void populateOutputConditionSelection(QComboBox *list)
|
||||
{
|
||||
list->clear();
|
||||
for (auto entry : audioOutputConditionTypes) {
|
||||
list->addItem(obs_module_text(entry.second.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void populateVolumeConditionSelection(QComboBox *list)
|
||||
{
|
||||
list->clear();
|
||||
for (auto entry : audioVolumeConditionTypes) {
|
||||
list->addItem(obs_module_text(entry.second.c_str()));
|
||||
}
|
||||
}
|
||||
@@ -133,6 +256,7 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionAudio> entryData)
|
||||
: QWidget(parent)
|
||||
{
|
||||
_checkTypes = new QComboBox();
|
||||
_audioSources = new QComboBox();
|
||||
_condition = new QComboBox();
|
||||
_volume = new QSpinBox();
|
||||
@@ -141,6 +265,8 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
|
||||
_volume->setMaximum(100);
|
||||
_volume->setMinimum(0);
|
||||
|
||||
QWidget::connect(_checkTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(CheckTypeChanged(int)));
|
||||
QWidget::connect(_volume, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(VolumeThresholdChanged(int)));
|
||||
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
|
||||
@@ -149,11 +275,12 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(SourceChanged(const QString &)));
|
||||
|
||||
populateCheckTypes(_checkTypes);
|
||||
populateAudioSelection(_audioSources);
|
||||
populateConditionSelection(_condition);
|
||||
|
||||
QHBoxLayout *switchLayout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{checkType}}", _checkTypes},
|
||||
{"{{audioSources}}", _audioSources},
|
||||
{"{{volume}}", _volume},
|
||||
{"{{condition}}", _condition},
|
||||
@@ -224,7 +351,31 @@ void MacroConditionAudioEdit::ConditionChanged(int cond)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_condition = static_cast<AudioCondition>(cond);
|
||||
if (_entryData->_checkType == AudioConditionCheckType::OUTPUT_VOLUME) {
|
||||
_entryData->_outputCondition =
|
||||
static_cast<AudioOutputCondition>(cond);
|
||||
} else {
|
||||
_entryData->_volumeCondition =
|
||||
static_cast<AudioVolumeCondition>(cond);
|
||||
}
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionAudioEdit::CheckTypeChanged(int cond)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_checkType = static_cast<AudioConditionCheckType>(cond);
|
||||
|
||||
const QSignalBlocker b(_condition);
|
||||
if (_entryData->_checkType == AudioConditionCheckType::OUTPUT_VOLUME) {
|
||||
populateOutputConditionSelection(_condition);
|
||||
} else {
|
||||
populateVolumeConditionSelection(_condition);
|
||||
}
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
@@ -237,7 +388,16 @@ void MacroConditionAudioEdit::UpdateEntryData()
|
||||
_audioSources->setCurrentText(
|
||||
GetWeakSourceName(_entryData->_audioSource).c_str());
|
||||
_volume->setValue(_entryData->_volume);
|
||||
_condition->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
_checkTypes->setCurrentIndex(static_cast<int>(_entryData->_checkType));
|
||||
if (_entryData->_checkType == AudioConditionCheckType::OUTPUT_VOLUME) {
|
||||
populateOutputConditionSelection(_condition);
|
||||
_condition->setCurrentIndex(
|
||||
static_cast<int>(_entryData->_outputCondition));
|
||||
} else {
|
||||
populateVolumeConditionSelection(_condition);
|
||||
_condition->setCurrentIndex(
|
||||
static_cast<int>(_entryData->_volumeCondition));
|
||||
}
|
||||
UpdateVolmeterSource();
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
@@ -248,9 +408,15 @@ void MacroConditionAudioEdit::SetWidgetVisibility()
|
||||
return;
|
||||
}
|
||||
|
||||
_volume->setVisible(_entryData->_condition == AudioCondition::ABOVE ||
|
||||
_entryData->_condition == AudioCondition::BELOW);
|
||||
_volMeter->setVisible(_entryData->_condition == AudioCondition::ABOVE ||
|
||||
_entryData->_condition == AudioCondition::BELOW);
|
||||
_volume->setVisible(
|
||||
_entryData->_checkType ==
|
||||
AudioConditionCheckType::OUTPUT_VOLUME ||
|
||||
(_entryData->_checkType ==
|
||||
AudioConditionCheckType::CONFIGURED_VOLUME &&
|
||||
(_entryData->_volumeCondition == AudioVolumeCondition::ABOVE ||
|
||||
_entryData->_volumeCondition == AudioVolumeCondition::EXACT ||
|
||||
_entryData->_volumeCondition == AudioVolumeCondition::BELOW)));
|
||||
_volMeter->setVisible(_entryData->_checkType ==
|
||||
AudioConditionCheckType::OUTPUT_VOLUME);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user