Add option to check / set audio monitoring of sources

This commit is contained in:
WarmUpTill 2022-12-05 17:21:40 +01:00 committed by WarmUpTill
parent 03854376ef
commit 0ce9c515af
11 changed files with 97 additions and 9 deletions

View File

@ -114,7 +114,8 @@ AdvSceneSwitcher.condition.audio.state.unmute="unmuted"
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.entry="{{checkType}} of {{audioSources}} is {{condition}}{{volume}}{{syncOffset}}"
AdvSceneSwitcher.condition.audio.type.monitor="Audio monitoring"
AdvSceneSwitcher.condition.audio.entry="{{checkType}} of {{audioSources}} is {{condition}}{{volume}}{{syncOffset}}{{monitorTypes}}"
AdvSceneSwitcher.condition.cursor="Cursor"
AdvSceneSwitcher.condition.cursor.type.region="is in region"
AdvSceneSwitcher.condition.cursor.type.moving="is moving"
@ -386,13 +387,14 @@ AdvSceneSwitcher.action.audio.type.unmute="Unmute"
AdvSceneSwitcher.action.audio.type.sourceVolume="Set source volume"
AdvSceneSwitcher.action.audio.type.masterVolume="Set master volume"
AdvSceneSwitcher.action.audio.type.syncOffset="Set sync offset"
AdvSceneSwitcher.action.audio.type.monitor="Set audio monitoring"
AdvSceneSwitcher.action.audio.fade.type.duration="over a duration of"
AdvSceneSwitcher.action.audio.fade.type.rate="at a rate of"
AdvSceneSwitcher.action.audio.fade.duration="{{fade}}Fade {{fadeTypes}} {{duration}} seconds."
AdvSceneSwitcher.action.audio.fade.rate="{{fade}}Fade {{fadeTypes}} {{rate}}per second."
AdvSceneSwitcher.action.audio.fade.wait="Wait for fade to complete."
AdvSceneSwitcher.action.audio.fade.abort="Abort already active fade."
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}"
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}{{monitorTypes}}"
AdvSceneSwitcher.action.recording="Recording"
AdvSceneSwitcher.action.recording.type.stop="Stop recording"
AdvSceneSwitcher.action.recording.type.start="Start recording"
@ -891,3 +893,7 @@ AdvSceneSwitcher.duration.condition.more="For at least"
AdvSceneSwitcher.duration.condition.equal="For exactly"
AdvSceneSwitcher.duration.condition.less="For at most"
AdvSceneSwitcher.duration.condition.within="Within the last"
AdvSceneSwitcher.audio.monitor.none="Monitor Off"
AdvSceneSwitcher.audio.monitor.monitorOnly="Monitor Only (mute output)"
AdvSceneSwitcher.audio.monitor.both="Monitor and Output"

View File

@ -105,7 +105,7 @@ AdvSceneSwitcher.condition.audio.state.mute="silenciado"
AdvSceneSwitcher.condition.audio.state.unmute="no silenciado"
AdvSceneSwitcher.condition.audio.type.output="Volumen de salida"
AdvSceneSwitcher.condition.audio.type.volume="Nivel de volumen configurado"
AdvSceneSwitcher.condition.audio.entry="{{checkType}} de {{audioSources}} es {{condition}}{{volume}}{{syncOffset}}"
AdvSceneSwitcher.condition.audio.entry="{{checkType}} de {{audioSources}} es {{condition}}{{volume}}{{syncOffset}}{{monitorTypes}}"
AdvSceneSwitcher.condition.cursor="Cursor"
AdvSceneSwitcher.condition.cursor.type.region="está en la región"
AdvSceneSwitcher.condition.cursor.type.moving="se está moviendo"
@ -347,7 +347,7 @@ AdvSceneSwitcher.action.audio.fade.duration="{{fade}}Fade {{fadeTypes}} {{durati
AdvSceneSwitcher.action.audio.fade.rate="{{fade}}Fade {{fadeTypes}} {{rate}}por segundo."
AdvSceneSwitcher.action.audio.fade.wait="Espere a que se complete el desvanecimiento".
AdvSceneSwitcher.action.audio.fade.abort="Cancelar atenuación ya activa."
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}"
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}{{monitorTypes}}"
AdvSceneSwitcher.action.recording="Grabando"
AdvSceneSwitcher.action.recording.type.stop="Detener grabación"
AdvSceneSwitcher.action.recording.type.start="Iniciar grabación"

