mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Add MIDI device name check
This commit is contained in:
parent
efaf9a2ef3
commit
c7afdd817b
|
|
@ -592,7 +592,15 @@ AdvSceneSwitcher.condition.run="Run"
|
|||
AdvSceneSwitcher.condition.run.entry="Process exits before timeout of{{timeout}}seconds"
|
||||
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}Check for exit code{{exitCode}}"
|
||||
AdvSceneSwitcher.condition.midi="MIDI"
|
||||
<<<<<<< HEAD
|
||||
AdvSceneSwitcher.condition.midi.entry="Message was received from{{device}}which matches:"
|
||||
=======
|
||||
AdvSceneSwitcher.condition.midi.condition.message="MIDI message was received"
|
||||
AdvSceneSwitcher.condition.midi.condition.deviceName="MIDI device is connected"
|
||||
AdvSceneSwitcher.condition.midi.condition.deviceName.info="On some platforms with certain APIs dynamic MIDI device detection might not function.\nSo this type of check might not be 100% reliable in all circumstances."
|
||||
AdvSceneSwitcher.condition.midi.entry.message="{{conditions}}from{{device}}which matches:"
|
||||
AdvSceneSwitcher.condition.midi.entry.deviceName="{{conditions}}{{deviceNames}}{{regex}}{{deviceListInfo}}"
|
||||
>>>>>>> c4e35d1a (Add MIDI device name check)
|
||||
AdvSceneSwitcher.condition.midi.entry.listen="Set MIDI message selection to messages incoming on selected device:{{listenButton}}"
|
||||
AdvSceneSwitcher.condition.display="Display"
|
||||
AdvSceneSwitcher.condition.display.type.displayName="Name of connected displays matches"
|
||||
|
|
|
|||
|
|
@ -446,7 +446,6 @@ AdvSceneSwitcher.condition.run="Exécution"
|
|||
AdvSceneSwitcher.condition.run.entry="Le processus se termine avant le délai de{{timeout}}secondes"
|
||||
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}Vérifier le code de sortie{{exitCode}}
|
||||
AdvSceneSwitcher.condition.midi="MIDI"
|
||||
AdvSceneSwitcher.condition.midi.entry="Message reçu depuis{{device}}qui correspond à :"
|
||||
AdvSceneSwitcher.condition.midi.entry.listen="Définir la sélection des messages MIDI pour les messages entrants sur l'appareil sélectionné :{{listenButton}}"
|
||||
AdvSceneSwitcher.condition.display="Affichage"
|
||||
AdvSceneSwitcher.condition.display.type.displayName="Le nom des écrans connectés correspond à"
|
||||
|
|
|
|||
|
|
@ -434,7 +434,6 @@ AdvSceneSwitcher.condition.run="运行"
|
|||
AdvSceneSwitcher.condition.run.entry="进程在超时 {{timeout}} 秒之前退出"
|
||||
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}检查退出代码{{exitCode}}"
|
||||
AdvSceneSwitcher.condition.midi="MIDI"
|
||||
AdvSceneSwitcher.condition.midi.entry="从{{device}} 收到的信息,符合:(从不咕咕的阿坤:这个好像是声卡工作是录音相关的功能,英文太抽象了,我就硬译过来了,如有相关设备,音乐好的,可以根据英文翻译好发给我!)"
|
||||
AdvSceneSwitcher.condition.midi.entry.listen="将MIDI信息选择设置为从选定设备上接收的信息: {{listenButton}}"
|
||||
AdvSceneSwitcher.condition.display="显示器"
|
||||
AdvSceneSwitcher.condition.display.type.displayName="连接的显示器的名称匹配"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,73 @@ bool MacroConditionMidi::_registered = MacroConditionFactory::Register(
|
|||
{MacroConditionMidi::Create, MacroConditionMidiEdit::Create,
|
||||
"AdvSceneSwitcher.condition.midi"});
|
||||
|
||||
static const std::map<MacroConditionMidi::Condition, std::string>
|
||||
conditionTypes = {
|
||||
{MacroConditionMidi::Condition::MIDI_MESSAGE,
|
||||
"AdvSceneSwitcher.condition.midi.condition.message"},
|
||||
{MacroConditionMidi::Condition::MIDI_CONNECTED_DEVICE_NAMES,
|
||||
"AdvSceneSwitcher.condition.midi.condition.deviceName"},
|
||||
};
|
||||
|
||||
bool MacroConditionMidi::CheckCondition()
|
||||
{
|
||||
switch (_condition) {
|
||||
case Condition::MIDI_MESSAGE:
|
||||
return CheckMessage();
|
||||
case Condition::MIDI_CONNECTED_DEVICE_NAMES:
|
||||
return CheckConnectedDevcieNames();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MacroConditionMidi::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
_message.Save(obj);
|
||||
_device.Save(obj);
|
||||
_deviceName.Save(obj, "deviceName");
|
||||
_regex.Save(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionMidi::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_message.Load(obj);
|
||||
_device.Load(obj);
|
||||
_deviceName.Load(obj, "deviceName");
|
||||
_regex.Load(obj);
|
||||
SetCondition(
|
||||
static_cast<Condition>(obs_data_get_int(obj, "condition")));
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroConditionMidi::GetShortDesc() const
|
||||
{
|
||||
return _condition == MacroConditionMidi::Condition::MIDI_MESSAGE
|
||||
? _device.Name()
|
||||
: "";
|
||||
}
|
||||
|
||||
void MacroConditionMidi::SetDevice(const MidiDevice &dev)
|
||||
{
|
||||
_device = dev;
|
||||
_messageBuffer = dev.RegisterForMidiMessages();
|
||||
}
|
||||
|
||||
void MacroConditionMidi::SetCondition(Condition condition)
|
||||
{
|
||||
_condition = condition;
|
||||
if (_condition == Condition::MIDI_MESSAGE) {
|
||||
_messageBuffer = _device.RegisterForMidiMessages();
|
||||
}
|
||||
SetupTempVars();
|
||||
}
|
||||
|
||||
bool MacroConditionMidi::CheckMessage()
|
||||
{
|
||||
if (!_messageBuffer) {
|
||||
return false;
|
||||
|
|
@ -40,37 +106,27 @@ bool MacroConditionMidi::CheckCondition()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool MacroConditionMidi::Save(obs_data_t *obj) const
|
||||
bool MacroConditionMidi::CheckConnectedDevcieNames()
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
_message.Save(obj);
|
||||
_device.Save(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionMidi::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_message.Load(obj);
|
||||
_device.Load(obj);
|
||||
_messageBuffer = _device.RegisterForMidiMessages();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroConditionMidi::GetShortDesc() const
|
||||
{
|
||||
return _device.Name();
|
||||
}
|
||||
|
||||
void MacroConditionMidi::SetDevice(const MidiDevice &dev)
|
||||
{
|
||||
_device = dev;
|
||||
_messageBuffer = dev.RegisterForMidiMessages();
|
||||
auto deviceNames = GetDeviceNames();
|
||||
if (!_regex.Enabled()) {
|
||||
return std::find(deviceNames.begin(), deviceNames.end(),
|
||||
std::string(_deviceName)) != deviceNames.end();
|
||||
}
|
||||
for (const auto &deviceName : deviceNames) {
|
||||
if (_regex.Matches(deviceName, _deviceName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MacroConditionMidi::SetupTempVars()
|
||||
{
|
||||
MacroCondition::SetupTempVars();
|
||||
if (_condition == Condition::MIDI_CONNECTED_DEVICE_NAMES) {
|
||||
return;
|
||||
}
|
||||
AddTempvar("type",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.midi.type"));
|
||||
AddTempvar("channel",
|
||||
|
|
@ -98,16 +154,45 @@ void MacroConditionMidi::SetVariableValues(const MidiMessage &m)
|
|||
SetTempVarValue("value2", std::to_string(m.Value()));
|
||||
}
|
||||
|
||||
static void populateConditionSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[_, name] : conditionTypes) {
|
||||
list->addItem(obs_module_text(name.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
MacroConditionMidiEdit::MacroConditionMidiEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionMidi> entryData)
|
||||
: QWidget(parent),
|
||||
_conditions(new QComboBox()),
|
||||
_devices(new MidiDeviceSelection(this, MidiDeviceType::INPUT)),
|
||||
_message(new MidiMessageSelection(this)),
|
||||
_resetMidiDevices(new QPushButton(
|
||||
obs_module_text("AdvSceneSwitcher.midi.resetDevices"))),
|
||||
_listen(new QPushButton(
|
||||
obs_module_text("AdvSceneSwitcher.midi.startListen")))
|
||||
obs_module_text("AdvSceneSwitcher.midi.startListen"))),
|
||||
_deviceNames(new QComboBox()),
|
||||
_regex(new RegexConfigWidget()),
|
||||
_deviceListInfo(new QLabel()),
|
||||
_listenLayout(new QHBoxLayout()),
|
||||
_entryLayout(new QHBoxLayout())
|
||||
{
|
||||
_deviceNames->addItems(GetDeviceNamesAsQStringList());
|
||||
_deviceNames->setEditable(true);
|
||||
|
||||
QString path = GetThemeTypeName() == "Light"
|
||||
? ":/res/images/help.svg"
|
||||
: ":/res/images/help_light.svg";
|
||||
QIcon icon(path);
|
||||
QPixmap pixmap = icon.pixmap(QSize(16, 16));
|
||||
_deviceListInfo->setPixmap(pixmap);
|
||||
_deviceListInfo->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.midi.condition.deviceName.info"));
|
||||
|
||||
populateConditionSelection(_conditions);
|
||||
|
||||
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(_devices,
|
||||
SIGNAL(DeviceSelectionChanged(const MidiDevice &)),
|
||||
this,
|
||||
|
|
@ -121,19 +206,21 @@ MacroConditionMidiEdit::MacroConditionMidiEdit(
|
|||
SLOT(ToggleListen()));
|
||||
QWidget::connect(&_listenTimer, SIGNAL(timeout()), this,
|
||||
SLOT(SetMessageSelectionToLastReceived()));
|
||||
QWidget::connect(_deviceNames,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(DeviceNameChanged(const QString &)));
|
||||
QWidget::connect(_regex,
|
||||
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
|
||||
SLOT(RegexChanged(const RegexConfig &)));
|
||||
|
||||
auto entryLayout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.condition.midi.entry"),
|
||||
entryLayout, {{"{{device}}", _devices}});
|
||||
auto listenLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.midi.entry.listen"),
|
||||
listenLayout, {{"{{listenButton}}", _listen}});
|
||||
_listenLayout, {{"{{listenButton}}", _listen}});
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(entryLayout);
|
||||
mainLayout->addLayout(_entryLayout);
|
||||
mainLayout->addWidget(_message);
|
||||
mainLayout->addLayout(listenLayout);
|
||||
mainLayout->addLayout(_listenLayout);
|
||||
mainLayout->addWidget(_resetMidiDevices);
|
||||
setLayout(mainLayout);
|
||||
|
||||
|
|
@ -155,11 +242,14 @@ void MacroConditionMidiEdit::UpdateEntryData()
|
|||
return;
|
||||
}
|
||||
|
||||
_conditions->setCurrentIndex(
|
||||
static_cast<int>(_entryData->GetCondition()));
|
||||
_message->SetMessage(_entryData->_message);
|
||||
_devices->SetDevice(_entryData->GetDevice());
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
_deviceNames->setCurrentText(QString::fromStdString(
|
||||
_entryData->_deviceName.UnresolvedValue()));
|
||||
_regex->SetRegexConfig(_entryData->_regex);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionMidiEdit::DeviceSelectionChanged(const MidiDevice &device)
|
||||
|
|
@ -211,6 +301,46 @@ void MacroConditionMidiEdit::EnableListening(bool enable)
|
|||
}
|
||||
}
|
||||
|
||||
void MacroConditionMidiEdit::SetWidgetVisibility()
|
||||
{
|
||||
_entryLayout->removeWidget(_conditions);
|
||||
_entryLayout->removeWidget(_devices);
|
||||
_entryLayout->removeWidget(_deviceNames);
|
||||
_entryLayout->removeWidget(_regex);
|
||||
|
||||
ClearLayout(_entryLayout);
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{conditions}}", _conditions},
|
||||
{"{{device}}", _devices},
|
||||
{"{{deviceNames}}", _deviceNames},
|
||||
{"{{regex}}", _regex},
|
||||
{"{{deviceListInfo}}", _deviceListInfo},
|
||||
};
|
||||
|
||||
const bool isMessageCheck = _entryData->GetCondition() ==
|
||||
MacroConditionMidi::Condition::MIDI_MESSAGE;
|
||||
|
||||
auto layoutString =
|
||||
isMessageCheck
|
||||
? "AdvSceneSwitcher.condition.midi.entry.message"
|
||||
: "AdvSceneSwitcher.condition.midi.entry.deviceName";
|
||||
|
||||
PlaceWidgets(obs_module_text(layoutString), _entryLayout,
|
||||
widgetPlaceholders);
|
||||
|
||||
SetLayoutVisible(_listenLayout, isMessageCheck);
|
||||
_devices->setVisible(isMessageCheck);
|
||||
_message->setVisible(isMessageCheck);
|
||||
_resetMidiDevices->setVisible(isMessageCheck);
|
||||
_deviceNames->setVisible(!isMessageCheck);
|
||||
_regex->setVisible(!isMessageCheck);
|
||||
_deviceListInfo->setVisible(!isMessageCheck);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroConditionMidiEdit::ToggleListen()
|
||||
{
|
||||
if (!_entryData) {
|
||||
|
|
@ -249,4 +379,41 @@ void MacroConditionMidiEdit::SetMessageSelectionToLastReceived()
|
|||
_entryData->_message = *message;
|
||||
}
|
||||
|
||||
void MacroConditionMidiEdit::ConditionChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->SetCondition(
|
||||
static_cast<MacroConditionMidi::Condition>(value));
|
||||
SetWidgetVisibility();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroConditionMidiEdit::DeviceNameChanged(const QString &deviceName)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_deviceName = deviceName.toStdString();
|
||||
}
|
||||
|
||||
void MacroConditionMidiEdit::RegexChanged(const RegexConfig &conf)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_regex = conf;
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "midi-helpers.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
|
|
@ -23,11 +25,23 @@ public:
|
|||
void SetDevice(const MidiDevice &dev);
|
||||
const MidiDevice &GetDevice() const { return _device; }
|
||||
MidiMessage _message;
|
||||
StringVariable _deviceName;
|
||||
RegexConfig _regex;
|
||||
|
||||
enum class Condition {
|
||||
MIDI_MESSAGE,
|
||||
MIDI_CONNECTED_DEVICE_NAMES,
|
||||
};
|
||||
void SetCondition(Condition);
|
||||
Condition GetCondition() const { return _condition; }
|
||||
|
||||
private:
|
||||
bool CheckMessage();
|
||||
bool CheckConnectedDevcieNames();
|
||||
void SetupTempVars();
|
||||
void SetVariableValues(const MidiMessage &);
|
||||
|
||||
Condition _condition = Condition::MIDI_MESSAGE;
|
||||
MidiDevice _device;
|
||||
MidiMessageBuffer _messageBuffer;
|
||||
std::chrono::high_resolution_clock::time_point _lastCheck{};
|
||||
|
|
@ -58,18 +72,29 @@ private slots:
|
|||
void ResetMidiDevices();
|
||||
void ToggleListen();
|
||||
void SetMessageSelectionToLastReceived();
|
||||
void ConditionChanged(int);
|
||||
void DeviceNameChanged(const QString &);
|
||||
void RegexChanged(const RegexConfig &);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
private:
|
||||
void EnableListening(bool);
|
||||
void SetWidgetVisibility();
|
||||
|
||||
std::shared_ptr<MacroConditionMidi> _entryData;
|
||||
|
||||
QComboBox *_conditions;
|
||||
MidiDeviceSelection *_devices;
|
||||
MidiMessageSelection *_message;
|
||||
QPushButton *_resetMidiDevices;
|
||||
QPushButton *_listen;
|
||||
QComboBox *_deviceNames;
|
||||
RegexConfigWidget *_regex;
|
||||
QLabel *_deviceListInfo;
|
||||
QHBoxLayout *_listenLayout;
|
||||
QHBoxLayout *_entryLayout;
|
||||
|
||||
QTimer _listenTimer;
|
||||
MidiMessageBuffer _messageBuffer;
|
||||
bool _currentlyListening = false;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ static bool setupDeviceObservers()
|
|||
static std::vector<libremidi::observer> observers;
|
||||
for (auto api : libremidi::available_apis()) {
|
||||
libremidi::observer_configuration cbs;
|
||||
cbs.input_added = [=](const libremidi::input_port &p) {
|
||||
cbs.track_virtual = true;
|
||||
cbs.input_added = [](const libremidi::input_port &p) {
|
||||
auto dev = MidiDeviceInstance::GetDevice(p);
|
||||
if (!dev) {
|
||||
return;
|
||||
|
|
@ -32,7 +33,7 @@ static bool setupDeviceObservers()
|
|||
dev->ClosePort();
|
||||
dev->OpenPort();
|
||||
};
|
||||
cbs.input_removed = [=](const libremidi::input_port &p) {
|
||||
cbs.input_removed = [](const libremidi::input_port &p) {
|
||||
auto dev = MidiDeviceInstance::GetDevice(p);
|
||||
if (!dev) {
|
||||
return;
|
||||
|
|
@ -40,7 +41,7 @@ static bool setupDeviceObservers()
|
|||
blog(LOG_INFO, "MIDI input removed: %s",
|
||||
p.port_name.c_str());
|
||||
};
|
||||
cbs.output_added = [=](const libremidi::output_port &p) {
|
||||
cbs.output_added = [](const libremidi::output_port &p) {
|
||||
auto dev = MidiDeviceInstance::GetDevice(p);
|
||||
if (!dev) {
|
||||
return;
|
||||
|
|
@ -50,7 +51,7 @@ static bool setupDeviceObservers()
|
|||
dev->ClosePort();
|
||||
dev->OpenPort();
|
||||
};
|
||||
cbs.output_removed = [=](const libremidi::output_port &p) {
|
||||
cbs.output_removed = [](const libremidi::output_port &p) {
|
||||
auto dev = MidiDeviceInstance::GetDevice(p);
|
||||
if (!dev) {
|
||||
return;
|
||||
|
|
@ -328,35 +329,95 @@ advss::MidiDeviceInstance::GetDevice(const libremidi::output_port &p)
|
|||
|
||||
static inline QStringList getInputDeviceNames()
|
||||
{
|
||||
QStringList devices;
|
||||
static QStringList devices;
|
||||
static std::mutex m;
|
||||
static std::vector<libremidi::observer> observers;
|
||||
static bool setupDone = false;
|
||||
|
||||
if (setupDone) {
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
return devices;
|
||||
}
|
||||
|
||||
// Set up observers
|
||||
try {
|
||||
libremidi::observer obs;
|
||||
for (const libremidi::input_port &port :
|
||||
obs.get_input_ports()) {
|
||||
devices << QString::fromStdString(
|
||||
getNameFromPortInformation(port));
|
||||
for (auto api : libremidi::available_apis()) {
|
||||
libremidi::observer_configuration cbs;
|
||||
cbs.track_virtual = true;
|
||||
cbs.input_added = [](const libremidi::input_port &p) {
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
auto device = QString::fromStdString(
|
||||
getNameFromPortInformation(p));
|
||||
if (devices.indexOf(device) == -1) {
|
||||
devices << device;
|
||||
}
|
||||
};
|
||||
cbs.input_removed = [](const libremidi::input_port &p) {
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
auto device = QString::fromStdString(
|
||||
getNameFromPortInformation(p));
|
||||
if (int i = devices.indexOf(device) != -1) {
|
||||
devices.removeAt(i);
|
||||
}
|
||||
};
|
||||
observers.emplace_back(
|
||||
cbs,
|
||||
libremidi::observer_configuration_for(api));
|
||||
}
|
||||
} catch (const libremidi::driver_error &error) {
|
||||
blog(LOG_WARNING, "Failed to get midi input devices: %s",
|
||||
error.what());
|
||||
}
|
||||
|
||||
setupDone = true;
|
||||
return devices;
|
||||
}
|
||||
|
||||
static inline QStringList getOutputDeviceNames()
|
||||
{
|
||||
QStringList devices;
|
||||
static QStringList devices;
|
||||
static std::mutex m;
|
||||
static std::vector<libremidi::observer> observers;
|
||||
static bool setupDone = false;
|
||||
|
||||
if (setupDone) {
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
return devices;
|
||||
}
|
||||
|
||||
// Set up observers
|
||||
try {
|
||||
libremidi::observer obs;
|
||||
for (const libremidi::output_port &port :
|
||||
obs.get_output_ports()) {
|
||||
devices << QString::fromStdString(
|
||||
getNameFromPortInformation(port));
|
||||
for (auto api : libremidi::available_apis()) {
|
||||
libremidi::observer_configuration cbs;
|
||||
cbs.track_virtual = true;
|
||||
cbs.output_added = [](const libremidi::output_port &p) {
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
auto device = QString::fromStdString(
|
||||
getNameFromPortInformation(p));
|
||||
if (devices.indexOf(device) == -1) {
|
||||
devices << device;
|
||||
}
|
||||
};
|
||||
cbs.output_removed =
|
||||
[](const libremidi::output_port &p) {
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
auto device = QString::fromStdString(
|
||||
getNameFromPortInformation(p));
|
||||
if (int i = devices.indexOf(device) !=
|
||||
-1) {
|
||||
devices.removeAt(i);
|
||||
}
|
||||
};
|
||||
observers.emplace_back(
|
||||
cbs,
|
||||
libremidi::observer_configuration_for(api));
|
||||
}
|
||||
} catch (const libremidi::driver_error &error) {
|
||||
blog(LOG_WARNING, "Failed to get midi output devices: %s",
|
||||
error.what());
|
||||
}
|
||||
|
||||
setupDone = true;
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
|
@ -997,6 +1058,28 @@ void MidiMessageSelection::ValueChanged(const NumberVariable<int> &v)
|
|||
emit MidiMessageChanged((_currentSelection));
|
||||
}
|
||||
|
||||
std::vector<std::string> GetDeviceNames()
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
const auto names = GetDeviceNamesAsQStringList();
|
||||
for (const auto &name : names) {
|
||||
result.emplace_back(name.toStdString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList GetDeviceNamesAsQStringList()
|
||||
{
|
||||
QStringList result;
|
||||
for (const auto &input : getInputDeviceNames()) {
|
||||
result << input;
|
||||
}
|
||||
for (const auto &output : getOutputDeviceNames()) {
|
||||
result << output;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList GetAllNotes()
|
||||
{
|
||||
static bool done = false;
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ private:
|
|||
const MidiDeviceType _type;
|
||||
};
|
||||
|
||||
std::vector<std::string> GetDeviceNames();
|
||||
QStringList GetDeviceNamesAsQStringList();
|
||||
QStringList GetAllNotes();
|
||||
|
||||
} // namespace advss
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user