Added: Voicemeeter audio processing support. When Voicemeeter is installed, it can be selected in the Configurator.
This commit is contained in:
1 parent
46d921945f
commit
989812ba36
55 files changed
+3044
-278
No files matched your search
@@ -22,6 +22,8 @@
|
||||
#include "FilterEngine.h"
|
||||
#include "AnalysisThread.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
AnalysisThread::AnalysisThread()
|
||||
{
|
||||
}
|
||||
@@ -50,10 +52,10 @@ AnalysisThread::~AnalysisThread()
|
||||
fftwf_destroy_plan(planForward);
|
||||
}
|
||||
|
||||
void AnalysisThread::setParameters(DeviceAPOInfo* device, int channelMask, int channelIndex, QString configPath, int frameCount)
|
||||
void AnalysisThread::setParameters(shared_ptr<AbstractAPOInfo> device, int channelMask, int channelIndex, QString configPath, int frameCount)
|
||||
{
|
||||
QMutexLocker mutexLocker(&mutex);
|
||||
this->device = *device;
|
||||
this->device = device;
|
||||
this->channelMask = channelMask;
|
||||
this->channelIndex = channelIndex;
|
||||
this->configPath = configPath;
|
||||
@@ -125,7 +127,7 @@ void AnalysisThread::run()
|
||||
break;
|
||||
}
|
||||
|
||||
DeviceAPOInfo device = this->device;
|
||||
shared_ptr<AbstractAPOInfo> device = this->device;
|
||||
int channelMask = this->channelMask;
|
||||
int channelIndex = this->channelIndex;
|
||||
QString configPath = this->configPath;
|
||||
@@ -136,8 +138,8 @@ void AnalysisThread::run()
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
unsigned channelCount = device.channelCount;
|
||||
if (channelMask != 0 && channelMask != device.channelMask)
|
||||
unsigned channelCount = device->getChannelCount();
|
||||
if (channelMask != 0 && channelMask != device->getChannelMask())
|
||||
{
|
||||
channelCount = 0;
|
||||
for (int i = 0; i < 31; i++)
|
||||
@@ -148,11 +150,11 @@ void AnalysisThread::run()
|
||||
}
|
||||
}
|
||||
|
||||
unsigned sampleRate = device.sampleRate;
|
||||
unsigned sampleRate = device->getSampleRate();
|
||||
|
||||
qint64 startTime = timer.nsecsElapsed();
|
||||
FilterEngine engine;
|
||||
engine.setDeviceInfo(device.isInput, true, device.deviceName, device.connectionName, device.deviceGuid);
|
||||
engine.setDeviceInfo(device->isInput(), true, device->getDeviceName(), device->getConnectionName(), device->getDeviceGuid(), device->getDeviceString());
|
||||
engine.initialize(sampleRate, channelCount, channelCount, channelCount, channelMask, frameCount, configPath.toStdWString());
|
||||
double initializationTime = (timer.nsecsElapsed() - startTime) / 1e6;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class AnalysisThread : public QThread
|
||||
public:
|
||||
AnalysisThread();
|
||||
~AnalysisThread();
|
||||
void setParameters(DeviceAPOInfo* device, int channelMask, int channelIndex, QString configPath, int frameCount);
|
||||
void setParameters(std::shared_ptr<AbstractAPOInfo> device, int channelMask, int channelIndex, QString configPath, int frameCount);
|
||||
void beginGetResult();
|
||||
void endGetResult();
|
||||
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
bool quit = false;
|
||||
|
||||
// input
|
||||
DeviceAPOInfo device;
|
||||
std::shared_ptr<AbstractAPOInfo> device;
|
||||
int channelMask;
|
||||
int channelIndex;
|
||||
QString configPath;
|
||||
|
||||
+8
-4
@@ -114,7 +114,9 @@ SOURCES += main.cpp\
|
||||
widgets/ExponentialSpinBox.cpp \
|
||||
FilterTableMimeData.cpp \
|
||||
helpers/DPIHelper.cpp \
|
||||
CustomStyle.cpp
|
||||
CustomStyle.cpp \
|
||||
../AbstractAPOInfo.cpp \
|
||||
../VoicemeeterAPOInfo.cpp
|
||||
|
||||
HEADERS += \
|
||||
../helpers/LogHelper.h \
|
||||
@@ -217,7 +219,9 @@ HEADERS += \
|
||||
widgets/ExponentialSpinBox.h \
|
||||
FilterTableMimeData.h \
|
||||
helpers/DPIHelper.h \
|
||||
CustomStyle.h
|
||||
CustomStyle.h \
|
||||
../AbstractAPOInfo.h \
|
||||
../VoicemeeterAPOInfo.h
|
||||
|
||||
FORMS += \
|
||||
guis/PreampFilterGUI.ui \
|
||||
@@ -238,7 +242,7 @@ FORMS += \
|
||||
guis/StageFilterGUI.ui
|
||||
|
||||
INCLUDEPATH += $$PWD/.. "C:/Program Files/libsndfile/include" "C:/Program Files/fftw3" "C:/Program Files/muparserx_v3_0_1/parser"
|
||||
LIBS += advapi32.lib version.lib ole32.lib Shlwapi.lib authz.lib libsndfile-1.lib libfftw3f-3.lib
|
||||
LIBS += user32.lib advapi32.lib version.lib ole32.lib Shlwapi.lib authz.lib libsndfile-1.lib libfftw3f-3.lib
|
||||
|
||||
build_pass:CONFIG(debug, debug|release) {
|
||||
LIBS += muparserxd.lib
|
||||
@@ -256,6 +260,6 @@ RESOURCES += \
|
||||
Editor.qrc
|
||||
TRANSLATIONS += translations/Editor_de.ts
|
||||
|
||||
RC_ICONS = icons/accessories-text-editor.ico
|
||||
RC_FILE = Editor.rc
|
||||
|
||||
DISTFILES += ../uncrustify.cfg
|
||||
@@ -0,0 +1,44 @@
|
||||
# if defined(UNDER_CE)
|
||||
# include <winbase.h>
|
||||
# else
|
||||
# include <windows.h>
|
||||
# endif
|
||||
#include "../version.h"
|
||||
|
||||
#define S2(x) #x
|
||||
#define S(x) S2(x)
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "icons\\accessories-text-editor.ico"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION MAJOR,MINOR,REVISION,0
|
||||
PRODUCTVERSION MAJOR,MINOR,REVISION,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "Equalizer APO Configuration Editor\0"
|
||||
VALUE "FileVersion", S(MAJOR) "." S(MINOR) "." S(REVISION) ".0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2017\0"
|
||||
VALUE "OriginalFilename", "Editor.exe\0"
|
||||
VALUE "ProductName", "Configuration Editor\0"
|
||||
VALUE "ProductVersion", S(MAJOR) "." S(MINOR) "." S(REVISION) ".0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 1200
|
||||
END
|
||||
END
|
||||
/* End of Version info */
|
||||
|
||||
@@ -83,7 +83,7 @@ FilterTable::FilterTable(MainWindow* mainWindow, QWidget* parent)
|
||||
QApplication::instance()->installEventFilter(this);
|
||||
}
|
||||
|
||||
void FilterTable::initialize(QScrollArea* scrollArea, const QList<DeviceAPOInfo>& outputDevices, const QList<DeviceAPOInfo>& inputDevices)
|
||||
void FilterTable::initialize(QScrollArea* scrollArea, const QList<shared_ptr<AbstractAPOInfo> >& outputDevices, const QList<shared_ptr<AbstractAPOInfo> >& inputDevices)
|
||||
{
|
||||
this->scrollArea = scrollArea;
|
||||
this->outputDevices = outputDevices;
|
||||
@@ -93,7 +93,7 @@ void FilterTable::initialize(QScrollArea* scrollArea, const QList<DeviceAPOInfo>
|
||||
factory->initialize(this);
|
||||
}
|
||||
|
||||
void FilterTable::updateDeviceAndChannelMask(DeviceAPOInfo* selectedDevice, int channelMask)
|
||||
void FilterTable::updateDeviceAndChannelMask(shared_ptr<AbstractAPOInfo> selectedDevice, int channelMask)
|
||||
{
|
||||
this->selectedDevice = selectedDevice;
|
||||
this->selectedChannelMask = channelMask;
|
||||
@@ -222,7 +222,9 @@ void FilterTable::updateGuis()
|
||||
|
||||
void FilterTable::propagateChannels()
|
||||
{
|
||||
vector<wstring> channelNames = ChannelHelper::getChannelNames(selectedDevice->channelCount, selectedChannelMask);
|
||||
vector<wstring> channelNames;
|
||||
if (selectedDevice != NULL)
|
||||
channelNames = ChannelHelper::getChannelNames(selectedDevice->getChannelCount(), selectedChannelMask);
|
||||
|
||||
for (Item* item : items)
|
||||
{
|
||||
@@ -1009,17 +1011,17 @@ const QSet<FilterTable::Item*>& FilterTable::getSelectedItems() const
|
||||
return selected;
|
||||
}
|
||||
|
||||
const QList<DeviceAPOInfo>& FilterTable::getOutputDevices() const
|
||||
const QList<shared_ptr<AbstractAPOInfo> >& FilterTable::getOutputDevices() const
|
||||
{
|
||||
return outputDevices;
|
||||
}
|
||||
|
||||
const QList<DeviceAPOInfo>& FilterTable::getInputDevices() const
|
||||
const QList<shared_ptr<AbstractAPOInfo> >& FilterTable::getInputDevices() const
|
||||
{
|
||||
return inputDevices;
|
||||
}
|
||||
|
||||
DeviceAPOInfo* FilterTable::getSelectedDevice() const
|
||||
shared_ptr<AbstractAPOInfo> FilterTable::getSelectedDevice() const
|
||||
{
|
||||
return selectedDevice;
|
||||
}
|
||||
|
||||
@@ -56,8 +56,8 @@ public:
|
||||
};
|
||||
|
||||
explicit FilterTable(MainWindow* mainWindow, QWidget* parent = 0);
|
||||
void initialize(QScrollArea* scrollArea, const QList<DeviceAPOInfo>& outputDevices, const QList<DeviceAPOInfo>& inputDevices);
|
||||
void updateDeviceAndChannelMask(DeviceAPOInfo* selectedDevice, int selectedChannelMask);
|
||||
void initialize(QScrollArea* scrollArea, const QList<std::shared_ptr<AbstractAPOInfo> >& outputDevices, const QList<std::shared_ptr<AbstractAPOInfo> >& inputDevices);
|
||||
void updateDeviceAndChannelMask(std::shared_ptr<AbstractAPOInfo> selectedDevice, int selectedChannelMask);
|
||||
void updateGuis();
|
||||
void propagateChannels();
|
||||
QList<QString> getLines();
|
||||
@@ -70,9 +70,9 @@ public:
|
||||
void paste();
|
||||
void deleteSelectedLines();
|
||||
|
||||
const QList<DeviceAPOInfo>& getOutputDevices() const;
|
||||
const QList<DeviceAPOInfo>& getInputDevices() const;
|
||||
DeviceAPOInfo* getSelectedDevice() const;
|
||||
const QList<std::shared_ptr<AbstractAPOInfo> >& getOutputDevices() const;
|
||||
const QList<std::shared_ptr<AbstractAPOInfo> >& getInputDevices() const;
|
||||
std::shared_ptr<AbstractAPOInfo> getSelectedDevice() const;
|
||||
int getSelectedChannelMask() const;
|
||||
|
||||
const QSet<Item*>& getSelectedItems() const;
|
||||
@@ -131,9 +131,9 @@ private:
|
||||
QList<IFilterGUIFactory*> factories;
|
||||
bool scrollingNow = false;
|
||||
QPoint scrollStartPoint;
|
||||
QList<DeviceAPOInfo> outputDevices;
|
||||
QList<DeviceAPOInfo> inputDevices;
|
||||
DeviceAPOInfo* selectedDevice;
|
||||
QList<std::shared_ptr<AbstractAPOInfo> > outputDevices;
|
||||
QList<std::shared_ptr<AbstractAPOInfo> > inputDevices;
|
||||
std::shared_ptr<AbstractAPOInfo> selectedDevice;
|
||||
int selectedChannelMask;
|
||||
QString configPath;
|
||||
int minimumHeightHint = 0;
|
||||
|
||||
+39
-39
@@ -51,15 +51,15 @@ using namespace std;
|
||||
MainWindow::MainWindow(QDir configDir, QWidget* parent)
|
||||
: QMainWindow(parent), ui(new Ui::MainWindow), configDir(configDir)
|
||||
{
|
||||
outputDevices = QList<DeviceAPOInfo>::fromVector(QVector<DeviceAPOInfo>::fromStdVector(DeviceAPOInfo::loadAllInfos(false)));
|
||||
inputDevices = QList<DeviceAPOInfo>::fromVector(QVector<DeviceAPOInfo>::fromStdVector(DeviceAPOInfo::loadAllInfos(true)));
|
||||
outputDevices = QList<shared_ptr<AbstractAPOInfo> >::fromVector(QVector<shared_ptr<AbstractAPOInfo> >::fromStdVector(DeviceAPOInfo::loadAllInfos(false)));
|
||||
inputDevices = QList<shared_ptr<AbstractAPOInfo> >::fromVector(QVector<shared_ptr<AbstractAPOInfo> >::fromStdVector(DeviceAPOInfo::loadAllInfos(true)));
|
||||
|
||||
defaultOutputDevice = NULL;
|
||||
for (DeviceAPOInfo& apoInfo : outputDevices)
|
||||
for (shared_ptr<AbstractAPOInfo>& apoInfo : outputDevices)
|
||||
{
|
||||
if (apoInfo.isDefaultDevice)
|
||||
if (apoInfo->isDefaultDevice())
|
||||
{
|
||||
defaultOutputDevice = &apoInfo;
|
||||
defaultOutputDevice = apoInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ MainWindow::MainWindow(QDir configDir, QWidget* parent)
|
||||
|
||||
QStandardItemModel* model = qobject_cast<QStandardItemModel*>(deviceComboBox->model());
|
||||
if (defaultOutputDevice != NULL)
|
||||
deviceComboBox->addItem(tr("Default") + " (" + QString::fromStdWString(defaultOutputDevice->connectionName) + " - " + QString::fromStdWString(defaultOutputDevice->deviceName) + ")", NULL);
|
||||
deviceComboBox->addItem(tr("Default") + " (" + QString::fromStdWString(defaultOutputDevice->getConnectionName()) + " - " + QString::fromStdWString(defaultOutputDevice->getDeviceName()) + ")", NULL);
|
||||
|
||||
deviceComboBox->addItem(tr("Playback devices:"));
|
||||
QStandardItem* item = model->item(model->rowCount() - 1);
|
||||
@@ -115,18 +115,18 @@ MainWindow::MainWindow(QDir configDir, QWidget* parent)
|
||||
item->setFont(font);
|
||||
item->setSelectable(false);
|
||||
|
||||
for (DeviceAPOInfo& apoInfo : outputDevices)
|
||||
if (apoInfo.isInstalled)
|
||||
deviceComboBox->addItem(QString::fromStdWString(apoInfo.connectionName) + " - " + QString::fromStdWString(apoInfo.deviceName), QVariant::fromValue(&apoInfo));
|
||||
for (shared_ptr<AbstractAPOInfo>& apoInfo : outputDevices)
|
||||
if (apoInfo->isInstalled())
|
||||
deviceComboBox->addItem(QString::fromStdWString(apoInfo->getConnectionName()) + " - " + QString::fromStdWString(apoInfo->getDeviceName()), QVariant::fromValue(apoInfo));
|
||||
|
||||
deviceComboBox->addItem(tr("Capture devices:"));
|
||||
item = model->item(model->rowCount() - 1);
|
||||
item->setFont(font);
|
||||
item->setSelectable(false);
|
||||
|
||||
for (DeviceAPOInfo& apoInfo : inputDevices)
|
||||
if (apoInfo.isInstalled)
|
||||
deviceComboBox->addItem(QString::fromStdWString(apoInfo.connectionName) + " - " + QString::fromStdWString(apoInfo.deviceName), QVariant::fromValue(&apoInfo));
|
||||
for (shared_ptr<AbstractAPOInfo>& apoInfo : inputDevices)
|
||||
if (apoInfo->isInstalled())
|
||||
deviceComboBox->addItem(QString::fromStdWString(apoInfo->getConnectionName()) + " - " + QString::fromStdWString(apoInfo->getDeviceName()), QVariant::fromValue(apoInfo));
|
||||
|
||||
connect(channelConfigurationComboBox, SIGNAL(activated(int)), this, SLOT(channelConfigurationSelected(int)));
|
||||
|
||||
@@ -183,7 +183,7 @@ void MainWindow::doChecks()
|
||||
}
|
||||
}
|
||||
|
||||
if (!defaultOutputDevice->isInstalled)
|
||||
if (defaultOutputDevice != NULL && !defaultOutputDevice->isInstalled())
|
||||
{
|
||||
if (QMessageBox::warning(this, tr("APO not installed to device"), tr("Equalizer APO has not been installed to the selected device.\nDo you want to run the Configurator application to fix the problem?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
|
||||
{
|
||||
@@ -192,23 +192,23 @@ void MainWindow::doChecks()
|
||||
}
|
||||
}
|
||||
|
||||
DeviceAPOInfo* disabledApoInfo = NULL;
|
||||
for (DeviceAPOInfo& apoInfo : outputDevices)
|
||||
AbstractAPOInfo* disabledApoInfo = NULL;
|
||||
for (shared_ptr<AbstractAPOInfo>& apoInfo : outputDevices)
|
||||
{
|
||||
if (apoInfo.isInstalled && apoInfo.isEnhancementsDisabled)
|
||||
if (apoInfo->isInstalled() && apoInfo->isEnhancementsDisabled())
|
||||
{
|
||||
disabledApoInfo = &apoInfo;
|
||||
disabledApoInfo = apoInfo.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (disabledApoInfo == NULL)
|
||||
{
|
||||
for (DeviceAPOInfo& apoInfo : inputDevices)
|
||||
for (shared_ptr<AbstractAPOInfo>& apoInfo : inputDevices)
|
||||
{
|
||||
if (apoInfo.isInstalled && apoInfo.isEnhancementsDisabled)
|
||||
if (apoInfo->isInstalled() && apoInfo->isEnhancementsDisabled())
|
||||
{
|
||||
disabledApoInfo = &apoInfo;
|
||||
disabledApoInfo = apoInfo.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -216,7 +216,7 @@ void MainWindow::doChecks()
|
||||
|
||||
if (disabledApoInfo != NULL)
|
||||
{
|
||||
if (QMessageBox::warning(this, tr("Audio enhancements disabled"), tr("Audio enhancements are not enabled for the device\n%0 %1.\nDo you want to run the Configurator application to fix the problem?").arg(QString::fromStdWString(disabledApoInfo->connectionName)).arg(QString::fromStdWString(disabledApoInfo->deviceName)), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
|
||||
if (QMessageBox::warning(this, tr("Audio enhancements disabled"), tr("Audio enhancements are not enabled for the device\n%0 %1.\nDo you want to run the Configurator application to fix the problem?").arg(QString::fromStdWString(disabledApoInfo->getConnectionName())).arg(QString::fromStdWString(disabledApoInfo->getDeviceName())), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
|
||||
{
|
||||
runConfigurator();
|
||||
return;
|
||||
@@ -402,7 +402,7 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
||||
|
||||
void MainWindow::deviceSelected(int index)
|
||||
{
|
||||
DeviceAPOInfo* apoInfo = deviceComboBox->itemData(index).value<DeviceAPOInfo*>();
|
||||
shared_ptr<AbstractAPOInfo> apoInfo = deviceComboBox->itemData(index).value<shared_ptr<AbstractAPOInfo> >();
|
||||
if (apoInfo == NULL)
|
||||
apoInfo = defaultOutputDevice;
|
||||
|
||||
@@ -415,7 +415,7 @@ void MainWindow::deviceSelected(int index)
|
||||
const GUIChannelHelper::ChannelConfigurationInfo* selectedInfo = NULL;
|
||||
for (const GUIChannelHelper::ChannelConfigurationInfo& info : infos)
|
||||
{
|
||||
if (info.channelMask == apoInfo->channelMask)
|
||||
if (info.channelMask == apoInfo->getChannelMask())
|
||||
{
|
||||
selectedInfo = &info;
|
||||
break;
|
||||
@@ -425,7 +425,7 @@ void MainWindow::deviceSelected(int index)
|
||||
if (selectedInfo != NULL)
|
||||
channelConfigurationComboBox->addItem(tr("From device") + " (" + selectedInfo->name + ")", 0);
|
||||
else
|
||||
channelConfigurationComboBox->addItem(tr("From device") + " (" + apoInfo->channelCount + " channels)", 0);
|
||||
channelConfigurationComboBox->addItem(tr("From device") + " (" + apoInfo->getChannelCount() + " channels)", 0);
|
||||
}
|
||||
|
||||
for (const GUIChannelHelper::ChannelConfigurationInfo& info : infos)
|
||||
@@ -436,7 +436,7 @@ void MainWindow::deviceSelected(int index)
|
||||
|
||||
void MainWindow::channelConfigurationSelected(int index)
|
||||
{
|
||||
DeviceAPOInfo* selectedDevice;
|
||||
shared_ptr<AbstractAPOInfo> selectedDevice;
|
||||
int channelMask;
|
||||
getDeviceAndChannelMask(&selectedDevice, &channelMask);
|
||||
|
||||
@@ -451,8 +451,8 @@ void MainWindow::channelConfigurationSelected(int index)
|
||||
|
||||
if (selectedDevice != NULL)
|
||||
{
|
||||
unsigned channelCount = selectedDevice->channelCount;
|
||||
if (channelMask != 0 && channelMask != selectedDevice->channelMask)
|
||||
unsigned channelCount = selectedDevice->getChannelCount();
|
||||
if (channelMask != 0 && channelMask != selectedDevice->getChannelMask())
|
||||
{
|
||||
channelCount = 0;
|
||||
for (int i = 0; i < 31; i++)
|
||||
@@ -816,7 +816,7 @@ FilterTable* MainWindow::addTab(QString title, QString tooltip, QString configPa
|
||||
filterTable->setAcceptDrops(true);
|
||||
filterTable->setFocusPolicy(Qt::WheelFocus);
|
||||
|
||||
DeviceAPOInfo* selectedDevice;
|
||||
shared_ptr<AbstractAPOInfo> selectedDevice;
|
||||
int channelMask;
|
||||
getDeviceAndChannelMask(&selectedDevice, &channelMask);
|
||||
filterTable->updateDeviceAndChannelMask(selectedDevice, channelMask);
|
||||
@@ -829,19 +829,19 @@ FilterTable* MainWindow::addTab(QString title, QString tooltip, QString configPa
|
||||
return filterTable;
|
||||
}
|
||||
|
||||
void MainWindow::getDeviceAndChannelMask(DeviceAPOInfo** selectedDevice, int* channelMask)
|
||||
void MainWindow::getDeviceAndChannelMask(shared_ptr<AbstractAPOInfo>* selectedDevice, int* channelMask)
|
||||
{
|
||||
*selectedDevice = deviceComboBox->currentData().value<DeviceAPOInfo*>();
|
||||
*selectedDevice = deviceComboBox->currentData().value<shared_ptr<AbstractAPOInfo> >();
|
||||
if (*selectedDevice == NULL)
|
||||
*selectedDevice = defaultOutputDevice;
|
||||
|
||||
*channelMask = channelConfigurationComboBox->currentData().toInt();
|
||||
if (*channelMask == 0 && selectedDevice != NULL)
|
||||
{
|
||||
*channelMask = (*selectedDevice)->channelMask;
|
||||
*channelMask = (*selectedDevice)->getChannelMask();
|
||||
|
||||
if (*channelMask == 0)
|
||||
*channelMask = ChannelHelper::getDefaultChannelMask((*selectedDevice)->channelCount);
|
||||
*channelMask = ChannelHelper::getDefaultChannelMask((*selectedDevice)->getChannelCount());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -894,7 +894,7 @@ bool MainWindow::askForClose(int tabIndex)
|
||||
|
||||
void MainWindow::startAnalysis()
|
||||
{
|
||||
DeviceAPOInfo* selectedDevice;
|
||||
shared_ptr<AbstractAPOInfo> selectedDevice;
|
||||
|
||||
int channelMask;
|
||||
getDeviceAndChannelMask(&selectedDevice, &channelMask);
|
||||
@@ -933,15 +933,15 @@ void MainWindow::loadPreferences()
|
||||
if (stateValue.isValid())
|
||||
restoreState(stateValue.toByteArray());
|
||||
instantModeCheckBox->setChecked(settings.value("instantMode", true).toBool());
|
||||
QString selectedDeviceGuid = settings.value("selectedDeviceGuid").toString();
|
||||
if (!selectedDeviceGuid.isEmpty())
|
||||
QString selectedDevice = settings.value("selectedDevice").toString();
|
||||
if (!selectedDevice.isEmpty())
|
||||
{
|
||||
for (int i = 0; i < deviceComboBox->count(); i++)
|
||||
{
|
||||
DeviceAPOInfo* apoInfo = deviceComboBox->itemData(i).value<DeviceAPOInfo*>();
|
||||
shared_ptr<AbstractAPOInfo> apoInfo = deviceComboBox->itemData(i).value<shared_ptr<AbstractAPOInfo> >();
|
||||
if (apoInfo != NULL)
|
||||
{
|
||||
if (QString::fromStdWString(apoInfo->deviceGuid).compare(selectedDeviceGuid, Qt::CaseInsensitive) == 0)
|
||||
if (QString::fromStdWString(apoInfo->getDeviceString()).compare(selectedDevice, Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
deviceComboBox->setCurrentIndex(i);
|
||||
break;
|
||||
@@ -1012,8 +1012,8 @@ void MainWindow::savePreferences()
|
||||
settings.setValue("geometry", saveGeometry());
|
||||
settings.setValue("windowState", saveState());
|
||||
settings.setValue("instantMode", instantModeCheckBox->isChecked());
|
||||
DeviceAPOInfo* selectedDevice = deviceComboBox->currentData().value<DeviceAPOInfo*>();
|
||||
settings.setValue("selectedDeviceGuid", selectedDevice != NULL ? QString::fromStdWString(selectedDevice->deviceGuid) : "");
|
||||
shared_ptr<AbstractAPOInfo> selectedDevice = deviceComboBox->currentData().value<shared_ptr<AbstractAPOInfo> >();
|
||||
settings.setValue("selectedDevice", selectedDevice != NULL ? QString::fromStdWString(selectedDevice->getDeviceString()) : "");
|
||||
int channelMask = channelConfigurationComboBox->currentData().toInt();
|
||||
settings.setValue("selectedChannelMask", channelMask);
|
||||
|
||||
|
||||
+5
-5
@@ -91,7 +91,7 @@ private slots:
|
||||
|
||||
private:
|
||||
FilterTable* addTab(QString title, QString tooltip, QString configPath, QList<QString> lines);
|
||||
void getDeviceAndChannelMask(DeviceAPOInfo** selectedDevice, int* channelMask);
|
||||
void getDeviceAndChannelMask(std::shared_ptr<AbstractAPOInfo>* selectedDevice, int* channelMask);
|
||||
bool askForClose(int tabIndex);
|
||||
void startAnalysis();
|
||||
void loadPreferences();
|
||||
@@ -104,9 +104,9 @@ private:
|
||||
QCheckBox* instantModeCheckBox;
|
||||
QComboBox* deviceComboBox;
|
||||
QComboBox* channelConfigurationComboBox;
|
||||
QList<DeviceAPOInfo> outputDevices;
|
||||
QList<DeviceAPOInfo> inputDevices;
|
||||
DeviceAPOInfo* defaultOutputDevice;
|
||||
QList<std::shared_ptr<AbstractAPOInfo> > outputDevices;
|
||||
QList<std::shared_ptr<AbstractAPOInfo> > inputDevices;
|
||||
std::shared_ptr<AbstractAPOInfo> defaultOutputDevice;
|
||||
AnalysisPlotScene* analysisPlotScene;
|
||||
AnalysisThread* analysisThread;
|
||||
bool restart = false;
|
||||
@@ -115,4 +115,4 @@ private:
|
||||
QStringList recentFiles;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(DeviceAPOInfo*)
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<AbstractAPOInfo>)
|
||||
@@ -22,13 +22,19 @@
|
||||
#include "ConvolutionFilterGUI.h"
|
||||
#include "ConvolutionFilterGUIFactory.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ConvolutionFilterGUIFactory::ConvolutionFilterGUIFactory()
|
||||
{
|
||||
}
|
||||
|
||||
void ConvolutionFilterGUIFactory::initialize(FilterTable* filterTable)
|
||||
{
|
||||
deviceSampleRate = filterTable->getSelectedDevice()->sampleRate;
|
||||
shared_ptr<AbstractAPOInfo> selectedDevice = filterTable->getSelectedDevice();
|
||||
if (selectedDevice != NULL)
|
||||
deviceSampleRate = filterTable->getSelectedDevice()->getSampleRate();
|
||||
else
|
||||
deviceSampleRate = 0;
|
||||
}
|
||||
|
||||
QList<FilterTemplate> ConvolutionFilterGUIFactory::createFilterTemplates()
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "DeviceFilterGUI.h"
|
||||
#include "DeviceFilterGUIDialog.h"
|
||||
#include <filters/DeviceFilterFactory.h>
|
||||
#include <VoicemeeterAPOInfo.h>
|
||||
#include "ui_DeviceFilterGUI.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -63,27 +64,39 @@ void DeviceFilterGUI::load(const QString& parameters)
|
||||
}
|
||||
else
|
||||
{
|
||||
const QList<DeviceAPOInfo>& devices = factory->getDevices();
|
||||
for (const DeviceAPOInfo& apoInfo : devices)
|
||||
const QList<shared_ptr<AbstractAPOInfo> >& devices = factory->getDevices();
|
||||
bool anyInstalled = false;
|
||||
for (const shared_ptr<AbstractAPOInfo>& apoInfo : devices)
|
||||
{
|
||||
if (!apoInfo.isInstalled)
|
||||
if (apoInfo->isInstalled() && DeviceFilterFactory::matchDevice(apoInfo->getDeviceString(), pattern.toStdWString()))
|
||||
{
|
||||
anyInstalled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const shared_ptr<AbstractAPOInfo>& apoInfo : devices)
|
||||
{
|
||||
if (anyInstalled && !apoInfo->isInstalled())
|
||||
continue;
|
||||
|
||||
wstring deviceString = apoInfo.connectionName + L" " + apoInfo.deviceName + L" " + apoInfo.deviceGuid;
|
||||
if (DeviceFilterFactory::matchDevice(deviceString, pattern.toStdWString()))
|
||||
if (DeviceFilterFactory::matchDevice(apoInfo->getDeviceString(), pattern.toStdWString()))
|
||||
{
|
||||
QStringList values;
|
||||
if (apoInfo.isInput)
|
||||
if (apoInfo->isInput())
|
||||
values.append(tr("Capture"));
|
||||
else
|
||||
values.append(tr("Playback"));
|
||||
values.append(QString::fromStdWString(apoInfo.connectionName));
|
||||
values.append(QString::fromStdWString(apoInfo.deviceName));
|
||||
values.append(QString::fromStdWString(apoInfo->getConnectionName()));
|
||||
values.append(QString::fromStdWString(apoInfo->getDeviceName()));
|
||||
QString state;
|
||||
if (apoInfo.isInstalled)
|
||||
if (apoInfo->isInstalled())
|
||||
state = tr("APO installed");
|
||||
else
|
||||
state = tr("APO not installed");
|
||||
VoicemeeterAPOInfo* voicemeeterInfo = dynamic_cast<VoicemeeterAPOInfo*>(apoInfo.get());
|
||||
if (voicemeeterInfo != NULL && !voicemeeterInfo->isVoicemeeterInstalled())
|
||||
state += ", " + tr("Voicemeeter was uninstalled");
|
||||
values.append(state);
|
||||
lastItem = new QTreeWidgetItem(ui->treeWidget, values);
|
||||
}
|
||||
@@ -93,7 +106,7 @@ void DeviceFilterGUI::load(const QString& parameters)
|
||||
{
|
||||
QStringList values;
|
||||
values.append("");
|
||||
values.append(tr("No device matched!"));
|
||||
values.append(tr("No device matched") + " \"" + pattern.trimmed() + "\"");
|
||||
values.append("");
|
||||
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeWidget, values);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ui_DeviceFilterGUIDialog.h"
|
||||
|
||||
#include <filters/DeviceFilterFactory.h>
|
||||
#include <VoicemeeterAPOInfo.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -44,26 +45,28 @@ DeviceFilterGUIDialog::DeviceFilterGUIDialog(DeviceFilterGUI* gui, DeviceFilterG
|
||||
outputNode->setExpanded(true);
|
||||
QTreeWidgetItem* inputNode = new QTreeWidgetItem(ui->treeWidget, QStringList(tr("Capture devices")));
|
||||
inputNode->setExpanded(true);
|
||||
const QList<DeviceAPOInfo>& devices = factory->getDevices();
|
||||
for (const DeviceAPOInfo& apoInfo : devices)
|
||||
const QList<shared_ptr<AbstractAPOInfo> >& devices = factory->getDevices();
|
||||
for (const shared_ptr<AbstractAPOInfo>& apoInfo : devices)
|
||||
{
|
||||
QStringList values;
|
||||
values.append(QString::fromStdWString(apoInfo.connectionName));
|
||||
values.append(QString::fromStdWString(apoInfo.deviceName));
|
||||
values.append(QString::fromStdWString(apoInfo->getConnectionName()));
|
||||
values.append(QString::fromStdWString(apoInfo->getDeviceName()));
|
||||
QString state;
|
||||
if (apoInfo.isInstalled)
|
||||
if (apoInfo->isInstalled())
|
||||
state = tr("APO installed");
|
||||
else
|
||||
state = tr("APO not installed");
|
||||
VoicemeeterAPOInfo* voicemeeterInfo = dynamic_cast<VoicemeeterAPOInfo*>(apoInfo.get());
|
||||
if (voicemeeterInfo != NULL && !voicemeeterInfo->isVoicemeeterInstalled())
|
||||
state += ", " + tr("Voicemeeter was uninstalled");
|
||||
values.append(state);
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(apoInfo.isInput ? inputNode : outputNode, values);
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(apoInfo->isInput() ? inputNode : outputNode, values);
|
||||
|
||||
wstring deviceString = apoInfo.connectionName + L" " + apoInfo.deviceName + L" " + apoInfo.deviceGuid;
|
||||
bool matches = !all && DeviceFilterFactory::matchDevice(deviceString, pattern.toStdWString());
|
||||
bool matches = !all && DeviceFilterFactory::matchDevice(apoInfo->getDeviceString(), pattern.toStdWString());
|
||||
item->setCheckState(0, matches ? Qt::Checked : Qt::Unchecked);
|
||||
item->setData(0, Qt::UserRole, QVariant::fromValue(&apoInfo));
|
||||
item->setHidden(!matches && !apoInfo.isInstalled && ui->showOnlyInstalledCheckBox->isChecked());
|
||||
if (!apoInfo.isInstalled)
|
||||
item->setData(0, Qt::UserRole, QVariant::fromValue(apoInfo));
|
||||
item->setHidden(!matches && !apoInfo->isInstalled() && ui->showOnlyInstalledCheckBox->isChecked());
|
||||
if (!apoInfo->isInstalled())
|
||||
for (int i = 0; i < ui->treeWidget->columnCount(); i++)
|
||||
item->setForeground(i, QBrush(Qt::gray));
|
||||
}
|
||||
@@ -96,9 +99,8 @@ QString DeviceFilterGUIDialog::getPattern()
|
||||
{
|
||||
if (pattern != "")
|
||||
pattern += "; ";
|
||||
const DeviceAPOInfo* apoInfo = item->data(0, Qt::UserRole).value<const DeviceAPOInfo*>();
|
||||
wstring deviceString = apoInfo->connectionName + L" " + apoInfo->deviceName + L" " + apoInfo->deviceGuid;
|
||||
pattern += QString::fromStdWString(deviceString);
|
||||
shared_ptr<AbstractAPOInfo> apoInfo = item->data(0, Qt::UserRole).value<shared_ptr<AbstractAPOInfo> >();
|
||||
pattern += QString::fromStdWString(apoInfo->getDeviceString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,8 +122,8 @@ void DeviceFilterGUIDialog::on_showOnlyInstalledCheckBox_toggled(bool checked)
|
||||
for (int j = 0; j < groupItem->childCount(); j++)
|
||||
{
|
||||
QTreeWidgetItem* item = groupItem->child(j);
|
||||
const DeviceAPOInfo* apoInfo = item->data(0, Qt::UserRole).value<const DeviceAPOInfo*>();
|
||||
item->setHidden(item->checkState(0) != Qt::Checked && !apoInfo->isInstalled && checked);
|
||||
shared_ptr<AbstractAPOInfo> apoInfo = item->data(0, Qt::UserRole).value<shared_ptr<AbstractAPOInfo> >();
|
||||
item->setHidden(item->checkState(0) != Qt::Checked && !apoInfo->isInstalled() && checked);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,4 +47,4 @@ private:
|
||||
Ui::DeviceFilterGUIDialog* ui;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(const DeviceAPOInfo*)
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<AbstractAPOInfo>)
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "DeviceFilterGUI.h"
|
||||
#include "DeviceFilterGUIFactory.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
DeviceFilterGUIFactory::DeviceFilterGUIFactory()
|
||||
{
|
||||
}
|
||||
@@ -51,7 +53,7 @@ IFilterGUI* DeviceFilterGUIFactory::createFilterGUI(QString& command, QString& p
|
||||
return result;
|
||||
}
|
||||
|
||||
const QList<DeviceAPOInfo>& DeviceFilterGUIFactory::getDevices() const
|
||||
const QList<shared_ptr<AbstractAPOInfo> >& DeviceFilterGUIFactory::getDevices() const
|
||||
{
|
||||
return devices;
|
||||
}
|
||||
@@ -34,8 +34,8 @@ public:
|
||||
QList<FilterTemplate> createFilterTemplates() override;
|
||||
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
|
||||
|
||||
const QList<DeviceAPOInfo>& getDevices() const;
|
||||
const QList<std::shared_ptr<AbstractAPOInfo> >& getDevices() const;
|
||||
|
||||
private:
|
||||
QList<DeviceAPOInfo> devices;
|
||||
QList<std::shared_ptr<AbstractAPOInfo> > devices;
|
||||
};
|
||||
Binary file not shown.
@@ -354,12 +354,12 @@ Wählen Sie eine andere Datei oder ändern Sie die Konfiguration des Geräts.</t
|
||||
<translation type="vanished">Convolution (Faltung mit Impulsantwort)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/ConvolutionFilterGUIFactory.cpp" line="37"/>
|
||||
<location filename="../guis/ConvolutionFilterGUIFactory.cpp" line="43"/>
|
||||
<source>Advanced filters</source>
|
||||
<translation>Fortgeschrittene Filter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/ConvolutionFilterGUIFactory.cpp" line="37"/>
|
||||
<location filename="../guis/ConvolutionFilterGUIFactory.cpp" line="43"/>
|
||||
<source>Convolution (Convolution with impulse response)</source>
|
||||
<translation>Convolution (Faltung mit Impulsantwort)</translation>
|
||||
</message>
|
||||
@@ -524,54 +524,63 @@ Wählen Sie eine andere Datei oder ändern Sie die Konfiguration des Geräts.</t
|
||||
<translation>Ändern...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="47"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="48"/>
|
||||
<source>Type</source>
|
||||
<translation>Typ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="48"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="49"/>
|
||||
<source>Connection</source>
|
||||
<translation>Anschluss</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="49"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="50"/>
|
||||
<source>Device</source>
|
||||
<translation>Gerät</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="50"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="51"/>
|
||||
<source>State</source>
|
||||
<translation>Status</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="59"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="60"/>
|
||||
<source>All devices</source>
|
||||
<translation>Alle Geräte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="77"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="87"/>
|
||||
<source>Capture</source>
|
||||
<translation>Aufnahme</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="79"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="89"/>
|
||||
<source>Playback</source>
|
||||
<translation>Wiedergabe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="84"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="94"/>
|
||||
<source>APO installed</source>
|
||||
<translation>APO installiert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="86"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="96"/>
|
||||
<source>APO not installed</source>
|
||||
<translation>APO nicht installiert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="96"/>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="99"/>
|
||||
<source>Voicemeeter was uninstalled</source>
|
||||
<translation>Voicemeeter wurde deinstalliert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUI.cpp" line="109"/>
|
||||
<source>No device matched</source>
|
||||
<translation>Kein Gerät passt zu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No device matched!</source>
|
||||
<translation>Kein Gerät stimmt überein!</translation>
|
||||
<translation type="vanished">Kein Gerät stimmt überein!</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -592,40 +601,45 @@ Wählen Sie eine andere Datei oder ändern Sie die Konfiguration des Geräts.</t
|
||||
<translation>Nur Geräte mit installiertem APO zeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="39"/>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="40"/>
|
||||
<source>Connection</source>
|
||||
<translation>Anschluss</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="40"/>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="41"/>
|
||||
<source>Device</source>
|
||||
<translation>Gerät</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="41"/>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="42"/>
|
||||
<source>State</source>
|
||||
<translation>Status</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="43"/>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="44"/>
|
||||
<source>Playback devices</source>
|
||||
<translation>Wiedergabegeräte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="45"/>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="46"/>
|
||||
<source>Capture devices</source>
|
||||
<translation>Aufnahmegeräte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="55"/>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="56"/>
|
||||
<source>APO installed</source>
|
||||
<translation>APO installiert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="57"/>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="58"/>
|
||||
<source>APO not installed</source>
|
||||
<translation>APO nicht installiert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIDialog.cpp" line="61"/>
|
||||
<source>Voicemeeter was uninstalled</source>
|
||||
<translation>Voicemeeter wurde deinstalliert</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DeviceFilterGUIFactory</name>
|
||||
@@ -634,12 +648,12 @@ Wählen Sie eine andere Datei oder ändern Sie die Konfiguration des Geräts.</t
|
||||
<translation type="vanished">Device (Gerät auswählen)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIFactory.cpp" line="37"/>
|
||||
<location filename="../guis/DeviceFilterGUIFactory.cpp" line="39"/>
|
||||
<source>Control</source>
|
||||
<translation>Steuerung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/DeviceFilterGUIFactory.cpp" line="37"/>
|
||||
<location filename="../guis/DeviceFilterGUIFactory.cpp" line="39"/>
|
||||
<source>Device (Select device)</source>
|
||||
<translation>Device (Gerät auswählen)</translation>
|
||||
</message>
|
||||
|
||||
Reference in new issue
Block a user