View File

@ -128,7 +128,7 @@ AdvSceneSwitcher.action.audio.type.mute="Замьютить"
AdvSceneSwitcher.action.audio.type.unmute="Размьютить"
AdvSceneSwitcher.action.audio.type.sourceVolume="Установить громкость источника"
AdvSceneSwitcher.action.audio.type.masterVolume="Установить главную громкость"
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}"
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}{{monitorTypes}}"
AdvSceneSwitcher.action.recording="Запись"
AdvSceneSwitcher.action.recording.type.stop="Остановить запись"
AdvSceneSwitcher.action.recording.type.start="Начать запись"

View File

@ -277,7 +277,7 @@ AdvSceneSwitcher.action.audio.type.mute="Sessiz"
AdvSceneSwitcher.action.audio.type.unmute="Ses açmak"
AdvSceneSwitcher.action.audio.type.sourceVolume="Kaynak ses seviyesini ayarla"
AdvSceneSwitcher.action.audio.type.masterVolume="Ana ses seviyesini ayarla"
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}"
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}{{monitorTypes}}"
AdvSceneSwitcher.action.recording="Kayıt"
AdvSceneSwitcher.action.recording.type.stop="Kayıt Durdur"
AdvSceneSwitcher.action.recording.type.start="Kayıt Başlat"

View File

@ -112,7 +112,7 @@ AdvSceneSwitcher.condition.audio.state.mute="静音"
AdvSceneSwitcher.condition.audio.state.unmute="取消静音"
AdvSceneSwitcher.condition.audio.type.output="输出音频"
AdvSceneSwitcher.condition.audio.type.volume="配置音量级别"
AdvSceneSwitcher.condition.audio.entry="{{checkType}} 的 {{audioSources}} 是 {{condition}}{{volume}}{{syncOffset}}"
AdvSceneSwitcher.condition.audio.entry="{{checkType}} 的 {{audioSources}} 是 {{condition}}{{volume}}{{syncOffset}}{{monitorTypes}}"
AdvSceneSwitcher.condition.cursor="屏幕区域"
AdvSceneSwitcher.condition.cursor.type.region="当前位置"
AdvSceneSwitcher.condition.cursor.type.moving="正在移动"
@ -385,7 +385,7 @@ AdvSceneSwitcher.action.audio.fade.duration="{{fade}}淡出 {{fadeTypes}} {{dura
AdvSceneSwitcher.action.audio.fade.rate="{{fade}}淡出 {{fadeTypes}} {{rate}}每秒."
AdvSceneSwitcher.action.audio.fade.wait="等待淡入淡出完成."
AdvSceneSwitcher.action.audio.fade.abort="中止已处于活动状态的淡入淡出."
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}"
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{syncOffset}}{{monitorTypes}}"
AdvSceneSwitcher.action.recording="录制"
AdvSceneSwitcher.action.recording.type.stop="停止录制"
AdvSceneSwitcher.action.recording.type.start="开始录制"

View File

@ -21,6 +21,8 @@ const static std::map<MacroActionAudio::Action, std::string> actionTypes = {
"AdvSceneSwitcher.action.audio.type.masterVolume"},
{MacroActionAudio::Action::SYNC_OFFSET,
"AdvSceneSwitcher.action.audio.type.syncOffset"},
{MacroActionAudio::Action::MONITOR,
"AdvSceneSwitcher.action.audio.type.monitor"},
};
const static std::map<MacroActionAudio::FadeType, std::string> fadeTypes = {
@ -189,6 +191,9 @@ bool MacroActionAudio::PerformAction()
case MacroActionAudio::Action::SYNC_OFFSET:
obs_source_set_sync_offset(s, _syncOffset * nsPerMs);
break;
case MacroActionAudio::Action::MONITOR:
obs_source_set_monitoring_type(s, _monitorType);
break;
default:
break;
}
@ -219,6 +224,7 @@ bool MacroActionAudio::Save(obs_data_t *obj)
GetWeakSourceName(_audioSource).c_str());
obs_data_set_int(obj, "action", static_cast<int>(_action));
obs_data_set_int(obj, "syncOffset", _syncOffset);
obs_data_set_int(obj, "monitor", _monitorType);
obs_data_set_int(obj, "volume", _volume);
obs_data_set_double(obj, "rate", _rate);
obs_data_set_bool(obj, "fade", _fade);
@ -237,6 +243,8 @@ bool MacroActionAudio::Load(obs_data_t *obj)
_action = static_cast<MacroActionAudio::Action>(
obs_data_get_int(obj, "action"));
_syncOffset = obs_data_get_int(obj, "syncOffset");
_monitorType = static_cast<obs_monitoring_type>(
obs_data_get_int(obj, "monitor"));
_volume = obs_data_get_int(obj, "volume");
_rate = obs_data_get_double(obj, "rate");
_fade = obs_data_get_bool(obj, "fade");
@ -288,6 +296,7 @@ MacroActionAudioEdit::MacroActionAudioEdit(
_actions(new QComboBox),
_fadeTypes(new QComboBox),
_syncOffset(new QSpinBox),
_monitorTypes(new QComboBox),
_volumePercent(new QSpinBox),
_fade(new QCheckBox),
_duration(new DurationSelection(parent, false)),
@ -314,6 +323,7 @@ MacroActionAudioEdit::MacroActionAudioEdit(
populateActionSelection(_actions);
populateAudioSelection(_audioSources);
populateFadeTypeSelection(_fadeTypes);
populateMonitorTypeSelection(_monitorTypes);
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionChanged(int)));
@ -322,6 +332,8 @@ MacroActionAudioEdit::MacroActionAudioEdit(
SLOT(SourceChanged(const QString &)));
QWidget::connect(_syncOffset, SIGNAL(valueChanged(int)), this,
SLOT(SyncOffsetChanged(int)));
QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(MonitorTypeChanged(int)));
QWidget::connect(_volumePercent, SIGNAL(valueChanged(int)), this,
SLOT(VolumeChanged(int)));
QWidget::connect(_fade, SIGNAL(stateChanged(int)), this,
@ -341,6 +353,7 @@ MacroActionAudioEdit::MacroActionAudioEdit(
{"{{audioSources}}", _audioSources},
{"{{actions}}", _actions},
{"{{syncOffset}}", _syncOffset},
{"{{monitorTypes}}", _monitorTypes},
{"{{volume}}", _volumePercent},
{"{{fade}}", _fade},
{"{{duration}}", _duration},
@ -384,6 +397,8 @@ void MacroActionAudioEdit::SetWidgetVisibility()
MacroActionAudio::Action::MASTER_VOLUME);
_syncOffset->setVisible(_entryData->_action ==
MacroActionAudio::Action::SYNC_OFFSET);
_monitorTypes->setVisible(_entryData->_action ==
MacroActionAudio::Action::MONITOR);
_fadeTypes->setDisabled(!_entryData->_fade);
_wait->setDisabled(!_entryData->_fade);
@ -435,6 +450,7 @@ void MacroActionAudioEdit::UpdateEntryData()
GetWeakSourceName(_entryData->_audioSource).c_str());
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_syncOffset->setValue(_entryData->_syncOffset);
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
_volumePercent->setValue(_entryData->_volume);
_fade->setChecked(_entryData->_fade);
_duration->SetDuration(_entryData->_duration);
@ -478,6 +494,16 @@ void MacroActionAudioEdit::SyncOffsetChanged(int value)
_entryData->_syncOffset = value;
}
void MacroActionAudioEdit::MonitorTypeChanged(int value)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_monitorType = static_cast<obs_monitoring_type>(value);
}
void MacroActionAudioEdit::VolumeChanged(int value)
{
if (_loading || !_entryData) {

View File

@ -29,6 +29,7 @@ public:
SOURCE_VOLUME,
MASTER_VOLUME,
SYNC_OFFSET,
MONITOR,
};
enum class FadeType {
@ -39,6 +40,7 @@ public:
Action _action = Action::MUTE;
FadeType _fadeType = FadeType::DURATION;
int64_t _syncOffset = 0;
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
int _volume = 0;
bool _fade = false;
Duration _duration;
@ -79,6 +81,7 @@ private slots:
void SourceChanged(const QString &text);
void ActionChanged(int value);
void SyncOffsetChanged(int value);
void MonitorTypeChanged(int value);
void VolumeChanged(int value);
void FadeChanged(int value);
void DurationChanged(double seconds);
@ -94,6 +97,7 @@ protected:
QComboBox *_actions;
QComboBox *_fadeTypes;
QSpinBox *_syncOffset;
QComboBox *_monitorTypes;
QSpinBox *_volumePercent;
QCheckBox *_fade;
DurationSelection *_duration;

View File

@ -18,6 +18,8 @@ static std::map<MacroConditionAudio::Type, std::string> checkTypes = {
"AdvSceneSwitcher.condition.audio.type.volume"},
{MacroConditionAudio::Type::SYNC_OFFSET,
"AdvSceneSwitcher.condition.audio.type.syncOffset"},
{MacroConditionAudio::Type::MONITOR,
"AdvSceneSwitcher.condition.audio.type.monitor"},
};
static std::map<MacroConditionAudio::OutputCondition, std::string>
@ -115,6 +117,19 @@ bool MacroConditionAudio::CheckSyncOffset()
return ret;
}
bool MacroConditionAudio::CheckMonitor()
{
if (!_audioSource) {
return false;
}
bool ret = false;
auto s = obs_weak_source_get_source(_audioSource);
ret = obs_source_get_monitoring_type(s) == _monitorType;
obs_source_release(s);
return ret;
}
bool MacroConditionAudio::CheckCondition()
{
switch (_checkType) {
@ -124,6 +139,8 @@ bool MacroConditionAudio::CheckCondition()
return CheckVolumeCondition();
case MacroConditionAudio::Type::SYNC_OFFSET:
return CheckSyncOffset();
case MacroConditionAudio::Type::MONITOR:
return CheckMonitor();
default:
break;
}
@ -137,6 +154,7 @@ bool MacroConditionAudio::Save(obs_data_t *obj)
GetWeakSourceName(_audioSource).c_str());
obs_data_set_int(obj, "volume", _volume);
obs_data_set_int(obj, "syncOffset", _syncOffset);
obs_data_set_int(obj, "monitor", _monitorType);
obs_data_set_int(obj, "checkType", static_cast<int>(_checkType));
obs_data_set_int(obj, "outputCondition",
static_cast<int>(_outputCondition));
@ -169,6 +187,8 @@ bool MacroConditionAudio::Load(obs_data_t *obj)
_audioSource = GetWeakSourceByName(audioSourceName);
_volume = obs_data_get_int(obj, "volume");
_syncOffset = obs_data_get_int(obj, "syncOffset");
_monitorType = static_cast<obs_monitoring_type>(
obs_data_get_int(obj, "monitor"));
_checkType = static_cast<MacroConditionAudio::Type>(
obs_data_get_int(obj, "checkType"));
_outputCondition = static_cast<MacroConditionAudio::OutputCondition>(
@ -243,7 +263,8 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
_audioSources(new QComboBox()),
_condition(new QComboBox()),
_volume(new QSpinBox()),
_syncOffset(new QSpinBox())
_syncOffset(new QSpinBox()),
_monitorTypes(new QComboBox)
{
_volume->setSuffix("%");
_volume->setMaximum(100);
@ -259,6 +280,8 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
SLOT(VolumeThresholdChanged(int)));
QWidget::connect(_syncOffset, SIGNAL(valueChanged(int)), this,
SLOT(SyncOffsetChanged(int)));
QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(MonitorTypeChanged(int)));
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int)));
QWidget::connect(_audioSources,
@ -267,6 +290,7 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
populateCheckTypes(_checkTypes);
populateAudioSelection(_audioSources);
populateMonitorTypeSelection(_monitorTypes);
QHBoxLayout *switchLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
@ -274,6 +298,7 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
{"{{audioSources}}", _audioSources},
{"{{volume}}", _volume},
{"{{syncOffset}}", _syncOffset},
{"{{monitorTypes}}", _monitorTypes},
{"{{condition}}", _condition},
};
placeWidgets(obs_module_text("AdvSceneSwitcher.condition.audio.entry"),
@ -345,6 +370,16 @@ void MacroConditionAudioEdit::SyncOffsetChanged(int value)
_entryData->_syncOffset = value;
}
void MacroConditionAudioEdit::MonitorTypeChanged(int value)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_monitorType = static_cast<obs_monitoring_type>(value);
}
void MacroConditionAudioEdit::ConditionChanged(int cond)
{
if (_loading || !_entryData) {
@ -393,6 +428,7 @@ void MacroConditionAudioEdit::UpdateEntryData()
GetWeakSourceName(_entryData->_audioSource).c_str());
_volume->setValue(_entryData->_volume);
_syncOffset->setValue(_entryData->_syncOffset);
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
_checkTypes->setCurrentIndex(static_cast<int>(_entryData->_checkType));
if (_entryData->_checkType ==
MacroConditionAudio::Type::OUTPUT_VOLUME) {
@ -433,6 +469,8 @@ void MacroConditionAudioEdit::SetWidgetVisibility()
MacroConditionAudio::Type::CONFIGURED_VOLUME);
_syncOffset->setVisible(_entryData->_checkType ==
MacroConditionAudio::Type::SYNC_OFFSET);
_monitorTypes->setVisible(_entryData->_checkType ==
MacroConditionAudio::Type::MONITOR);
_volMeter->setVisible(_entryData->_checkType ==
MacroConditionAudio::Type::OUTPUT_VOLUME);
adjustSize();

View File

@ -29,6 +29,7 @@ public:
OUTPUT_VOLUME,
CONFIGURED_VOLUME,
SYNC_OFFSET,
MONITOR,
};
enum class OutputCondition {
@ -47,6 +48,7 @@ public:
OBSWeakSource _audioSource;
int _volume = 0;
int64_t _syncOffset = 0;
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
Type _checkType = Type::OUTPUT_VOLUME;
OutputCondition _outputCondition = OutputCondition::ABOVE;
VolumeCondition _volumeCondition = VolumeCondition::ABOVE;
@ -56,6 +58,7 @@ private:
bool CheckOutputCondition();
bool CheckVolumeCondition();
bool CheckSyncOffset();
bool CheckMonitor();
float _peak = -std::numeric_limits<float>::infinity();
static bool _registered;
@ -85,6 +88,7 @@ private slots:
void ConditionChanged(int cond);
void CheckTypeChanged(int cond);
void SyncOffsetChanged(int value);
void MonitorTypeChanged(int value);
signals:
void HeaderInfoChanged(const QString &);
@ -95,6 +99,7 @@ protected:
QComboBox *_condition;
QSpinBox *_volume;
QSpinBox *_syncOffset;
QComboBox *_monitorTypes;
VolControl *_volMeter = nullptr;
std::shared_ptr<MacroConditionAudio> _entryData;

View File

@ -824,6 +824,14 @@ void populateProfileSelection(QComboBox *box)
box->setCurrentIndex(0);
}
void populateMonitorTypeSelection(QComboBox *list)
{
list->addItem(obs_module_text("AdvSceneSwitcher.audio.monitor.none"));
list->addItem(
obs_module_text("AdvSceneSwitcher.audio.monitor.monitorOnly"));
list->addItem(obs_module_text("AdvSceneSwitcher.audio.monitor.both"));
}
bool windowPosValid(QPoint pos)
{
return !!QGuiApplication::screenAt(pos);

View File

@ -81,6 +81,7 @@ void populateFilterSelection(QComboBox *list,
OBSWeakSource weakSource = nullptr);
void populateSourceGroupSelection(QComboBox *list);
void populateProfileSelection(QComboBox *list);
void populateMonitorTypeSelection(QComboBox *list);
bool windowPosValid(QPoint pos);
bool doubleEquals(double left, double right, double epsilon);
void setButtonIcon(QPushButton *button, const char *path);