mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-02-24 10:20:06 -05:00
Denoiser feature base commit
This commit is contained in:
parent
3eae58bf4a
commit
455f8a8034
@ -152,6 +152,7 @@ option(ENABLE_FEATURE_REMOTECONTROL "Enable feature remote control plugin" ON)
|
||||
option(ENABLE_FEATURE_SKYMAP "Enable feature sky map plugin" ON)
|
||||
option(ENABLE_FEATURE_SID "Enable feature sid plugin" ON)
|
||||
option(ENABLE_FEATURE_MORSEDECODER "Enable feature morsedecoder plugin" ON)
|
||||
option(ENABLE_FEATURE_DENOISER "Enable feature denoiser plugin" ON)
|
||||
|
||||
# on windows always build external libraries
|
||||
if(WIN32)
|
||||
@ -824,6 +825,7 @@ if (NOT ENABLE_EXTERNAL_LIBRARIES OR (ENABLE_EXTERNAL_LIBRARIES STREQUAL "AUTO")
|
||||
find_package(HIDAPI)
|
||||
find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
|
||||
find_package(GGMorse)
|
||||
find_package(RNnoise)
|
||||
|
||||
# Devices
|
||||
if(ENABLE_AIRSPY)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"binaryDir": "build-default",
|
||||
"binaryDir": "build",
|
||||
"cacheVariables": {
|
||||
"DEBUG_OUTPUT": "ON",
|
||||
"AIRSPYHF_DIR": "/opt/install/libairspyhf",
|
||||
@ -29,6 +29,7 @@
|
||||
"UHD_DIR": "/opt/install/uhd",
|
||||
"XTRX_DIR": "/opt/install/xtrx-images",
|
||||
"GGMORSE_DIR": "/opt/install/ggmorse",
|
||||
"RNNOISE_DIR": "/opt/install/rnnoise",
|
||||
"CMAKE_INSTALL_PREFIX": "/opt/install/sdrangel"
|
||||
},
|
||||
"warnings": {
|
||||
|
||||
38
cmake/Modules/FindRNnoise.cmake
Normal file
38
cmake/Modules/FindRNnoise.cmake
Normal file
@ -0,0 +1,38 @@
|
||||
if (NOT RNNOISE_FOUND)
|
||||
INCLUDE(FindPkgConfig)
|
||||
PKG_CHECK_MODULES(PC_RNNoise "librnnoise")
|
||||
|
||||
FIND_PATH(RNNOISE_INCLUDE_DIR
|
||||
NAMES rnnoise.h
|
||||
HINTS ${RNNOISE_DIR}/include
|
||||
${PC_RNNOISE_INCLUDE_DIR}
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
PATHS /usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(RNNOISE_LIBRARIES
|
||||
NAMES rnnoise librnnoise
|
||||
HINTS ${RNNOISE_DIR}/lib
|
||||
${RNNOISE_DIR}/lib64
|
||||
${PC_RNNOISE_LIBDIR}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
if (RNNOISE_INCLUDE_DIR AND RNNOISE_LIBRARIES)
|
||||
set(RNNOISE_FOUND TRUE CACHE INTERNAL "RNNoise found")
|
||||
message(STATUS "Found RNNoise: ${RNNOISE_INCLUDE_DIR}, ${RNNOISE_LIBRARIES}")
|
||||
else (RNNOISE_INCLUDE_DIR AND RNNOISE_LIBRARIES)
|
||||
set(RNNOISE_FOUND FALSE CACHE INTERNAL "RNNoise found")
|
||||
message(STATUS "RNNoise not found")
|
||||
endif (RNNOISE_INCLUDE_DIR AND RNNOISE_LIBRARIES)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(RNNoise DEFAULT_MSG RNNOISE_LIBRARIES RNNOISE_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(RNNOISE_LIBRARIES RNNOISE_INCLUDE_DIR)
|
||||
endif (NOT RNNOISE_FOUND)
|
||||
@ -132,3 +132,9 @@ if (ENABLE_FEATURE_MORSEDECODER AND GGMORSE_FOUND)
|
||||
else()
|
||||
message(STATUS "Not building morsedecoder (ENABLE_FEATURE_MORSEDECODER=${ENABLE_FEATURE_MORSEDECODER} GGMODSE_FOUND=${GGMORSE_FOUND})")
|
||||
endif()
|
||||
|
||||
if (ENABLE_FEATURE_DENOISER AND RNNOISE_FOUND)
|
||||
add_subdirectory(denoiser)
|
||||
else()
|
||||
message(STATUS "Not building denoiser (ENABLE_FEATURE_DENOISER=${ENABLE_FEATURE_DENOISER} RNNOISE_FOUND=${RNNOISE_FOUND})")
|
||||
endif()
|
||||
|
||||
69
plugins/feature/denoiser/CMakeLists.txt
Normal file
69
plugins/feature/denoiser/CMakeLists.txt
Normal file
@ -0,0 +1,69 @@
|
||||
project(denoiser)
|
||||
|
||||
set(denoiser_SOURCES
|
||||
denoiser.cpp
|
||||
denoisersettings.cpp
|
||||
denoiserplugin.cpp
|
||||
denoiserworker.cpp
|
||||
denoiserwebapiadapter.cpp
|
||||
)
|
||||
|
||||
set(denoiser_HEADERS
|
||||
denoiser.h
|
||||
denoisersettings.h
|
||||
denoiserplugin.h
|
||||
denoiserworker.h
|
||||
denoiserwebapiadapter.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||
${RNNOISE_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if(NOT SERVER_MODE)
|
||||
set(denoiser_SOURCES
|
||||
${denoiser_SOURCES}
|
||||
denoisergui.cpp
|
||||
denoisergui.ui
|
||||
)
|
||||
set(denoiser_HEADERS
|
||||
${denoiser_HEADERS}
|
||||
denoisergui.h
|
||||
)
|
||||
|
||||
set(TARGET_NAME ${PLUGINS_PREFIX}featuredenoiser)
|
||||
set(TARGET_LIB "Qt::Widgets")
|
||||
set(TARGET_LIB_GUI "sdrgui")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
|
||||
else()
|
||||
set(TARGET_NAME ${PLUGINSSRV_PREFIX}featuredenoisersrv)
|
||||
set(TARGET_LIB "")
|
||||
set(TARGET_LIB_GUI "")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR})
|
||||
endif()
|
||||
|
||||
if(NOT Qt6_FOUND)
|
||||
add_library(${TARGET_NAME} ${denoiser_SOURCES})
|
||||
else()
|
||||
qt_add_plugin(${TARGET_NAME} CLASS_NAME DenoiserPlugin ${denoiser_SOURCES})
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME})
|
||||
endif()
|
||||
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE
|
||||
Qt::Core
|
||||
${TARGET_LIB}
|
||||
sdrbase
|
||||
${TARGET_LIB_GUI}
|
||||
${RNNOISE_LIBRARIES}
|
||||
)
|
||||
|
||||
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
||||
|
||||
# Install debug symbols
|
||||
if (WIN32)
|
||||
install(FILES $<TARGET_PDB_FILE:${TARGET_NAME}> CONFIGURATIONS Debug RelWithDebInfo DESTINATION ${INSTALL_FOLDER} )
|
||||
endif()
|
||||
648
plugins/feature/denoiser/denoiser.cpp
Normal file
648
plugins/feature/denoiser/denoiser.cpp
Normal file
@ -0,0 +1,648 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QDebug>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QBuffer>
|
||||
|
||||
#include "SWGFeatureSettings.h"
|
||||
#include "SWGFeatureActions.h"
|
||||
#include "SWGDeviceState.h"
|
||||
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "dsp/datafifo.h"
|
||||
#include "settings/serializable.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "maincore.h"
|
||||
|
||||
#include "denoiserworker.h"
|
||||
#include "denoiser.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(Denoiser::MsgConfigureDenoiser, Message)
|
||||
MESSAGE_CLASS_DEFINITION(Denoiser::MsgStartStop, Message)
|
||||
MESSAGE_CLASS_DEFINITION(Denoiser::MsgReportChannels, Message)
|
||||
MESSAGE_CLASS_DEFINITION(Denoiser::MsgSelectChannel, Message)
|
||||
MESSAGE_CLASS_DEFINITION(Denoiser::MsgReportSampleRate, Message)
|
||||
|
||||
const char* const Denoiser::m_featureIdURI = "sdrangel.feature.denoiser";
|
||||
const char* const Denoiser::m_featureId = "Denoiser";
|
||||
|
||||
Denoiser::Denoiser(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||
m_thread(nullptr),
|
||||
m_running(false),
|
||||
m_worker(nullptr),
|
||||
m_availableChannelOrFeatureHandler(DenoiserSettings::m_channelURIs),
|
||||
m_selectedChannel(nullptr),
|
||||
m_dataPipe(nullptr)
|
||||
{
|
||||
qDebug("Denoiser::Denoiser: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||
setObjectName(m_featureId);
|
||||
m_state = StIdle;
|
||||
m_errorMessage = "Denoiser error";
|
||||
m_networkManager = new QNetworkAccessManager();
|
||||
QObject::connect(
|
||||
m_networkManager,
|
||||
&QNetworkAccessManager::finished,
|
||||
this,
|
||||
&Denoiser::networkManagerFinished
|
||||
);
|
||||
QObject::connect(
|
||||
&m_availableChannelOrFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&Denoiser::channelsOrFeaturesChanged
|
||||
);
|
||||
m_availableChannelOrFeatureHandler.scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
Denoiser::~Denoiser()
|
||||
{
|
||||
QObject::disconnect(
|
||||
&m_availableChannelOrFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&Denoiser::channelsOrFeaturesChanged
|
||||
);
|
||||
QObject::disconnect(
|
||||
m_networkManager,
|
||||
&QNetworkAccessManager::finished,
|
||||
this,
|
||||
&Denoiser::networkManagerFinished
|
||||
);
|
||||
delete m_networkManager;
|
||||
stop();
|
||||
}
|
||||
|
||||
void Denoiser::start()
|
||||
{
|
||||
QMutexLocker m_lock(&m_mutex);
|
||||
|
||||
if (m_running) {
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug("Denoiser::start");
|
||||
m_thread = new QThread();
|
||||
m_worker = new DenoiserWorker();
|
||||
m_worker->moveToThread(m_thread);
|
||||
|
||||
QObject::connect(
|
||||
m_thread,
|
||||
&QThread::started,
|
||||
m_worker,
|
||||
&DenoiserWorker::startWork
|
||||
);
|
||||
QObject::connect(
|
||||
m_thread,
|
||||
&QThread::finished,
|
||||
m_worker,
|
||||
&QObject::deleteLater
|
||||
);
|
||||
QObject::connect(
|
||||
m_thread,
|
||||
&QThread::finished,
|
||||
m_thread,
|
||||
&QThread::deleteLater
|
||||
);
|
||||
|
||||
m_worker->setMessageQueueToFeature(getInputMessageQueue());
|
||||
m_worker->startWork();
|
||||
m_state = StRunning;
|
||||
m_thread->start();
|
||||
|
||||
DenoiserWorker::MsgConfigureDenoiserWorker *msg
|
||||
= DenoiserWorker::MsgConfigureDenoiserWorker::create(m_settings, QList<QString>(), true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
m_worker->applySampleRate(m_sampleRate);
|
||||
|
||||
if (m_dataPipe)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
DenoiserWorker::MsgConnectFifo *msg = DenoiserWorker::MsgConnectFifo::create(fifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
void Denoiser::stop()
|
||||
{
|
||||
QMutexLocker m_lock(&m_mutex);
|
||||
|
||||
if (!m_running) {
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug("Denoiser::stop");
|
||||
m_running = false;
|
||||
|
||||
if (m_dataPipe)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
DenoiserWorker::MsgConnectFifo *msg = DenoiserWorker::MsgConnectFifo::create(fifo, false);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
m_worker->stopWork();
|
||||
m_state = StIdle;
|
||||
m_thread->quit();
|
||||
m_thread->wait();
|
||||
}
|
||||
|
||||
double Denoiser::getMagSqAvg() const
|
||||
{
|
||||
return m_running ? m_worker->getMagSqAvg() : 0.0;
|
||||
}
|
||||
|
||||
bool Denoiser::handleMessage(const Message& cmd)
|
||||
{
|
||||
if (MsgConfigureDenoiser::match(cmd))
|
||||
{
|
||||
MsgConfigureDenoiser& cfg = (MsgConfigureDenoiser&) cmd;
|
||||
qDebug() << "Denoiser::handleMessage: MsgConfigureDenoiser";
|
||||
applySettings(cfg.getSettings(), cfg.getSettingsKeys(), cfg.getForce());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgStartStop::match(cmd))
|
||||
{
|
||||
MsgStartStop& cfg = (MsgStartStop&) cmd;
|
||||
qDebug() << "Denoiser::handleMessage: MsgStartStop: start:" << cfg.getStartStop();
|
||||
|
||||
if (cfg.getStartStop()) {
|
||||
start();
|
||||
} else {
|
||||
stop();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgSelectChannel::match(cmd))
|
||||
{
|
||||
MsgSelectChannel& cfg = (MsgSelectChannel&) cmd;
|
||||
ChannelAPI *selectedChannel = cfg.getChannel();
|
||||
qDebug("Denoiser::handleMessage: MsgSelectChannel: %p %s",
|
||||
selectedChannel, qPrintable(selectedChannel->objectName()));
|
||||
setChannel(selectedChannel);
|
||||
MainCore::MsgChannelDemodQuery *msg = MainCore::MsgChannelDemodQuery::create();
|
||||
selectedChannel->getInputMessageQueue()->push(msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MainCore::MsgChannelDemodReport::match(cmd))
|
||||
{
|
||||
qDebug() << "Denoiser::handleMessage: MainCore::MsgChannelDemodReport";
|
||||
MainCore::MsgChannelDemodReport& report = (MainCore::MsgChannelDemodReport&) cmd;
|
||||
|
||||
if (report.getChannelAPI() == m_selectedChannel)
|
||||
{
|
||||
m_sampleRate = report.getSampleRate();
|
||||
|
||||
if (m_running) {
|
||||
m_worker->applySampleRate(m_sampleRate);
|
||||
}
|
||||
|
||||
if (m_dataPipe)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->setSize(2*m_sampleRate);
|
||||
}
|
||||
}
|
||||
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgReportSampleRate *msg = MsgReportSampleRate::create(m_sampleRate);
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray Denoiser::serialize() const
|
||||
{
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool Denoiser::deserialize(const QByteArray& data)
|
||||
{
|
||||
if (m_settings.deserialize(data))
|
||||
{
|
||||
MsgConfigureDenoiser *msg = MsgConfigureDenoiser::create(m_settings, QList<QString>(), true);
|
||||
m_inputMessageQueue.push(msg);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
MsgConfigureDenoiser *msg = MsgConfigureDenoiser::create(m_settings, QList<QString>(), true);
|
||||
m_inputMessageQueue.push(msg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Denoiser::applySettings(const DenoiserSettings& settings, const QList<QString>& settingsKeys, bool force)
|
||||
{
|
||||
qDebug() << "Denoiser::applySettings:" << settings.getDebugString(settingsKeys, force) << " force: " << force;
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
DenoiserWorker::MsgConfigureDenoiserWorker *msg = DenoiserWorker::MsgConfigureDenoiserWorker::create(
|
||||
settings, settingsKeys, force
|
||||
);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
|
||||
if (settings.m_useReverseAPI)
|
||||
{
|
||||
bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) ||
|
||||
settingsKeys.contains("reverseAPIAddress") ||
|
||||
settingsKeys.contains("reverseAPIPort") ||
|
||||
settingsKeys.contains("reverseAPIFeatureSetIndex") ||
|
||||
settingsKeys.contains("m_reverseAPIFeatureIndex");
|
||||
webapiReverseSendSettings(settingsKeys, settings, fullUpdate || force);
|
||||
}
|
||||
|
||||
if (force) {
|
||||
m_settings = settings;
|
||||
} else {
|
||||
m_settings.applySettings(settingsKeys, settings);
|
||||
}
|
||||
}
|
||||
|
||||
void Denoiser::channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
m_availableChannels = m_availableChannelOrFeatureHandler.getAvailableChannelOrFeatureList();
|
||||
notifyUpdate(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
void Denoiser::notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgReportChannels *msg = MsgReportChannels::create(renameFrom, renameTo);
|
||||
msg->getAvailableChannels() = m_availableChannels;
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void Denoiser::getAvailableChannelsReport()
|
||||
{
|
||||
notifyUpdate(QStringList{}, QStringList{});
|
||||
}
|
||||
|
||||
|
||||
void Denoiser::setChannel(ChannelAPI *selectedChannel)
|
||||
{
|
||||
if ((selectedChannel == m_selectedChannel) || (m_availableChannels.indexOfObject(selectedChannel) == -1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
|
||||
if (m_selectedChannel)
|
||||
{
|
||||
ObjectPipe *pipe = mainCore->getDataPipes().unregisterProducerToConsumer(m_selectedChannel, this, "demod");
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(pipe->m_element);
|
||||
|
||||
if ((fifo) && m_running)
|
||||
{
|
||||
DenoiserWorker::MsgConnectFifo *msg = DenoiserWorker::MsgConnectFifo::create(fifo, false);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
ObjectPipe *messagePipe = mainCore->getMessagePipes().unregisterProducerToConsumer(m_selectedChannel, this, "reportdemod");
|
||||
|
||||
if (messagePipe)
|
||||
{
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(messagePipe->m_element);
|
||||
|
||||
if (messageQueue) {
|
||||
disconnect(messageQueue, &MessageQueue::messageEnqueued, this, nullptr); // Have to use nullptr, as slot is a lambda.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_dataPipe = mainCore->getDataPipes().registerProducerToConsumer(selectedChannel, this, "demod");
|
||||
connect(m_dataPipe, SIGNAL(toBeDeleted(int, QObject*)), this, SLOT(handleDataPipeToBeDeleted(int, QObject*)));
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
fifo->setSize(96000);
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
DenoiserWorker::MsgConnectFifo *msg = DenoiserWorker::MsgConnectFifo::create(fifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectPipe *messagePipe = mainCore->getMessagePipes().registerProducerToConsumer(selectedChannel, this, "reportdemod");
|
||||
|
||||
if (messagePipe)
|
||||
{
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(messagePipe->m_element);
|
||||
|
||||
if (messageQueue)
|
||||
{
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handleChannelMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
m_selectedChannel = selectedChannel;
|
||||
}
|
||||
|
||||
int Denoiser::webapiRun(bool run,
|
||||
SWGSDRangel::SWGDeviceState& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
getFeatureStateStr(*response.getState());
|
||||
MsgStartStop *msg = MsgStartStop::create(run);
|
||||
getInputMessageQueue()->push(msg);
|
||||
return 202;
|
||||
}
|
||||
|
||||
int Denoiser::webapiSettingsGet(
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setDenoiserSettings(new SWGSDRangel::SWGDenoiserSettings());
|
||||
response.getDenoiserSettings()->init();
|
||||
webapiFormatFeatureSettings(response, m_settings);
|
||||
return 200;
|
||||
}
|
||||
|
||||
int Denoiser::webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& featureSettingsKeys,
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
DenoiserSettings settings = m_settings;
|
||||
webapiUpdateFeatureSettings(settings, featureSettingsKeys, response);
|
||||
|
||||
MsgConfigureDenoiser *msg = MsgConfigureDenoiser::create(settings, featureSettingsKeys, force);
|
||||
m_inputMessageQueue.push(msg);
|
||||
|
||||
qDebug("Denoiser::webapiSettingsPutPatch: forward to GUI: %p", m_guiMessageQueue);
|
||||
if (m_guiMessageQueue) // forward to GUI if any
|
||||
{
|
||||
MsgConfigureDenoiser *msgToGUI = MsgConfigureDenoiser::create(settings, featureSettingsKeys, force);
|
||||
m_guiMessageQueue->push(msgToGUI);
|
||||
}
|
||||
|
||||
webapiFormatFeatureSettings(response, settings);
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
void Denoiser::webapiFormatFeatureSettings(
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
const DenoiserSettings& settings)
|
||||
{
|
||||
if (response.getDenoiserSettings()->getTitle()) {
|
||||
*response.getDenoiserSettings()->getTitle() = settings.m_title;
|
||||
} else {
|
||||
response.getDenoiserSettings()->setTitle(new QString(settings.m_title));
|
||||
}
|
||||
|
||||
response.getDenoiserSettings()->setRgbColor(settings.m_rgbColor);
|
||||
response.getDenoiserSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
|
||||
|
||||
if (response.getDenoiserSettings()->getReverseApiAddress()) {
|
||||
*response.getDenoiserSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress;
|
||||
} else {
|
||||
response.getDenoiserSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
|
||||
}
|
||||
|
||||
response.getDenoiserSettings()->setReverseApiPort(settings.m_reverseAPIPort);
|
||||
response.getDenoiserSettings()->setReverseApiFeatureSetIndex(settings.m_reverseAPIFeatureSetIndex);
|
||||
response.getDenoiserSettings()->setReverseApiFeatureIndex(settings.m_reverseAPIFeatureIndex);
|
||||
|
||||
if (response.getDenoiserSettings()->getFileRecordName()) {
|
||||
*response.getDenoiserSettings()->getFileRecordName() = settings.m_fileRecordName;
|
||||
} else {
|
||||
response.getDenoiserSettings()->setFileRecordName(new QString(settings.m_fileRecordName));
|
||||
}
|
||||
|
||||
response.getDenoiserSettings()->setRecordToFile(settings.m_recordToFile ? 1 : 0);
|
||||
|
||||
if (settings.m_rollupState)
|
||||
{
|
||||
if (response.getDenoiserSettings()->getRollupState())
|
||||
{
|
||||
settings.m_rollupState->formatTo(response.getDenoiserSettings()->getRollupState());
|
||||
}
|
||||
else
|
||||
{
|
||||
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
|
||||
settings.m_rollupState->formatTo(swgRollupState);
|
||||
response.getDenoiserSettings()->setRollupState(swgRollupState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Denoiser::webapiUpdateFeatureSettings(
|
||||
DenoiserSettings& settings,
|
||||
const QStringList& featureSettingsKeys,
|
||||
SWGSDRangel::SWGFeatureSettings& response)
|
||||
{
|
||||
if (featureSettingsKeys.contains("title")) {
|
||||
settings.m_title = *response.getDenoiserSettings()->getTitle();
|
||||
}
|
||||
if (featureSettingsKeys.contains("rgbColor")) {
|
||||
settings.m_rgbColor = response.getDenoiserSettings()->getRgbColor();
|
||||
}
|
||||
if (featureSettingsKeys.contains("useReverseAPI")) {
|
||||
settings.m_useReverseAPI = response.getDenoiserSettings()->getUseReverseApi() != 0;
|
||||
}
|
||||
if (featureSettingsKeys.contains("reverseAPIAddress")) {
|
||||
settings.m_reverseAPIAddress = *response.getDenoiserSettings()->getReverseApiAddress();
|
||||
}
|
||||
if (featureSettingsKeys.contains("reverseAPIPort")) {
|
||||
settings.m_reverseAPIPort = response.getDenoiserSettings()->getReverseApiPort();
|
||||
}
|
||||
if (featureSettingsKeys.contains("reverseAPIFeatureSetIndex")) {
|
||||
settings.m_reverseAPIFeatureSetIndex = response.getDenoiserSettings()->getReverseApiFeatureSetIndex();
|
||||
}
|
||||
if (featureSettingsKeys.contains("reverseAPIFeatureIndex")) {
|
||||
settings.m_reverseAPIFeatureIndex = response.getDenoiserSettings()->getReverseApiFeatureIndex();
|
||||
}
|
||||
if (settings.m_rollupState && featureSettingsKeys.contains("rollupState")) {
|
||||
settings.m_rollupState->updateFrom(featureSettingsKeys, response.getDenoiserSettings()->getRollupState());
|
||||
}
|
||||
if (featureSettingsKeys.contains("fileRecordName")) {
|
||||
settings.m_fileRecordName = *response.getDenoiserSettings()->getFileRecordName();
|
||||
}
|
||||
if (featureSettingsKeys.contains("recordToFile")) {
|
||||
settings.m_recordToFile = response.getDenoiserSettings()->getRecordToFile() != 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Denoiser::webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const DenoiserSettings& settings, bool force)
|
||||
{
|
||||
SWGSDRangel::SWGFeatureSettings *swgFeatureSettings = new SWGSDRangel::SWGFeatureSettings();
|
||||
// swgFeatureSettings->setOriginatorFeatureIndex(getIndexInDeviceSet());
|
||||
// swgFeatureSettings->setOriginatorFeatureSetIndex(getDeviceSetIndex());
|
||||
swgFeatureSettings->setFeatureType(new QString("Denoiser"));
|
||||
swgFeatureSettings->setDenoiserSettings(new SWGSDRangel::SWGDenoiserSettings());
|
||||
SWGSDRangel::SWGDenoiserSettings *swgDenoiserSettings = swgFeatureSettings->getDenoiserSettings();
|
||||
|
||||
// transfer data that has been modified. When force is on transfer all data except reverse API data
|
||||
|
||||
if (featureSettingsKeys.contains("title") || force) {
|
||||
swgDenoiserSettings->setTitle(new QString(settings.m_title));
|
||||
}
|
||||
if (featureSettingsKeys.contains("rgbColor") || force) {
|
||||
swgDenoiserSettings->setRgbColor(settings.m_rgbColor);
|
||||
}
|
||||
if (featureSettingsKeys.contains("fileRecordName")) {
|
||||
swgDenoiserSettings->setFileRecordName(new QString(settings.m_fileRecordName));
|
||||
}
|
||||
if (featureSettingsKeys.contains("recordToFile")) {
|
||||
swgDenoiserSettings->setRecordToFile(settings.m_recordToFile ? 1 : 0);
|
||||
}
|
||||
if (settings.m_rollupState && (featureSettingsKeys.contains("rollupState") || force)) {
|
||||
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
|
||||
settings.m_rollupState->formatTo(swgRollupState);
|
||||
swgDenoiserSettings->setRollupState(swgRollupState);
|
||||
}
|
||||
|
||||
QString channelSettingsURL = QString("http://%1:%2/sdrangel/featureset/%3/feature/%4/settings")
|
||||
.arg(settings.m_reverseAPIAddress)
|
||||
.arg(settings.m_reverseAPIPort)
|
||||
.arg(settings.m_reverseAPIFeatureSetIndex)
|
||||
.arg(settings.m_reverseAPIFeatureIndex);
|
||||
m_networkRequest.setUrl(QUrl(channelSettingsURL));
|
||||
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
QBuffer *buffer = new QBuffer();
|
||||
buffer->open((QBuffer::ReadWrite));
|
||||
buffer->write(swgFeatureSettings->asJson().toUtf8());
|
||||
buffer->seek(0);
|
||||
|
||||
// Always use PATCH to avoid passing reverse API settings
|
||||
QNetworkReply *reply = m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
|
||||
buffer->setParent(reply);
|
||||
|
||||
delete swgFeatureSettings;
|
||||
}
|
||||
|
||||
void Denoiser::networkManagerFinished(QNetworkReply *reply)
|
||||
{
|
||||
QNetworkReply::NetworkError replyError = reply->error();
|
||||
|
||||
if (replyError)
|
||||
{
|
||||
qWarning() << "Denoiser::networkManagerFinished:"
|
||||
<< " error(" << (int) replyError
|
||||
<< "): " << replyError
|
||||
<< ": " << reply->errorString();
|
||||
}
|
||||
else
|
||||
{
|
||||
QString answer = reply->readAll();
|
||||
answer.chop(1); // remove last \n
|
||||
qDebug("Denoiser::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void Denoiser::handleChannelMessageQueue(MessageQueue* messageQueue)
|
||||
{
|
||||
Message* message;
|
||||
|
||||
while ((message = messageQueue->pop()) != nullptr)
|
||||
{
|
||||
if (handleMessage(*message)) {
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Denoiser::handleDataPipeToBeDeleted(int reason, QObject *object)
|
||||
{
|
||||
qDebug("Denoiser::handleDataPipeToBeDeleted: %d %p", reason, object);
|
||||
|
||||
if ((reason == 0) && (m_selectedChannel == object))
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if ((fifo) && m_running)
|
||||
{
|
||||
DenoiserWorker::MsgConnectFifo *msg = DenoiserWorker::MsgConnectFifo::create(fifo, false);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
m_selectedChannel = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int Denoiser::webapiActionsPost(
|
||||
const QStringList&,
|
||||
SWGSDRangel::SWGFeatureActions& query,
|
||||
QString& errorMessage) {
|
||||
|
||||
MainCore* m_core = MainCore::instance();
|
||||
auto action = query.getDenoiserActions();
|
||||
if (action == nullptr) {
|
||||
errorMessage = QString("missing DenoiserActions in request");
|
||||
return 404;
|
||||
}
|
||||
|
||||
auto deviceId = action->getDeviceId();
|
||||
auto chanId = action->getChannelId();
|
||||
|
||||
ChannelAPI * chan = m_core->getChannel(deviceId, chanId);
|
||||
if (chan == nullptr) {
|
||||
errorMessage = QString("device(%1) or channel (%2) on the device does not exist").arg(deviceId).arg(chanId);
|
||||
return 404;
|
||||
}
|
||||
|
||||
MsgSelectChannel *msg = MsgSelectChannel::create(chan);
|
||||
getInputMessageQueue()->push(msg);
|
||||
return 200;
|
||||
}
|
||||
226
plugins/feature/denoiser/denoiser.h
Normal file
226
plugins/feature/denoiser/denoiser.h
Normal file
@ -0,0 +1,226 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_FEATURE_DENOISER_H_
|
||||
#define INCLUDE_FEATURE_DENOISER_H_
|
||||
|
||||
#include <QHash>
|
||||
#include <QNetworkRequest>
|
||||
#include <QRecursiveMutex>
|
||||
|
||||
#include "feature/feature.h"
|
||||
#include "util/message.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
|
||||
#include "denoisersettings.h"
|
||||
|
||||
class WebAPIAdapterInterface;
|
||||
class DenoiserWorker;
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class QThread;
|
||||
class ObjectPipe;
|
||||
|
||||
namespace SWGSDRangel {
|
||||
class SWGDeviceState;
|
||||
}
|
||||
|
||||
class Denoiser : public Feature
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
class MsgConfigureDenoiser : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const DenoiserSettings& getSettings() const { return m_settings; }
|
||||
const QList<QString>& getSettingsKeys() const { return m_settingsKeys; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureDenoiser* create(const DenoiserSettings& settings, const QList<QString>& settingsKeys, bool force) {
|
||||
return new MsgConfigureDenoiser(settings, settingsKeys, force);
|
||||
}
|
||||
|
||||
private:
|
||||
DenoiserSettings m_settings;
|
||||
QList<QString> m_settingsKeys;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureDenoiser(const DenoiserSettings& settings, const QList<QString>& settingsKeys, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_settingsKeys(settingsKeys),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgStartStop : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
bool getStartStop() const { return m_startStop; }
|
||||
|
||||
static MsgStartStop* create(bool startStop) {
|
||||
return new MsgStartStop(startStop);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool m_startStop;
|
||||
|
||||
MsgStartStop(bool startStop) :
|
||||
Message(),
|
||||
m_startStop(startStop)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgReportChannels : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
AvailableChannelOrFeatureList& getAvailableChannels() { return m_availableChannels; }
|
||||
const QStringList& getRenameFrom() const { return m_renameFrom; }
|
||||
const QStringList& getRenameTo() const { return m_renameTo; }
|
||||
|
||||
static MsgReportChannels* create(const QStringList& renameFrom, const QStringList& renameTo) {
|
||||
return new MsgReportChannels(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
private:
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
QStringList m_renameFrom;
|
||||
QStringList m_renameTo;
|
||||
|
||||
MsgReportChannels(const QStringList& renameFrom, const QStringList& renameTo) :
|
||||
Message(),
|
||||
m_renameFrom(renameFrom),
|
||||
m_renameTo(renameTo)
|
||||
{}
|
||||
};
|
||||
|
||||
class MsgSelectChannel : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
ChannelAPI *getChannel() { return m_channel; }
|
||||
static MsgSelectChannel* create(ChannelAPI *channel) {
|
||||
return new MsgSelectChannel(channel);
|
||||
}
|
||||
|
||||
protected:
|
||||
ChannelAPI *m_channel;
|
||||
|
||||
MsgSelectChannel(ChannelAPI *channel) :
|
||||
Message(),
|
||||
m_channel(channel)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgReportSampleRate : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
|
||||
static MsgReportSampleRate* create(int sampleRate) {
|
||||
return new MsgReportSampleRate(sampleRate);
|
||||
}
|
||||
|
||||
private:
|
||||
int m_sampleRate;
|
||||
|
||||
MsgReportSampleRate(int sampleRate) :
|
||||
Message(),
|
||||
m_sampleRate(sampleRate)
|
||||
{}
|
||||
};
|
||||
|
||||
Denoiser(WebAPIAdapterInterface *webAPIAdapterInterface);
|
||||
virtual ~Denoiser();
|
||||
virtual void destroy() { delete this; }
|
||||
double getMagSqAvg() const;
|
||||
virtual bool handleMessage(const Message& cmd);
|
||||
|
||||
virtual void getIdentifier(QString& id) const { id = objectName(); }
|
||||
virtual QString getIdentifier() const { return objectName(); }
|
||||
virtual void getTitle(QString& title) const { title = m_settings.m_title; }
|
||||
|
||||
virtual QByteArray serialize() const;
|
||||
virtual bool deserialize(const QByteArray& data);
|
||||
|
||||
virtual int webapiRun(bool run,
|
||||
SWGSDRangel::SWGDeviceState& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiSettingsGet(
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& featureSettingsKeys,
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiActionsPost(
|
||||
const QStringList& featureActionsKeys,
|
||||
SWGSDRangel::SWGFeatureActions& query,
|
||||
QString& errorMessage);
|
||||
|
||||
static void webapiFormatFeatureSettings(
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
const DenoiserSettings& settings);
|
||||
|
||||
static void webapiUpdateFeatureSettings(
|
||||
DenoiserSettings& settings,
|
||||
const QStringList& featureSettingsKeys,
|
||||
SWGSDRangel::SWGFeatureSettings& response);
|
||||
|
||||
void getAvailableChannelsReport();
|
||||
|
||||
static const char* const m_featureIdURI;
|
||||
static const char* const m_featureId;
|
||||
|
||||
private:
|
||||
QThread *m_thread;
|
||||
QRecursiveMutex m_mutex;
|
||||
bool m_running;
|
||||
DenoiserWorker *m_worker;
|
||||
DenoiserSettings m_settings;
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
AvailableChannelOrFeatureHandler m_availableChannelOrFeatureHandler;
|
||||
ChannelAPI *m_selectedChannel;
|
||||
ObjectPipe *m_dataPipe;
|
||||
int m_sampleRate;
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QNetworkRequest m_networkRequest;
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void applySettings(const DenoiserSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
||||
void notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void setChannel(ChannelAPI *selectedChannel);
|
||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const DenoiserSettings& settings, bool force);
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleChannelMessageQueue(MessageQueue *messageQueues);
|
||||
void channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void handleDataPipeToBeDeleted(int reason, QObject *object);
|
||||
};
|
||||
|
||||
#endif // INCLUDE_FEATURE_DENOISER_H_
|
||||
398
plugins/feature/denoiser/denoisergui.cpp
Normal file
398
plugins/feature/denoiser/denoisergui.cpp
Normal file
@ -0,0 +1,398 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "feature/featureuiset.h"
|
||||
#include "gui/basicfeaturesettingsdialog.h"
|
||||
#include "gui/dialpopup.h"
|
||||
#include "gui/dialogpositioner.h"
|
||||
#include "util/db.h"
|
||||
#include "maincore.h"
|
||||
|
||||
#include "ui_denoisergui.h"
|
||||
#include "denoiser.h"
|
||||
#include "denoisergui.h"
|
||||
|
||||
DenoiserGUI* DenoiserGUI::create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature)
|
||||
{
|
||||
DenoiserGUI* gui = new DenoiserGUI(pluginAPI, featureUISet, feature);
|
||||
return gui;
|
||||
}
|
||||
|
||||
void DenoiserGUI::destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void DenoiserGUI::resetToDefaults()
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
}
|
||||
|
||||
QByteArray DenoiserGUI::serialize() const
|
||||
{
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool DenoiserGUI::deserialize(const QByteArray& data)
|
||||
{
|
||||
if (m_settings.deserialize(data))
|
||||
{
|
||||
m_feature->setWorkspaceIndex(m_settings.m_workspaceIndex);
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DenoiserGUI::handleMessage(const Message& message)
|
||||
{
|
||||
if (Denoiser::MsgConfigureDenoiser::match(message))
|
||||
{
|
||||
qDebug("DenoiserGUI::handleMessage: Denoiser::MsgConfigureDenoiser");
|
||||
const Denoiser::MsgConfigureDenoiser& cfg = (Denoiser::MsgConfigureDenoiser&) message;
|
||||
|
||||
if (cfg.getForce()) {
|
||||
m_settings = cfg.getSettings();
|
||||
} else {
|
||||
m_settings.applySettings(cfg.getSettingsKeys(), cfg.getSettings());
|
||||
}
|
||||
|
||||
blockApplySettings(true);
|
||||
displaySettings();
|
||||
blockApplySettings(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (Denoiser::MsgReportChannels::match(message))
|
||||
{
|
||||
qDebug("DenoiserGUI::handleMessage: Denoiser::MsgReportChannels");
|
||||
Denoiser::MsgReportChannels& report = (Denoiser::MsgReportChannels&) message;
|
||||
m_availableChannels = report.getAvailableChannels();
|
||||
updateChannelList();
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (Denoiser::MsgReportSampleRate::match(message))
|
||||
{
|
||||
Denoiser::MsgReportSampleRate& report = (Denoiser::MsgReportSampleRate&) message;
|
||||
int sampleRate = report.getSampleRate();
|
||||
qDebug("DenoiserGUI::handleMessage: Denoiser::MsgReportSampleRate: %d", sampleRate);
|
||||
displaySampleRate(sampleRate);
|
||||
m_sampleRate = sampleRate;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DenoiserGUI::handleInputMessages()
|
||||
{
|
||||
Message* message;
|
||||
|
||||
while ((message = getInputMessageQueue()->pop()))
|
||||
{
|
||||
if (handleMessage(*message)) {
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
||||
{
|
||||
(void) widget;
|
||||
(void) rollDown;
|
||||
|
||||
RollupContents *rollupContents = getRollupContents();
|
||||
|
||||
rollupContents->saveState(m_rollupState);
|
||||
applySettings();
|
||||
}
|
||||
|
||||
DenoiserGUI::DenoiserGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) :
|
||||
FeatureGUI(parent),
|
||||
ui(new Ui::DenoiserGUI),
|
||||
m_pluginAPI(pluginAPI),
|
||||
m_featureUISet(featureUISet),
|
||||
m_sampleRate(48000),
|
||||
m_doApplySettings(true),
|
||||
m_lastFeatureState(0),
|
||||
m_selectedChannel(nullptr)
|
||||
{
|
||||
m_feature = feature;
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
m_helpURL = "plugins/feature/denoiser/readme.md";
|
||||
RollupContents *rollupContents = getRollupContents();
|
||||
ui->setupUi(rollupContents);
|
||||
rollupContents->arrangeRollups();
|
||||
connect(rollupContents, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
|
||||
|
||||
m_denoiser = reinterpret_cast<Denoiser*>(feature);
|
||||
m_denoiser->setMessageQueueToGUI(&m_inputMessageQueue);
|
||||
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
|
||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
|
||||
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
|
||||
m_statusTimer.start(1000);
|
||||
|
||||
displaySampleRate(m_sampleRate);
|
||||
|
||||
connect(&MainCore::instance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
|
||||
|
||||
m_settings.setRollupState(&m_rollupState);
|
||||
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
makeUIConnections();
|
||||
DialPopup::addPopupsToChildDials(this);
|
||||
m_resizer.enableChildMouseTracking();
|
||||
m_denoiser->getAvailableChannelsReport();
|
||||
}
|
||||
|
||||
DenoiserGUI::~DenoiserGUI()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DenoiserGUI::blockApplySettings(bool block)
|
||||
{
|
||||
m_doApplySettings = !block;
|
||||
}
|
||||
|
||||
void DenoiserGUI::setWorkspaceIndex(int index)
|
||||
{
|
||||
m_settings.m_workspaceIndex = index;
|
||||
m_feature->setWorkspaceIndex(index);
|
||||
}
|
||||
|
||||
void DenoiserGUI::displaySettings()
|
||||
{
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
setWindowTitle(m_settings.m_title);
|
||||
setTitle(m_settings.m_title);
|
||||
blockApplySettings(true);
|
||||
ui->record->setChecked(m_settings.m_recordToFile);
|
||||
ui->fileNameText->setText(m_settings.m_fileRecordName);
|
||||
ui->showFileDialog->setEnabled(!m_settings.m_recordToFile);
|
||||
getRollupContents()->restoreState(m_rollupState);
|
||||
blockApplySettings(false);
|
||||
}
|
||||
|
||||
void DenoiserGUI::displaySampleRate(int sampleRate)
|
||||
{
|
||||
QString s = QString::number(sampleRate/1000.0, 'f', 1);
|
||||
ui->sinkSampleRateText->setText(tr("%1 kS/s").arg(s));
|
||||
}
|
||||
|
||||
void DenoiserGUI::updateChannelList()
|
||||
{
|
||||
ui->channels->blockSignals(true);
|
||||
ui->channels->clear();
|
||||
|
||||
AvailableChannelOrFeatureList::const_iterator it = m_availableChannels.begin();
|
||||
int selectedItem = -1;
|
||||
|
||||
for (int i = 0; it != m_availableChannels.end(); ++it, i++)
|
||||
{
|
||||
ui->channels->addItem(it->getLongId());
|
||||
|
||||
if (it->m_object == m_selectedChannel) {
|
||||
selectedItem = i;
|
||||
}
|
||||
}
|
||||
|
||||
ui->channels->blockSignals(false);
|
||||
|
||||
if (m_availableChannels.size() > 0)
|
||||
{
|
||||
if (selectedItem >= 0) {
|
||||
ui->channels->setCurrentIndex(selectedItem);
|
||||
} else {
|
||||
ui->channels->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserGUI::onMenuDialogCalled(const QPoint &p)
|
||||
{
|
||||
if (m_contextMenuType == ContextMenuType::ContextMenuChannelSettings)
|
||||
{
|
||||
BasicFeatureSettingsDialog dialog(this);
|
||||
dialog.setTitle(m_settings.m_title);
|
||||
dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
|
||||
dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
|
||||
dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
|
||||
dialog.setReverseAPIFeatureSetIndex(m_settings.m_reverseAPIFeatureSetIndex);
|
||||
dialog.setReverseAPIFeatureIndex(m_settings.m_reverseAPIFeatureIndex);
|
||||
dialog.setDefaultTitle(m_displayedName);
|
||||
|
||||
dialog.move(p);
|
||||
new DialogPositioner(&dialog, false);
|
||||
dialog.exec();
|
||||
|
||||
m_settings.m_title = dialog.getTitle();
|
||||
m_settings.m_useReverseAPI = dialog.useReverseAPI();
|
||||
m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
|
||||
m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
|
||||
m_settings.m_reverseAPIFeatureSetIndex = dialog.getReverseAPIFeatureSetIndex();
|
||||
m_settings.m_reverseAPIFeatureIndex = dialog.getReverseAPIFeatureIndex();
|
||||
|
||||
setTitle(m_settings.m_title);
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
|
||||
m_settingsKeys.append("title");
|
||||
m_settingsKeys.append("rgbColor");
|
||||
m_settingsKeys.append("useReverseAPI");
|
||||
m_settingsKeys.append("reverseAPIAddress");
|
||||
m_settingsKeys.append("reverseAPIPort");
|
||||
m_settingsKeys.append("reverseAPIFeatureSetIndex");
|
||||
m_settingsKeys.append("reverseAPIFeatureIndex");
|
||||
|
||||
applySettings();
|
||||
}
|
||||
|
||||
resetContextMenuType();
|
||||
}
|
||||
|
||||
void DenoiserGUI::on_startStop_toggled(bool checked)
|
||||
{
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
Denoiser::MsgStartStop *message = Denoiser::MsgStartStop::create(checked);
|
||||
m_denoiser->getInputMessageQueue()->push(message);
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserGUI::on_channels_currentIndexChanged(int index)
|
||||
{
|
||||
if ((index >= 0) && (index < m_availableChannels.size()))
|
||||
{
|
||||
m_selectedChannel = qobject_cast<ChannelAPI*>(m_availableChannels[index].m_object);
|
||||
Denoiser::MsgSelectChannel *msg = Denoiser::MsgSelectChannel::create(m_selectedChannel);
|
||||
m_denoiser->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserGUI::on_channelApply_clicked()
|
||||
{
|
||||
if (ui->channels->count() > 0) {
|
||||
on_channels_currentIndexChanged(ui->channels->currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserGUI::on_record_toggled(bool checked)
|
||||
{
|
||||
ui->showFileDialog->setEnabled(!checked);
|
||||
m_settings.m_recordToFile = checked;
|
||||
m_settingsKeys.append("recordToFile");
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DenoiserGUI::on_showFileDialog_clicked(bool checked)
|
||||
{
|
||||
(void) checked;
|
||||
QFileDialog fileDialog(
|
||||
this,
|
||||
tr("Save record file"),
|
||||
m_settings.m_fileRecordName,
|
||||
tr("WAV Files (*.wav)")
|
||||
);
|
||||
|
||||
fileDialog.setOptions(QFileDialog::DontUseNativeDialog);
|
||||
fileDialog.setFileMode(QFileDialog::AnyFile);
|
||||
QStringList fileNames;
|
||||
|
||||
if (fileDialog.exec())
|
||||
{
|
||||
fileNames = fileDialog.selectedFiles();
|
||||
|
||||
if (fileNames.size() > 0)
|
||||
{
|
||||
m_settings.m_fileRecordName = fileNames.at(0);
|
||||
ui->fileNameText->setText(m_settings.m_fileRecordName);
|
||||
m_settingsKeys.append("fileRecordName");
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserGUI::tick()
|
||||
{
|
||||
m_channelPowerAvg(m_denoiser->getMagSqAvg());
|
||||
double powDb = CalcDb::dbPower((double) m_channelPowerAvg);
|
||||
ui->channelPower->setText(tr("%1 dB").arg(powDb, 0, 'f', 1));
|
||||
}
|
||||
|
||||
void DenoiserGUI::updateStatus()
|
||||
{
|
||||
int state = m_denoiser->getState();
|
||||
|
||||
if (m_lastFeatureState != state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case Feature::StNotStarted:
|
||||
ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
|
||||
break;
|
||||
case Feature::StIdle:
|
||||
ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
|
||||
break;
|
||||
case Feature::StRunning:
|
||||
ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
|
||||
break;
|
||||
case Feature::StError:
|
||||
ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
|
||||
QMessageBox::information(this, tr("Message"), m_denoiser->getErrorMessage());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_lastFeatureState = state;
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserGUI::applySettings(bool force)
|
||||
{
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
Denoiser::MsgConfigureDenoiser* message = Denoiser::MsgConfigureDenoiser::create( m_settings, m_settingsKeys, force);
|
||||
m_denoiser->getInputMessageQueue()->push(message);
|
||||
}
|
||||
|
||||
m_settingsKeys.clear();
|
||||
}
|
||||
|
||||
void DenoiserGUI::makeUIConnections()
|
||||
{
|
||||
QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &DenoiserGUI::on_startStop_toggled);
|
||||
QObject::connect(ui->channels, qOverload<int>(&QComboBox::currentIndexChanged), this, &DenoiserGUI::on_channels_currentIndexChanged);
|
||||
QObject::connect(ui->channelApply, &QPushButton::clicked, this, &DenoiserGUI::on_channelApply_clicked);
|
||||
QObject::connect(ui->record, &ButtonSwitch::toggled, this, &DenoiserGUI::on_record_toggled);
|
||||
QObject::connect(ui->showFileDialog, &QPushButton::clicked, this, &DenoiserGUI::on_showFileDialog_clicked);
|
||||
}
|
||||
99
plugins/feature/denoiser/denoisergui.h
Normal file
99
plugins/feature/denoiser/denoisergui.h
Normal file
@ -0,0 +1,99 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_FEATURE_DENOISERGUI_H_
|
||||
#define INCLUDE_FEATURE_DENOISERGUI_H_
|
||||
|
||||
#include <QTimer>
|
||||
#include <QList>
|
||||
|
||||
#include "feature/featuregui.h"
|
||||
#include "util/movingaverage.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
#include "settings/rollupstate.h"
|
||||
|
||||
#include "denoisersettings.h"
|
||||
|
||||
class PluginAPI;
|
||||
class FeatureUISet;
|
||||
class Denoiser;
|
||||
class Feature;
|
||||
|
||||
namespace Ui {
|
||||
class DenoiserGUI;
|
||||
}
|
||||
|
||||
class DenoiserGUI : public FeatureGUI {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static DenoiserGUI* create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature);
|
||||
virtual void destroy();
|
||||
|
||||
void resetToDefaults();
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||
virtual void setWorkspaceIndex(int index);
|
||||
virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
|
||||
virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
|
||||
virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
|
||||
|
||||
private:
|
||||
Ui::DenoiserGUI* ui;
|
||||
PluginAPI* m_pluginAPI;
|
||||
FeatureUISet* m_featureUISet;
|
||||
DenoiserSettings m_settings;
|
||||
QList<QString> m_settingsKeys;
|
||||
RollupState m_rollupState;
|
||||
int m_sampleRate;
|
||||
bool m_doApplySettings;
|
||||
|
||||
Denoiser* m_denoiser;
|
||||
MessageQueue m_inputMessageQueue;
|
||||
QTimer m_statusTimer;
|
||||
int m_lastFeatureState;
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
ChannelAPI *m_selectedChannel;
|
||||
MovingAverageUtil<double, double, 40> m_channelPowerAvg;
|
||||
|
||||
explicit DenoiserGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
|
||||
virtual ~DenoiserGUI();
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings(bool force = false);
|
||||
void displaySettings();
|
||||
void displaySampleRate(int sampleRate);
|
||||
void updateChannelList();
|
||||
bool handleMessage(const Message& message);
|
||||
void makeUIConnections();
|
||||
|
||||
private slots:
|
||||
void onMenuDialogCalled(const QPoint &p);
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void handleInputMessages();
|
||||
void on_startStop_toggled(bool checked);
|
||||
void on_channels_currentIndexChanged(int index);
|
||||
void on_channelApply_clicked();
|
||||
void on_record_toggled(bool checked);
|
||||
void on_showFileDialog_clicked(bool checked);
|
||||
void updateStatus();
|
||||
void tick();
|
||||
};
|
||||
|
||||
|
||||
#endif // INCLUDE_FEATURE_DENOISERGUI_H_
|
||||
419
plugins/feature/denoiser/denoisergui.ui
Normal file
419
plugins/feature/denoiser/denoisergui.ui
Normal file
@ -0,0 +1,419 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DenoiserGUI</class>
|
||||
<widget class="RollupContents" name="DenoiserGUI">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>452</width>
|
||||
<height>200</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>452</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Sans</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Denoiser</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="settingsContainer" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>2</y>
|
||||
<width>450</width>
|
||||
<height>151</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>450</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="HeaderLayout">
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="startStop">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>start/stop acquisition</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/play.png</normaloff>
|
||||
<normalon>:/stop.png</normalon>:/play.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="channelsLabel">
|
||||
<property name="text">
|
||||
<string>Chan</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="channels">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel index</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="channelApply">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>(Re) apply channel selection</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/checkmark.png</normaloff>:/checkmark.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sinkSampleRateText">
|
||||
<property name="toolTip">
|
||||
<string>Analyzer (sink) sample rate</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>00000.0 kS/s</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="channelPower">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>52</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel power</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-100.0 dB</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="denoiserLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox">
|
||||
<property name="toolTip">
|
||||
<string>Noise reduction scheme</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>RNnoise</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="audioMute">
|
||||
<property name="toolTip">
|
||||
<string>Left: Mute/Unmute audio Right: view/select audio device</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/sound_on.png</normaloff>
|
||||
<normalon>:/sound_off.png</normalon>:/sound_on.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="volumeLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="volLabel">
|
||||
<property name="text">
|
||||
<string>Vol</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDial" name="volume">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Audio input gain</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="volumeText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Audio input gain value</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1.0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LevelMeterVU" name="volumeMeter" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Mono</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Level (% full range) top trace: average, bottom trace: instantaneous peak, tip: peak hold</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="fileNameLayout">
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="record">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Start/stop recording</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/record_off.png</normaloff>:/record_off.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="showFileDialog">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Open file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/preset-load.png</normaloff>:/preset-load.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="fileNameText">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Current recording file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ButtonSwitch</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>gui/buttonswitch.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>RollupContents</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/rollupcontents.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LevelMeterVU</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/levelmeter.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../sdrgui/resources/res.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
78
plugins/feature/denoiser/denoiserplugin.cpp
Normal file
78
plugins/feature/denoiser/denoiserplugin.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QtPlugin>
|
||||
#include "plugin/pluginapi.h"
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
#include "denoisergui.h"
|
||||
#endif
|
||||
#include "denoiser.h"
|
||||
#include "denoiserplugin.h"
|
||||
#include "denoiserwebapiadapter.h"
|
||||
const PluginDescriptor DenoiserPlugin::m_pluginDescriptor = {
|
||||
Denoiser::m_featureId,
|
||||
QStringLiteral("Denoiser"),
|
||||
QStringLiteral("7.23.0"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel")
|
||||
};
|
||||
|
||||
DenoiserPlugin::DenoiserPlugin(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_pluginAPI(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
const PluginDescriptor& DenoiserPlugin::getPluginDescriptor() const
|
||||
{
|
||||
return m_pluginDescriptor;
|
||||
}
|
||||
|
||||
void DenoiserPlugin::initPlugin(PluginAPI* pluginAPI)
|
||||
{
|
||||
m_pluginAPI = pluginAPI;
|
||||
|
||||
// register RigCtl Server feature
|
||||
m_pluginAPI->registerFeature(Denoiser::m_featureIdURI, Denoiser::m_featureId, this);
|
||||
}
|
||||
|
||||
#ifdef SERVER_MODE
|
||||
FeatureGUI* DenoiserPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const
|
||||
{
|
||||
(void) featureUISet;
|
||||
(void) feature;
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
FeatureGUI* DenoiserPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const
|
||||
{
|
||||
return DenoiserGUI::create(m_pluginAPI, featureUISet, feature);
|
||||
}
|
||||
#endif
|
||||
|
||||
Feature* DenoiserPlugin::createFeature(WebAPIAdapterInterface* webAPIAdapterInterface) const
|
||||
{
|
||||
return new Denoiser(webAPIAdapterInterface);
|
||||
}
|
||||
|
||||
FeatureWebAPIAdapter* DenoiserPlugin::createFeatureWebAPIAdapter() const
|
||||
{
|
||||
return new DenoiserWebAPIAdapter();
|
||||
}
|
||||
48
plugins/feature/denoiser/denoiserplugin.h
Normal file
48
plugins/feature/denoiser/denoiserplugin.h
Normal file
@ -0,0 +1,48 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_FEATURE_DENOISERPLUGIN_H
|
||||
#define INCLUDE_FEATURE_DENOISERPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include "plugin/plugininterface.h"
|
||||
|
||||
class FeatureGUI;
|
||||
class WebAPIAdapterInterface;
|
||||
|
||||
class DenoiserPlugin : public QObject, PluginInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(PluginInterface)
|
||||
Q_PLUGIN_METADATA(IID "sdrangel.feature.denoiser")
|
||||
|
||||
public:
|
||||
explicit DenoiserPlugin(QObject* parent = nullptr);
|
||||
|
||||
const PluginDescriptor& getPluginDescriptor() const;
|
||||
void initPlugin(PluginAPI* pluginAPI);
|
||||
|
||||
virtual FeatureGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const;
|
||||
virtual Feature* createFeature(WebAPIAdapterInterface *webAPIAdapterInterface) const;
|
||||
virtual FeatureWebAPIAdapter* createFeatureWebAPIAdapter() const;
|
||||
|
||||
private:
|
||||
static const PluginDescriptor m_pluginDescriptor;
|
||||
|
||||
PluginAPI* m_pluginAPI;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_FEATURE_DENOISERPLUGIN_H
|
||||
220
plugins/feature/denoiser/denoisersettings.cpp
Normal file
220
plugins/feature/denoiser/denoisersettings.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "util/simpleserializer.h"
|
||||
#include "settings/serializable.h"
|
||||
|
||||
#include "denoisersettings.h"
|
||||
|
||||
const QStringList DenoiserSettings::m_channelURIs = {
|
||||
QStringLiteral("sdrangel.channel.amdemod"),
|
||||
QStringLiteral("sdrangel.channel.bfm"),
|
||||
QStringLiteral("sdrangel.channel.dabdemod"),
|
||||
QStringLiteral("sdrangel.channel.dsddemod"),
|
||||
QStringLiteral("sdrangel.channel.m17demod"),
|
||||
QStringLiteral("sdrangel.channel.nfmdemod"),
|
||||
QStringLiteral("sdrangel.channel.ssbdemod"),
|
||||
QStringLiteral("sdrangel.channel.wfmdemod"),
|
||||
QStringLiteral("sdrangel.channel.wdsprx"),
|
||||
};
|
||||
|
||||
DenoiserSettings::DenoiserSettings() :
|
||||
m_rollupState(nullptr)
|
||||
{
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
void DenoiserSettings::resetToDefaults()
|
||||
{
|
||||
m_denoiserType = DenoiserType::DenoiserType_RNnoise;
|
||||
m_title = "Denoiser";
|
||||
m_audioMute = false;
|
||||
m_rgbColor = 0xffd700; // gold
|
||||
m_useReverseAPI = false;
|
||||
m_reverseAPIAddress = "localhost";
|
||||
m_reverseAPIPort = 8888;
|
||||
m_reverseAPIFeatureSetIndex = 0;
|
||||
m_reverseAPIFeatureIndex = 0;
|
||||
m_fileRecordName = "denoiser_record.wav";
|
||||
m_recordToFile = false;
|
||||
m_workspaceIndex = -1;
|
||||
m_geometryBytes.clear();
|
||||
}
|
||||
|
||||
QByteArray DenoiserSettings::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
|
||||
s.writeS32(1, static_cast<qint32>(m_denoiserType));
|
||||
s.writeBool(14, m_audioMute);
|
||||
s.writeString(2, m_title);
|
||||
s.writeU32(3, m_rgbColor);
|
||||
s.writeBool(4, m_useReverseAPI);
|
||||
s.writeString(5, m_reverseAPIAddress);
|
||||
s.writeU32(6, m_reverseAPIPort);
|
||||
s.writeU32(7, m_reverseAPIFeatureSetIndex);
|
||||
s.writeU32(8, m_reverseAPIFeatureIndex);
|
||||
s.writeString(9, m_fileRecordName);
|
||||
s.writeBool(10, m_recordToFile);
|
||||
s.writeS32(11, m_workspaceIndex);
|
||||
s.writeBlob(12, m_geometryBytes);
|
||||
|
||||
if (m_rollupState) {
|
||||
s.writeBlob(13, m_rollupState->serialize());
|
||||
}
|
||||
|
||||
return s.final();
|
||||
}
|
||||
|
||||
bool DenoiserSettings::deserialize(const QByteArray& data)
|
||||
{
|
||||
SimpleDeserializer d(data);
|
||||
|
||||
if (!d.isValid())
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d.getVersion() == 1)
|
||||
{
|
||||
qint32 itmp;
|
||||
QByteArray bytetmp;
|
||||
uint32_t utmp;
|
||||
|
||||
d.readS32(1, &itmp, 1);
|
||||
m_denoiserType = static_cast<DenoiserType>(itmp);
|
||||
d.readBool(14, &m_audioMute, false);
|
||||
d.readString(2, &m_title, "Denoiser");
|
||||
d.readU32(3, &m_rgbColor, 0xffd700); // gold
|
||||
d.readBool(4, &m_useReverseAPI, false);
|
||||
d.readString(5, &m_reverseAPIAddress, "localhost");
|
||||
d.readU32(6, &utmp, 8888);
|
||||
|
||||
if ((utmp > 1023) && (utmp < 65535)) {
|
||||
m_reverseAPIPort = utmp;
|
||||
} else {
|
||||
m_reverseAPIPort = 8888;
|
||||
}
|
||||
|
||||
d.readU32(7, &utmp, 0);
|
||||
m_reverseAPIFeatureSetIndex = utmp > 99 ? 99 : utmp;
|
||||
d.readU32(8, &utmp, 0);
|
||||
m_reverseAPIFeatureIndex = utmp > 99 ? 99 : utmp;
|
||||
d.readString(9, &m_fileRecordName, "denoiser_record.wav");
|
||||
d.readBool(10, &m_recordToFile, false);
|
||||
d.readS32(11, &m_workspaceIndex, -1);
|
||||
d.readBlob(12, &m_geometryBytes);
|
||||
|
||||
if (m_rollupState)
|
||||
{
|
||||
d.readBlob(13, &bytetmp);
|
||||
m_rollupState->deserialize(bytetmp);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserSettings::applySettings(const QStringList& settingsKeys, const DenoiserSettings& settings)
|
||||
{
|
||||
if (settingsKeys.contains("denoiserType")) {
|
||||
m_denoiserType = settings.m_denoiserType;
|
||||
}
|
||||
if (settingsKeys.contains("audioMute")) {
|
||||
m_audioMute = settings.m_audioMute;
|
||||
}
|
||||
if (settingsKeys.contains("title")) {
|
||||
m_title = settings.m_title;
|
||||
}
|
||||
if (settingsKeys.contains("rgbColor")) {
|
||||
m_rgbColor = settings.m_rgbColor;
|
||||
}
|
||||
if (settingsKeys.contains("useReverseAPI")) {
|
||||
m_useReverseAPI = settings.m_useReverseAPI;
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIAddress")) {
|
||||
m_reverseAPIAddress = settings.m_reverseAPIAddress;
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIPort")) {
|
||||
m_reverseAPIPort = settings.m_reverseAPIPort;
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIFeatureSetIndex")) {
|
||||
m_reverseAPIFeatureSetIndex = settings.m_reverseAPIFeatureSetIndex;
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIFeatureIndex")) {
|
||||
m_reverseAPIFeatureIndex = settings.m_reverseAPIFeatureIndex;
|
||||
}
|
||||
if (settingsKeys.contains("workspaceIndex")) {
|
||||
m_workspaceIndex = settings.m_workspaceIndex;
|
||||
}
|
||||
if (settingsKeys.contains("fileRecordName")) {
|
||||
m_fileRecordName = settings.m_fileRecordName;
|
||||
}
|
||||
if (settingsKeys.contains("recordToFile")) {
|
||||
m_recordToFile = settings.m_recordToFile;
|
||||
}
|
||||
}
|
||||
|
||||
QString DenoiserSettings::getDebugString(const QStringList& settingsKeys, bool force) const
|
||||
{
|
||||
QString debugString;
|
||||
|
||||
if (settingsKeys.contains("denoiserType") || force) {
|
||||
debugString += QString("DenoiserType: %1 ").arg(static_cast<qint32>(m_denoiserType));
|
||||
}
|
||||
if (settingsKeys.contains("audioMute") || force) {
|
||||
debugString += QString("Audio Mute: %1 ").arg(m_audioMute ? "true" : "false");
|
||||
}
|
||||
if (settingsKeys.contains("title") || force) {
|
||||
debugString += QString("Title: %1 ").arg(m_title);
|
||||
}
|
||||
if (settingsKeys.contains("rgbColor") || force) {
|
||||
debugString += QString("RGB Color: 0x%1 ").arg(QString::number(m_rgbColor, 16).rightJustified(6, '0'));
|
||||
}
|
||||
if (settingsKeys.contains("useReverseAPI") || force) {
|
||||
debugString += QString("Use Reverse API: %1 ").arg(m_useReverseAPI ? "true" : "false");
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIAddress") || force) {
|
||||
debugString += QString("Reverse API Address: %1 ").arg(m_reverseAPIAddress);
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIPort") || force) {
|
||||
debugString += QString("Reverse API Port: %1 ").arg(m_reverseAPIPort);
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIFeatureSetIndex") || force) {
|
||||
debugString += QString("Reverse API Feature Set Index: %1 ").arg(m_reverseAPIFeatureSetIndex);
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIFeatureIndex") || force) {
|
||||
debugString += QString("Reverse API Feature Index: %1 ").arg(m_reverseAPIFeatureIndex);
|
||||
}
|
||||
if (settingsKeys.contains("workspaceIndex") || force) {
|
||||
debugString += QString("Workspace Index: %1 ").arg(m_workspaceIndex);
|
||||
}
|
||||
if (settingsKeys.contains("fileRecordName") || force) {
|
||||
debugString += QString("File Record Name: %1 ").arg(m_fileRecordName);
|
||||
}
|
||||
if (settingsKeys.contains("recordToFile") || force) {
|
||||
debugString += QString("Record To File: %1 ").arg(m_recordToFile ? "true" : "false");
|
||||
}
|
||||
|
||||
return debugString;
|
||||
}
|
||||
62
plugins/feature/denoiser/denoisersettings.h
Normal file
62
plugins/feature/denoiser/denoisersettings.h
Normal file
@ -0,0 +1,62 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDE_FEATURE_DENOISER_DENOISERSETTINGS_H_
|
||||
#define INCLUDE_FEATURE_DENOISER_DENOISERSETTINGS_H_
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
class Serializable;
|
||||
|
||||
struct DenoiserSettings
|
||||
{
|
||||
enum class DenoiserType
|
||||
{
|
||||
DenoiserType_None = 0,
|
||||
DenoiserType_RNnoise = 1,
|
||||
};
|
||||
|
||||
DenoiserType m_denoiserType;
|
||||
bool m_audioMute;
|
||||
QString m_title;
|
||||
quint32 m_rgbColor;
|
||||
bool m_useReverseAPI;
|
||||
QString m_reverseAPIAddress;
|
||||
uint16_t m_reverseAPIPort;
|
||||
uint16_t m_reverseAPIFeatureSetIndex;
|
||||
uint16_t m_reverseAPIFeatureIndex;
|
||||
QString m_fileRecordName;
|
||||
bool m_recordToFile;
|
||||
Serializable *m_rollupState;
|
||||
int m_workspaceIndex;
|
||||
QByteArray m_geometryBytes;
|
||||
|
||||
DenoiserSettings();
|
||||
~DenoiserSettings() = default;
|
||||
void resetToDefaults();
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
||||
void applySettings(const QStringList& settingsKeys, const DenoiserSettings& settings);
|
||||
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
|
||||
|
||||
static const QStringList m_channelURIs;
|
||||
};
|
||||
|
||||
|
||||
#endif // INCLUDE_FEATURE_DENOISER_DENOISERSETTINGS_H_
|
||||
51
plugins/feature/denoiser/denoiserwebapiadapter.cpp
Normal file
51
plugins/feature/denoiser/denoiserwebapiadapter.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SWGFeatureSettings.h"
|
||||
#include "denoiser.h"
|
||||
#include "denoiserwebapiadapter.h"
|
||||
|
||||
DenoiserWebAPIAdapter::DenoiserWebAPIAdapter()
|
||||
{}
|
||||
|
||||
DenoiserWebAPIAdapter::~DenoiserWebAPIAdapter()
|
||||
{}
|
||||
|
||||
int DenoiserWebAPIAdapter::webapiSettingsGet(
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setDenoiserSettings(new SWGSDRangel::SWGDenoiserSettings());
|
||||
response.getDenoiserSettings()->init();
|
||||
Denoiser::webapiFormatFeatureSettings(response, m_settings);
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
int DenoiserWebAPIAdapter::webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& featureSettingsKeys,
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) force; // no action
|
||||
(void) errorMessage;
|
||||
Denoiser::webapiUpdateFeatureSettings(m_settings, featureSettingsKeys, response);
|
||||
|
||||
return 200;
|
||||
}
|
||||
49
plugins/feature/denoiser/denoiserwebapiadapter.h
Normal file
49
plugins/feature/denoiser/denoiserwebapiadapter.h
Normal file
@ -0,0 +1,49 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_DENOISER_WEBAPIADAPTER_H
|
||||
#define INCLUDE_DENOISER_WEBAPIADAPTER_H
|
||||
|
||||
#include "feature/featurewebapiadapter.h"
|
||||
#include "denoisersettings.h"
|
||||
|
||||
/**
|
||||
* Standalone API adapter only for the settings
|
||||
*/
|
||||
class DenoiserWebAPIAdapter : public FeatureWebAPIAdapter {
|
||||
public:
|
||||
DenoiserWebAPIAdapter();
|
||||
virtual ~DenoiserWebAPIAdapter();
|
||||
|
||||
virtual QByteArray serialize() const { return m_settings.serialize(); }
|
||||
virtual bool deserialize(const QByteArray& data) { return m_settings.deserialize(data); }
|
||||
|
||||
virtual int webapiSettingsGet(
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& featureSettingsKeys,
|
||||
SWGSDRangel::SWGFeatureSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
private:
|
||||
DenoiserSettings m_settings;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_DENOISER_WEBAPIADAPTER_H
|
||||
245
plugins/feature/denoiser/denoiserworker.cpp
Normal file
245
plugins/feature/denoiser/denoiserworker.cpp
Normal file
@ -0,0 +1,245 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dsp/wavfilerecord.h"
|
||||
|
||||
#include "denoiserworker.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(DenoiserWorker::MsgConfigureDenoiserWorker, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DenoiserWorker::MsgConnectFifo, Message)
|
||||
|
||||
DenoiserWorker::DenoiserWorker(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_dataFifo(nullptr),
|
||||
m_sinkSampleRate(0),
|
||||
m_msgQueueToFeature(nullptr),
|
||||
m_magsq(0.0),
|
||||
m_sampleBufferSize(0),
|
||||
m_channelPowerAvg(),
|
||||
m_wavFileRecord(nullptr),
|
||||
m_nbBytes(0)
|
||||
{
|
||||
}
|
||||
|
||||
DenoiserWorker::~DenoiserWorker()
|
||||
{
|
||||
m_inputMessageQueue.clear();
|
||||
}
|
||||
|
||||
void DenoiserWorker::reset()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_inputMessageQueue.clear();
|
||||
}
|
||||
|
||||
void DenoiserWorker::startWork()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_wavFileRecord = new WavFileRecord(m_sinkSampleRate);
|
||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
}
|
||||
|
||||
void DenoiserWorker::stopWork()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
if (m_wavFileRecord)
|
||||
{
|
||||
delete m_wavFileRecord;
|
||||
m_wavFileRecord = nullptr;
|
||||
}
|
||||
disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
}
|
||||
|
||||
void DenoiserWorker::feedPart(
|
||||
const QByteArray::const_iterator& begin,
|
||||
const QByteArray::const_iterator& end,
|
||||
DataFifo::DataType dataType
|
||||
)
|
||||
{
|
||||
int nbBytes;
|
||||
|
||||
switch(dataType)
|
||||
{
|
||||
case DataFifo::DataTypeCI16:
|
||||
nbBytes = 4;
|
||||
break;
|
||||
case DataFifo::DataTypeI16:
|
||||
default:
|
||||
nbBytes = 2;
|
||||
}
|
||||
|
||||
if ((nbBytes != m_nbBytes) && m_wavFileRecord)
|
||||
{
|
||||
m_wavFileRecord->stopRecording();
|
||||
m_wavFileRecord->setMono(nbBytes == 2);
|
||||
}
|
||||
|
||||
m_nbBytes = nbBytes;
|
||||
int countSamples = (end - begin) / nbBytes;
|
||||
|
||||
if (countSamples > m_sampleBufferSize)
|
||||
{
|
||||
m_sampleBuffer.resize(countSamples);
|
||||
m_sampleBufferSize = countSamples;
|
||||
}
|
||||
|
||||
for (int i = 0; i < countSamples; i++) {
|
||||
processSample(dataType, begin, i);
|
||||
}
|
||||
|
||||
if (m_settings.m_recordToFile && m_wavFileRecord)
|
||||
{
|
||||
for (int is = 0; is < countSamples; is++)
|
||||
{
|
||||
const Sample& sample = m_sampleBuffer[is];
|
||||
|
||||
if ((sample.m_real == 0) && (sample.m_imag == 0))
|
||||
{
|
||||
if (m_wavFileRecord->isRecording()) {
|
||||
m_wavFileRecord->stopRecording();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_wavFileRecord->isRecording()) {
|
||||
m_wavFileRecord->startRecording();
|
||||
}
|
||||
writeSampleToFile(sample);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserWorker::writeSampleToFile(const Sample& sample)
|
||||
{
|
||||
if (!m_wavFileRecord) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SDR_RX_SAMP_SZ == 16)
|
||||
{
|
||||
if (m_nbBytes == 2) {
|
||||
m_wavFileRecord->writeMono(sample.m_real);
|
||||
} else {
|
||||
m_wavFileRecord->write(sample.m_real, sample.m_imag);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_nbBytes == 2) {
|
||||
m_wavFileRecord->writeMono(sample.m_real >> 8);
|
||||
} else {
|
||||
m_wavFileRecord->write(sample.m_real >> 8, sample.m_imag >> 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserWorker::handleInputMessages()
|
||||
{
|
||||
Message* message = nullptr;
|
||||
|
||||
while ((message = m_inputMessageQueue.pop()) != nullptr)
|
||||
{
|
||||
const Message& cmd = *message;
|
||||
handleMessage(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
bool DenoiserWorker::handleMessage(const Message& cmd)
|
||||
{
|
||||
if (MsgConfigureDenoiserWorker::match(cmd))
|
||||
{
|
||||
const MsgConfigureDenoiserWorker& conf = static_cast<const MsgConfigureDenoiserWorker&>(cmd);
|
||||
qDebug("DenoiserWorker::handleMessage: MsgConfigureDenoiserWorker");
|
||||
applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce());
|
||||
return true;
|
||||
}
|
||||
else if (MsgConnectFifo::match(cmd))
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
MsgConnectFifo& msg = (MsgConnectFifo&) cmd;
|
||||
m_dataFifo = msg.getFifo();
|
||||
bool doConnect = msg.getConnect();
|
||||
qDebug("DenoiserWorker::handleMessage: MsgConnectFifo: %s", (doConnect ? "connect" : "disconnect"));
|
||||
|
||||
if (doConnect) {
|
||||
QObject::connect(
|
||||
m_dataFifo,
|
||||
&DataFifo::dataReady,
|
||||
this,
|
||||
&DenoiserWorker::handleData,
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
QObject::disconnect(
|
||||
m_dataFifo,
|
||||
&DataFifo::dataReady,
|
||||
this,
|
||||
&DenoiserWorker::handleData
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DenoiserWorker::applySettings(const DenoiserSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
Q_UNUSED(settingsKeys)
|
||||
Q_UNUSED(force)
|
||||
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
void DenoiserWorker::applySampleRate(int sampleRate)
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_sinkSampleRate = sampleRate;
|
||||
}
|
||||
|
||||
void DenoiserWorker::handleData()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
|
||||
while ((m_dataFifo->fill() > 0) && (m_inputMessageQueue.size() == 0))
|
||||
{
|
||||
QByteArray::iterator part1begin;
|
||||
QByteArray::iterator part1end;
|
||||
QByteArray::iterator part2begin;
|
||||
QByteArray::iterator part2end;
|
||||
DataFifo::DataType dataType;
|
||||
|
||||
std::size_t count = m_dataFifo->readBegin(m_dataFifo->fill(), &part1begin, &part1end, &part2begin, &part2end, dataType);
|
||||
|
||||
// first part of FIFO data
|
||||
if (part1begin != part1end) {
|
||||
feedPart(part1begin, part1end, dataType);
|
||||
}
|
||||
|
||||
// second part of FIFO data (used when block wraps around)
|
||||
if (part2begin != part2end) {
|
||||
feedPart(part2begin, part2end, dataType);
|
||||
}
|
||||
|
||||
m_dataFifo->readCommit((unsigned int) count);
|
||||
}
|
||||
}
|
||||
150
plugins/feature/denoiser/denoiserworker.h
Normal file
150
plugins/feature/denoiser/denoiserworker.h
Normal file
@ -0,0 +1,150 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDE_FEATURE_DENOISER_DENOISERWORKER_H_
|
||||
#define INCLUDE_FEATURE_DENOISER_DENOISERWORKER_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <QByteArray>
|
||||
|
||||
#include "util/movingaverage.h"
|
||||
#include "util/message.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "dsp/dsptypes.h"
|
||||
#include "dsp/datafifo.h"
|
||||
|
||||
#include "denoisersettings.h"
|
||||
|
||||
class WavFileRecord;
|
||||
|
||||
class DenoiserWorker : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
class MsgConfigureDenoiserWorker : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
public:
|
||||
const DenoiserSettings& getSettings() const { return m_settings; }
|
||||
const QStringList& getSettingsKeys() const { return m_settingsKeys; }
|
||||
bool getForce() const { return m_force; }
|
||||
static MsgConfigureDenoiserWorker* create(const DenoiserSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
return new MsgConfigureDenoiserWorker(settings, settingsKeys, force);
|
||||
}
|
||||
private:
|
||||
DenoiserSettings m_settings;
|
||||
QStringList m_settingsKeys;
|
||||
bool m_force;
|
||||
MsgConfigureDenoiserWorker(const DenoiserSettings& settings, const QStringList& settingsKeys, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_settingsKeys(settingsKeys),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgConnectFifo : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
public:
|
||||
DataFifo *getFifo() { return m_fifo; }
|
||||
bool getConnect() const { return m_connect; }
|
||||
static MsgConnectFifo* create(DataFifo *fifo, bool connect) {
|
||||
return new MsgConnectFifo(fifo, connect);
|
||||
}
|
||||
private:
|
||||
DataFifo *m_fifo;
|
||||
bool m_connect;
|
||||
MsgConnectFifo(DataFifo *fifo, bool connect) :
|
||||
Message(),
|
||||
m_fifo(fifo),
|
||||
m_connect(connect)
|
||||
{ }
|
||||
};
|
||||
|
||||
explicit DenoiserWorker(QObject *parent = nullptr);
|
||||
~DenoiserWorker() override;
|
||||
void reset();
|
||||
void startWork();
|
||||
void stopWork();
|
||||
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||
void setMessageQueueToFeature(MessageQueue *messageQueue) { m_msgQueueToFeature = messageQueue; }
|
||||
void applySampleRate(int sampleRate);
|
||||
void applySettings(const DenoiserSettings& settings, const QStringList& settingsKeys, bool force = false);
|
||||
double getMagSq() const { return m_magsq; }
|
||||
double getMagSqAvg() const { return (double) m_channelPowerAvg; }
|
||||
|
||||
private:
|
||||
DataFifo *m_dataFifo;
|
||||
int m_sinkSampleRate;
|
||||
MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
|
||||
MessageQueue *m_msgQueueToFeature; //!< Queue to report channel change to main feature object
|
||||
DenoiserSettings m_settings;
|
||||
double m_magsq;
|
||||
SampleVector m_sampleBuffer;
|
||||
int m_sampleBufferSize;
|
||||
MovingAverageUtil<double, double, 480> m_channelPowerAvg;
|
||||
WavFileRecord* m_wavFileRecord;
|
||||
int m_nbBytes;
|
||||
QRecursiveMutex m_mutex;
|
||||
|
||||
void feedPart(
|
||||
const QByteArray::const_iterator& begin,
|
||||
const QByteArray::const_iterator& end,
|
||||
DataFifo::DataType dataType
|
||||
);
|
||||
|
||||
bool handleMessage(const Message& cmd);
|
||||
void writeSampleToFile(const Sample& sample);
|
||||
|
||||
inline void processSample(
|
||||
DataFifo::DataType dataType,
|
||||
const QByteArray::const_iterator& begin,
|
||||
int i
|
||||
)
|
||||
{
|
||||
switch(dataType)
|
||||
{
|
||||
case DataFifo::DataTypeI16: {
|
||||
int16_t *s = (int16_t*) begin;
|
||||
double re = s[i] / (double) std::numeric_limits<int16_t>::max();
|
||||
m_magsq = re*re;
|
||||
m_channelPowerAvg(m_magsq);
|
||||
|
||||
m_sampleBuffer[i].setReal(re * SDR_RX_SCALEF);
|
||||
m_sampleBuffer[i].setImag(0);
|
||||
}
|
||||
break;
|
||||
case DataFifo::DataTypeCI16: {
|
||||
int16_t *s = (int16_t*) begin;
|
||||
double re = s[2*i] / (double) std::numeric_limits<int16_t>::max();
|
||||
double im = s[2*i+1] / (double) std::numeric_limits<int16_t>::max();
|
||||
m_magsq = re*re + im*im;
|
||||
m_channelPowerAvg(m_magsq);
|
||||
|
||||
m_sampleBuffer[i].setReal(re * SDR_RX_SCALEF);
|
||||
m_sampleBuffer[i].setImag(im * SDR_RX_SCALEF);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private slots:
|
||||
void handleInputMessages();
|
||||
void handleData(); //!< Handle data when samples have to be processed
|
||||
};
|
||||
|
||||
#endif // INCLUDE_FEATURE_DENOISER_DENOISERWORKER_H_
|
||||
@ -40,6 +40,7 @@
|
||||
<file>webapi/doc/swagger/include/DATVDemod.yaml</file>
|
||||
<file>webapi/doc/swagger/include/DATVMod.yaml</file>
|
||||
<file>webapi/doc/swagger/include/DemodAnalyzer.yaml</file>
|
||||
<file>webapi/doc/swagger/include/Denoiser.yaml</file>
|
||||
<file>webapi/doc/swagger/include/DeviceActions.yaml</file>
|
||||
<file>webapi/doc/swagger/include/DeviceReports.yaml</file>
|
||||
<file>webapi/doc/swagger/include/DeviceSettings.yaml</file>
|
||||
|
||||
@ -5625,6 +5625,66 @@ margin-bottom: 20px;
|
||||
}
|
||||
},
|
||||
"description" : "DemodAnalyzer"
|
||||
};
|
||||
defs.DenoiserActions = {
|
||||
"required" : [ "channelId", "deviceId" ],
|
||||
"properties" : {
|
||||
"deviceId" : {
|
||||
"type" : "integer",
|
||||
"description" : "Set source device Id/Number that channel belongs to"
|
||||
},
|
||||
"channelId" : {
|
||||
"type" : "integer",
|
||||
"description" : "Set source channel Id/Number of the channel within the device"
|
||||
}
|
||||
},
|
||||
"description" : "Denoiser actions"
|
||||
};
|
||||
defs.DenoiserSettings = {
|
||||
"properties" : {
|
||||
"denoiserType" : {
|
||||
"type" : "integer",
|
||||
"description" : "Denoiser type\n * 0 - none\n * 1 - RNnoise\n"
|
||||
},
|
||||
"audioMute" : {
|
||||
"type" : "integer",
|
||||
"description" : "Audio mute\n * 1 - mute\n * 0 - unmute\n"
|
||||
},
|
||||
"title" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"rgbColor" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"fileRecordName" : {
|
||||
"type" : "string",
|
||||
"description" : "Output wave file name"
|
||||
},
|
||||
"recordToFile" : {
|
||||
"type" : "integer",
|
||||
"description" : "Recording status\n * 1 - recording\n * 0 - not recording\n"
|
||||
},
|
||||
"useReverseAPI" : {
|
||||
"type" : "integer",
|
||||
"description" : "Synchronize with reverse API\n * 1 - yes\n * 0 - no\n"
|
||||
},
|
||||
"reverseAPIAddress" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"reverseAPIPort" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"reverseAPIFeatureSetIndex" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"reverseAPIFeatureIndex" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"rollupState" : {
|
||||
"$ref" : "#/definitions/RollupState"
|
||||
}
|
||||
},
|
||||
"description" : "Denoiser"
|
||||
};
|
||||
defs.DeviceActions = {
|
||||
"required" : [ "deviceHwType", "direction" ],
|
||||
@ -6518,6 +6578,9 @@ margin-bottom: 20px;
|
||||
},
|
||||
"DemodAnalyzerActions" : {
|
||||
"$ref" : "#/definitions/DemodAnalyzerActions"
|
||||
},
|
||||
"DenoiserActions" : {
|
||||
"$ref" : "#/definitions/DenoiserActions"
|
||||
}
|
||||
},
|
||||
"description" : "Base feature actions. Only the feature actions corresponding to the feature specified in the featureType field is or should be present."
|
||||
@ -6735,6 +6798,9 @@ margin-bottom: 20px;
|
||||
"DemodAnalyzerSettings" : {
|
||||
"$ref" : "#/definitions/DemodAnalyzerSettings"
|
||||
},
|
||||
"DenoiserSettings" : {
|
||||
"$ref" : "#/definitions/DenoiserSettings"
|
||||
},
|
||||
"JogdialControllerSettings" : {
|
||||
"$ref" : "#/definitions/JogdialControllerSettings"
|
||||
},
|
||||
@ -59654,7 +59720,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2026-01-04T12:41:15.650+01:00
|
||||
Generated 2026-01-06T07:31:33.605+01:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
57
sdrbase/resources/webapi/doc/swagger/include/Denoiser.yaml
Normal file
57
sdrbase/resources/webapi/doc/swagger/include/Denoiser.yaml
Normal file
@ -0,0 +1,57 @@
|
||||
DenoiserSettings:
|
||||
description: Denoiser
|
||||
properties:
|
||||
denoiserType:
|
||||
type: integer
|
||||
description: >
|
||||
Denoiser type
|
||||
* 0 - none
|
||||
* 1 - RNnoise
|
||||
audioMute:
|
||||
type: integer
|
||||
description: >
|
||||
Audio mute
|
||||
* 1 - mute
|
||||
* 0 - unmute
|
||||
title:
|
||||
type: string
|
||||
rgbColor:
|
||||
type: integer
|
||||
fileRecordName:
|
||||
type: string
|
||||
description: Output wave file name
|
||||
recordToFile:
|
||||
type: integer
|
||||
description: >
|
||||
Recording status
|
||||
* 1 - recording
|
||||
* 0 - not recording
|
||||
useReverseAPI:
|
||||
type: integer
|
||||
description: >
|
||||
Synchronize with reverse API
|
||||
* 1 - yes
|
||||
* 0 - no
|
||||
reverseAPIAddress:
|
||||
type: string
|
||||
reverseAPIPort:
|
||||
type: integer
|
||||
reverseAPIFeatureSetIndex:
|
||||
type: integer
|
||||
reverseAPIFeatureIndex:
|
||||
type: integer
|
||||
rollupState:
|
||||
$ref: "/doc/swagger/include/RollupState.yaml#/RollupState"
|
||||
|
||||
DenoiserActions:
|
||||
description: "Denoiser actions"
|
||||
required:
|
||||
- deviceId
|
||||
- channelId
|
||||
properties:
|
||||
deviceId:
|
||||
type: integer
|
||||
description: "Set source device Id/Number that channel belongs to"
|
||||
channelId:
|
||||
type: integer
|
||||
description: "Set source channel Id/Number of the channel within the device"
|
||||
@ -41,3 +41,5 @@ FeatureActions:
|
||||
$ref: "/doc/swagger/include/VORLocalizer.yaml#/VORLocalizerActions"
|
||||
DemodAnalyzerActions:
|
||||
$ref: "/doc/swagger/include/DemodAnalyzer.yaml#/DemodAnalyzerActions"
|
||||
DenoiserActions:
|
||||
$ref: "/doc/swagger/include/Denoiser.yaml#/DenoiserActions"
|
||||
|
||||
@ -25,6 +25,8 @@ FeatureSettings:
|
||||
$ref: "/doc/swagger/include/APRS.yaml#/APRSSettings"
|
||||
DemodAnalyzerSettings:
|
||||
$ref: "/doc/swagger/include/DemodAnalyzer.yaml#/DemodAnalyzerSettings"
|
||||
DenoiserSettings:
|
||||
$ref: "/doc/swagger/include/Denoiser.yaml#/DenoiserSettings"
|
||||
JogdialControllerSettings:
|
||||
$ref: "/doc/swagger/include/JogdialController.yaml#/JogdialControllerSettings"
|
||||
GS232ControllerSettings:
|
||||
|
||||
57
swagger/sdrangel/api/swagger/include/Denoiser.yaml
Normal file
57
swagger/sdrangel/api/swagger/include/Denoiser.yaml
Normal file
@ -0,0 +1,57 @@
|
||||
DenoiserSettings:
|
||||
description: Denoiser
|
||||
properties:
|
||||
denoiserType:
|
||||
type: integer
|
||||
description: >
|
||||
Denoiser type
|
||||
* 0 - none
|
||||
* 1 - RNnoise
|
||||
audioMute:
|
||||
type: integer
|
||||
description: >
|
||||
Audio mute
|
||||
* 1 - mute
|
||||
* 0 - unmute
|
||||
title:
|
||||
type: string
|
||||
rgbColor:
|
||||
type: integer
|
||||
fileRecordName:
|
||||
type: string
|
||||
description: Output wave file name
|
||||
recordToFile:
|
||||
type: integer
|
||||
description: >
|
||||
Recording status
|
||||
* 1 - recording
|
||||
* 0 - not recording
|
||||
useReverseAPI:
|
||||
type: integer
|
||||
description: >
|
||||
Synchronize with reverse API
|
||||
* 1 - yes
|
||||
* 0 - no
|
||||
reverseAPIAddress:
|
||||
type: string
|
||||
reverseAPIPort:
|
||||
type: integer
|
||||
reverseAPIFeatureSetIndex:
|
||||
type: integer
|
||||
reverseAPIFeatureIndex:
|
||||
type: integer
|
||||
rollupState:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RollupState.yaml#/RollupState"
|
||||
|
||||
DenoiserActions:
|
||||
description: "Denoiser actions"
|
||||
required:
|
||||
- deviceId
|
||||
- channelId
|
||||
properties:
|
||||
deviceId:
|
||||
type: integer
|
||||
description: "Set source device Id/Number that channel belongs to"
|
||||
channelId:
|
||||
type: integer
|
||||
description: "Set source channel Id/Number of the channel within the device"
|
||||
@ -41,3 +41,5 @@ FeatureActions:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/VORLocalizer.yaml#/VORLocalizerActions"
|
||||
DemodAnalyzerActions:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/DemodAnalyzer.yaml#/DemodAnalyzerActions"
|
||||
DenoiserActions:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/Denoiser.yaml#/DenoiserActions"
|
||||
|
||||
@ -25,6 +25,8 @@ FeatureSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/APRS.yaml#/APRSSettings"
|
||||
DemodAnalyzerSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/DemodAnalyzer.yaml#/DemodAnalyzerSettings"
|
||||
DenoiserSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/Denoiser.yaml#/DenoiserSettings"
|
||||
JogdialControllerSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/JogdialController.yaml#/JogdialControllerSettings"
|
||||
GS232ControllerSettings:
|
||||
|
||||
@ -5625,6 +5625,66 @@ margin-bottom: 20px;
|
||||
}
|
||||
},
|
||||
"description" : "DemodAnalyzer"
|
||||
};
|
||||
defs.DenoiserActions = {
|
||||
"required" : [ "channelId", "deviceId" ],
|
||||
"properties" : {
|
||||
"deviceId" : {
|
||||
"type" : "integer",
|
||||
"description" : "Set source device Id/Number that channel belongs to"
|
||||
},
|
||||
"channelId" : {
|
||||
"type" : "integer",
|
||||
"description" : "Set source channel Id/Number of the channel within the device"
|
||||
}
|
||||
},
|
||||
"description" : "Denoiser actions"
|
||||
};
|
||||
defs.DenoiserSettings = {
|
||||
"properties" : {
|
||||
"denoiserType" : {
|
||||
"type" : "integer",
|
||||
"description" : "Denoiser type\n * 0 - none\n * 1 - RNnoise\n"
|
||||
},
|
||||
"audioMute" : {
|
||||
"type" : "integer",
|
||||
"description" : "Audio mute\n * 1 - mute\n * 0 - unmute\n"
|
||||
},
|
||||
"title" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"rgbColor" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"fileRecordName" : {
|
||||
"type" : "string",
|
||||
"description" : "Output wave file name"
|
||||
},
|
||||
"recordToFile" : {
|
||||
"type" : "integer",
|
||||
"description" : "Recording status\n * 1 - recording\n * 0 - not recording\n"
|
||||
},
|
||||
"useReverseAPI" : {
|
||||
"type" : "integer",
|
||||
"description" : "Synchronize with reverse API\n * 1 - yes\n * 0 - no\n"
|
||||
},
|
||||
"reverseAPIAddress" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"reverseAPIPort" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"reverseAPIFeatureSetIndex" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"reverseAPIFeatureIndex" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"rollupState" : {
|
||||
"$ref" : "#/definitions/RollupState"
|
||||
}
|
||||
},
|
||||
"description" : "Denoiser"
|
||||
};
|
||||
defs.DeviceActions = {
|
||||
"required" : [ "deviceHwType", "direction" ],
|
||||
@ -6518,6 +6578,9 @@ margin-bottom: 20px;
|
||||
},
|
||||
"DemodAnalyzerActions" : {
|
||||
"$ref" : "#/definitions/DemodAnalyzerActions"
|
||||
},
|
||||
"DenoiserActions" : {
|
||||
"$ref" : "#/definitions/DenoiserActions"
|
||||
}
|
||||
},
|
||||
"description" : "Base feature actions. Only the feature actions corresponding to the feature specified in the featureType field is or should be present."
|
||||
@ -6735,6 +6798,9 @@ margin-bottom: 20px;
|
||||
"DemodAnalyzerSettings" : {
|
||||
"$ref" : "#/definitions/DemodAnalyzerSettings"
|
||||
},
|
||||
"DenoiserSettings" : {
|
||||
"$ref" : "#/definitions/DenoiserSettings"
|
||||
},
|
||||
"JogdialControllerSettings" : {
|
||||
"$ref" : "#/definitions/JogdialControllerSettings"
|
||||
},
|
||||
@ -59654,7 +59720,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2026-01-04T12:41:15.650+01:00
|
||||
Generated 2026-01-06T07:31:33.605+01:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
131
swagger/sdrangel/code/qt5/client/SWGDenoiserActions.cpp
Normal file
131
swagger/sdrangel/code/qt5/client/SWGDenoiserActions.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "SWGDenoiserActions.h"
|
||||
|
||||
#include "SWGHelpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
SWGDenoiserActions::SWGDenoiserActions(QString* json) {
|
||||
init();
|
||||
this->fromJson(*json);
|
||||
}
|
||||
|
||||
SWGDenoiserActions::SWGDenoiserActions() {
|
||||
device_id = 0;
|
||||
m_device_id_isSet = false;
|
||||
channel_id = 0;
|
||||
m_channel_id_isSet = false;
|
||||
}
|
||||
|
||||
SWGDenoiserActions::~SWGDenoiserActions() {
|
||||
this->cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
SWGDenoiserActions::init() {
|
||||
device_id = 0;
|
||||
m_device_id_isSet = false;
|
||||
channel_id = 0;
|
||||
m_channel_id_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGDenoiserActions::cleanup() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
SWGDenoiserActions*
|
||||
SWGDenoiserActions::fromJson(QString &json) {
|
||||
QByteArray array (json.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
SWGDenoiserActions::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&device_id, pJson["deviceId"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&channel_id, pJson["channelId"], "qint32", "");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
SWGDenoiserActions::asJson ()
|
||||
{
|
||||
QJsonObject* obj = this->asJsonObject();
|
||||
|
||||
QJsonDocument doc(*obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
delete obj;
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject*
|
||||
SWGDenoiserActions::asJsonObject() {
|
||||
QJsonObject* obj = new QJsonObject();
|
||||
if(m_device_id_isSet){
|
||||
obj->insert("deviceId", QJsonValue(device_id));
|
||||
}
|
||||
if(m_channel_id_isSet){
|
||||
obj->insert("channelId", QJsonValue(channel_id));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserActions::getDeviceId() {
|
||||
return device_id;
|
||||
}
|
||||
void
|
||||
SWGDenoiserActions::setDeviceId(qint32 device_id) {
|
||||
this->device_id = device_id;
|
||||
this->m_device_id_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserActions::getChannelId() {
|
||||
return channel_id;
|
||||
}
|
||||
void
|
||||
SWGDenoiserActions::setChannelId(qint32 channel_id) {
|
||||
this->channel_id = channel_id;
|
||||
this->m_channel_id_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGDenoiserActions::isSet(){
|
||||
bool isObjectUpdated = false;
|
||||
do{
|
||||
if(m_device_id_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_channel_id_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
64
swagger/sdrangel/code/qt5/client/SWGDenoiserActions.h
Normal file
64
swagger/sdrangel/code/qt5/client/SWGDenoiserActions.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWGDenoiserActions.h
|
||||
*
|
||||
* Denoiser actions
|
||||
*/
|
||||
|
||||
#ifndef SWGDenoiserActions_H_
|
||||
#define SWGDenoiserActions_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
|
||||
#include "SWGObject.h"
|
||||
#include "export.h"
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
class SWG_API SWGDenoiserActions: public SWGObject {
|
||||
public:
|
||||
SWGDenoiserActions();
|
||||
SWGDenoiserActions(QString* json);
|
||||
virtual ~SWGDenoiserActions();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
virtual QString asJson () override;
|
||||
virtual QJsonObject* asJsonObject() override;
|
||||
virtual void fromJsonObject(QJsonObject &json) override;
|
||||
virtual SWGDenoiserActions* fromJson(QString &jsonString) override;
|
||||
|
||||
qint32 getDeviceId();
|
||||
void setDeviceId(qint32 device_id);
|
||||
|
||||
qint32 getChannelId();
|
||||
void setChannelId(qint32 channel_id);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
private:
|
||||
qint32 device_id;
|
||||
bool m_device_id_isSet;
|
||||
|
||||
qint32 channel_id;
|
||||
bool m_channel_id_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGDenoiserActions_H_ */
|
||||
369
swagger/sdrangel/code/qt5/client/SWGDenoiserSettings.cpp
Normal file
369
swagger/sdrangel/code/qt5/client/SWGDenoiserSettings.cpp
Normal file
@ -0,0 +1,369 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "SWGDenoiserSettings.h"
|
||||
|
||||
#include "SWGHelpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
SWGDenoiserSettings::SWGDenoiserSettings(QString* json) {
|
||||
init();
|
||||
this->fromJson(*json);
|
||||
}
|
||||
|
||||
SWGDenoiserSettings::SWGDenoiserSettings() {
|
||||
denoiser_type = 0;
|
||||
m_denoiser_type_isSet = false;
|
||||
audio_mute = 0;
|
||||
m_audio_mute_isSet = false;
|
||||
title = nullptr;
|
||||
m_title_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
file_record_name = nullptr;
|
||||
m_file_record_name_isSet = false;
|
||||
record_to_file = 0;
|
||||
m_record_to_file_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
m_use_reverse_api_isSet = false;
|
||||
reverse_api_address = nullptr;
|
||||
m_reverse_api_address_isSet = false;
|
||||
reverse_api_port = 0;
|
||||
m_reverse_api_port_isSet = false;
|
||||
reverse_api_feature_set_index = 0;
|
||||
m_reverse_api_feature_set_index_isSet = false;
|
||||
reverse_api_feature_index = 0;
|
||||
m_reverse_api_feature_index_isSet = false;
|
||||
rollup_state = nullptr;
|
||||
m_rollup_state_isSet = false;
|
||||
}
|
||||
|
||||
SWGDenoiserSettings::~SWGDenoiserSettings() {
|
||||
this->cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
SWGDenoiserSettings::init() {
|
||||
denoiser_type = 0;
|
||||
m_denoiser_type_isSet = false;
|
||||
audio_mute = 0;
|
||||
m_audio_mute_isSet = false;
|
||||
title = new QString("");
|
||||
m_title_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
file_record_name = new QString("");
|
||||
m_file_record_name_isSet = false;
|
||||
record_to_file = 0;
|
||||
m_record_to_file_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
m_use_reverse_api_isSet = false;
|
||||
reverse_api_address = new QString("");
|
||||
m_reverse_api_address_isSet = false;
|
||||
reverse_api_port = 0;
|
||||
m_reverse_api_port_isSet = false;
|
||||
reverse_api_feature_set_index = 0;
|
||||
m_reverse_api_feature_set_index_isSet = false;
|
||||
reverse_api_feature_index = 0;
|
||||
m_reverse_api_feature_index_isSet = false;
|
||||
rollup_state = new SWGRollupState();
|
||||
m_rollup_state_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGDenoiserSettings::cleanup() {
|
||||
|
||||
|
||||
if(title != nullptr) {
|
||||
delete title;
|
||||
}
|
||||
|
||||
if(file_record_name != nullptr) {
|
||||
delete file_record_name;
|
||||
}
|
||||
|
||||
|
||||
if(reverse_api_address != nullptr) {
|
||||
delete reverse_api_address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(rollup_state != nullptr) {
|
||||
delete rollup_state;
|
||||
}
|
||||
}
|
||||
|
||||
SWGDenoiserSettings*
|
||||
SWGDenoiserSettings::fromJson(QString &json) {
|
||||
QByteArray array (json.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
SWGDenoiserSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&denoiser_type, pJson["denoiserType"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&audio_mute, pJson["audioMute"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&file_record_name, pJson["fileRecordName"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&record_to_file, pJson["recordToFile"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_port, pJson["reverseAPIPort"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_feature_set_index, pJson["reverseAPIFeatureSetIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_feature_index, pJson["reverseAPIFeatureIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&rollup_state, pJson["rollupState"], "SWGRollupState", "SWGRollupState");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
SWGDenoiserSettings::asJson ()
|
||||
{
|
||||
QJsonObject* obj = this->asJsonObject();
|
||||
|
||||
QJsonDocument doc(*obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
delete obj;
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject*
|
||||
SWGDenoiserSettings::asJsonObject() {
|
||||
QJsonObject* obj = new QJsonObject();
|
||||
if(m_denoiser_type_isSet){
|
||||
obj->insert("denoiserType", QJsonValue(denoiser_type));
|
||||
}
|
||||
if(m_audio_mute_isSet){
|
||||
obj->insert("audioMute", QJsonValue(audio_mute));
|
||||
}
|
||||
if(title != nullptr && *title != QString("")){
|
||||
toJsonValue(QString("title"), title, obj, QString("QString"));
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
obj->insert("rgbColor", QJsonValue(rgb_color));
|
||||
}
|
||||
if(file_record_name != nullptr && *file_record_name != QString("")){
|
||||
toJsonValue(QString("fileRecordName"), file_record_name, obj, QString("QString"));
|
||||
}
|
||||
if(m_record_to_file_isSet){
|
||||
obj->insert("recordToFile", QJsonValue(record_to_file));
|
||||
}
|
||||
if(m_use_reverse_api_isSet){
|
||||
obj->insert("useReverseAPI", QJsonValue(use_reverse_api));
|
||||
}
|
||||
if(reverse_api_address != nullptr && *reverse_api_address != QString("")){
|
||||
toJsonValue(QString("reverseAPIAddress"), reverse_api_address, obj, QString("QString"));
|
||||
}
|
||||
if(m_reverse_api_port_isSet){
|
||||
obj->insert("reverseAPIPort", QJsonValue(reverse_api_port));
|
||||
}
|
||||
if(m_reverse_api_feature_set_index_isSet){
|
||||
obj->insert("reverseAPIFeatureSetIndex", QJsonValue(reverse_api_feature_set_index));
|
||||
}
|
||||
if(m_reverse_api_feature_index_isSet){
|
||||
obj->insert("reverseAPIFeatureIndex", QJsonValue(reverse_api_feature_index));
|
||||
}
|
||||
if((rollup_state != nullptr) && (rollup_state->isSet())){
|
||||
toJsonValue(QString("rollupState"), rollup_state, obj, QString("SWGRollupState"));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserSettings::getDenoiserType() {
|
||||
return denoiser_type;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setDenoiserType(qint32 denoiser_type) {
|
||||
this->denoiser_type = denoiser_type;
|
||||
this->m_denoiser_type_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserSettings::getAudioMute() {
|
||||
return audio_mute;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setAudioMute(qint32 audio_mute) {
|
||||
this->audio_mute = audio_mute;
|
||||
this->m_audio_mute_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGDenoiserSettings::getTitle() {
|
||||
return title;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setTitle(QString* title) {
|
||||
this->title = title;
|
||||
this->m_title_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserSettings::getRgbColor() {
|
||||
return rgb_color;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setRgbColor(qint32 rgb_color) {
|
||||
this->rgb_color = rgb_color;
|
||||
this->m_rgb_color_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGDenoiserSettings::getFileRecordName() {
|
||||
return file_record_name;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setFileRecordName(QString* file_record_name) {
|
||||
this->file_record_name = file_record_name;
|
||||
this->m_file_record_name_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserSettings::getRecordToFile() {
|
||||
return record_to_file;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setRecordToFile(qint32 record_to_file) {
|
||||
this->record_to_file = record_to_file;
|
||||
this->m_record_to_file_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserSettings::getUseReverseApi() {
|
||||
return use_reverse_api;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setUseReverseApi(qint32 use_reverse_api) {
|
||||
this->use_reverse_api = use_reverse_api;
|
||||
this->m_use_reverse_api_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGDenoiserSettings::getReverseApiAddress() {
|
||||
return reverse_api_address;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setReverseApiAddress(QString* reverse_api_address) {
|
||||
this->reverse_api_address = reverse_api_address;
|
||||
this->m_reverse_api_address_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserSettings::getReverseApiPort() {
|
||||
return reverse_api_port;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setReverseApiPort(qint32 reverse_api_port) {
|
||||
this->reverse_api_port = reverse_api_port;
|
||||
this->m_reverse_api_port_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserSettings::getReverseApiFeatureSetIndex() {
|
||||
return reverse_api_feature_set_index;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setReverseApiFeatureSetIndex(qint32 reverse_api_feature_set_index) {
|
||||
this->reverse_api_feature_set_index = reverse_api_feature_set_index;
|
||||
this->m_reverse_api_feature_set_index_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGDenoiserSettings::getReverseApiFeatureIndex() {
|
||||
return reverse_api_feature_index;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setReverseApiFeatureIndex(qint32 reverse_api_feature_index) {
|
||||
this->reverse_api_feature_index = reverse_api_feature_index;
|
||||
this->m_reverse_api_feature_index_isSet = true;
|
||||
}
|
||||
|
||||
SWGRollupState*
|
||||
SWGDenoiserSettings::getRollupState() {
|
||||
return rollup_state;
|
||||
}
|
||||
void
|
||||
SWGDenoiserSettings::setRollupState(SWGRollupState* rollup_state) {
|
||||
this->rollup_state = rollup_state;
|
||||
this->m_rollup_state_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGDenoiserSettings::isSet(){
|
||||
bool isObjectUpdated = false;
|
||||
do{
|
||||
if(m_denoiser_type_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_audio_mute_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(title && *title != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(file_record_name && *file_record_name != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_record_to_file_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_use_reverse_api_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(reverse_api_address && *reverse_api_address != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_port_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_feature_set_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_feature_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(rollup_state && rollup_state->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
126
swagger/sdrangel/code/qt5/client/SWGDenoiserSettings.h
Normal file
126
swagger/sdrangel/code/qt5/client/SWGDenoiserSettings.h
Normal file
@ -0,0 +1,126 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWGDenoiserSettings.h
|
||||
*
|
||||
* Denoiser
|
||||
*/
|
||||
|
||||
#ifndef SWGDenoiserSettings_H_
|
||||
#define SWGDenoiserSettings_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
#include "SWGRollupState.h"
|
||||
#include <QString>
|
||||
|
||||
#include "SWGObject.h"
|
||||
#include "export.h"
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
class SWG_API SWGDenoiserSettings: public SWGObject {
|
||||
public:
|
||||
SWGDenoiserSettings();
|
||||
SWGDenoiserSettings(QString* json);
|
||||
virtual ~SWGDenoiserSettings();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
virtual QString asJson () override;
|
||||
virtual QJsonObject* asJsonObject() override;
|
||||
virtual void fromJsonObject(QJsonObject &json) override;
|
||||
virtual SWGDenoiserSettings* fromJson(QString &jsonString) override;
|
||||
|
||||
qint32 getDenoiserType();
|
||||
void setDenoiserType(qint32 denoiser_type);
|
||||
|
||||
qint32 getAudioMute();
|
||||
void setAudioMute(qint32 audio_mute);
|
||||
|
||||
QString* getTitle();
|
||||
void setTitle(QString* title);
|
||||
|
||||
qint32 getRgbColor();
|
||||
void setRgbColor(qint32 rgb_color);
|
||||
|
||||
QString* getFileRecordName();
|
||||
void setFileRecordName(QString* file_record_name);
|
||||
|
||||
qint32 getRecordToFile();
|
||||
void setRecordToFile(qint32 record_to_file);
|
||||
|
||||
qint32 getUseReverseApi();
|
||||
void setUseReverseApi(qint32 use_reverse_api);
|
||||
|
||||
QString* getReverseApiAddress();
|
||||
void setReverseApiAddress(QString* reverse_api_address);
|
||||
|
||||
qint32 getReverseApiPort();
|
||||
void setReverseApiPort(qint32 reverse_api_port);
|
||||
|
||||
qint32 getReverseApiFeatureSetIndex();
|
||||
void setReverseApiFeatureSetIndex(qint32 reverse_api_feature_set_index);
|
||||
|
||||
qint32 getReverseApiFeatureIndex();
|
||||
void setReverseApiFeatureIndex(qint32 reverse_api_feature_index);
|
||||
|
||||
SWGRollupState* getRollupState();
|
||||
void setRollupState(SWGRollupState* rollup_state);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
private:
|
||||
qint32 denoiser_type;
|
||||
bool m_denoiser_type_isSet;
|
||||
|
||||
qint32 audio_mute;
|
||||
bool m_audio_mute_isSet;
|
||||
|
||||
QString* title;
|
||||
bool m_title_isSet;
|
||||
|
||||
qint32 rgb_color;
|
||||
bool m_rgb_color_isSet;
|
||||
|
||||
QString* file_record_name;
|
||||
bool m_file_record_name_isSet;
|
||||
|
||||
qint32 record_to_file;
|
||||
bool m_record_to_file_isSet;
|
||||
|
||||
qint32 use_reverse_api;
|
||||
bool m_use_reverse_api_isSet;
|
||||
|
||||
QString* reverse_api_address;
|
||||
bool m_reverse_api_address_isSet;
|
||||
|
||||
qint32 reverse_api_port;
|
||||
bool m_reverse_api_port_isSet;
|
||||
|
||||
qint32 reverse_api_feature_set_index;
|
||||
bool m_reverse_api_feature_set_index_isSet;
|
||||
|
||||
qint32 reverse_api_feature_index;
|
||||
bool m_reverse_api_feature_index_isSet;
|
||||
|
||||
SWGRollupState* rollup_state;
|
||||
bool m_rollup_state_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGDenoiserSettings_H_ */
|
||||
@ -62,6 +62,8 @@ SWGFeatureActions::SWGFeatureActions() {
|
||||
m_vor_localizer_actions_isSet = false;
|
||||
demod_analyzer_actions = nullptr;
|
||||
m_demod_analyzer_actions_isSet = false;
|
||||
denoiser_actions = nullptr;
|
||||
m_denoiser_actions_isSet = false;
|
||||
}
|
||||
|
||||
SWGFeatureActions::~SWGFeatureActions() {
|
||||
@ -104,6 +106,8 @@ SWGFeatureActions::init() {
|
||||
m_vor_localizer_actions_isSet = false;
|
||||
demod_analyzer_actions = new SWGDemodAnalyzerActions();
|
||||
m_demod_analyzer_actions_isSet = false;
|
||||
denoiser_actions = new SWGDenoiserActions();
|
||||
m_denoiser_actions_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
@ -155,6 +159,9 @@ SWGFeatureActions::cleanup() {
|
||||
if(demod_analyzer_actions != nullptr) {
|
||||
delete demod_analyzer_actions;
|
||||
}
|
||||
if(denoiser_actions != nullptr) {
|
||||
delete denoiser_actions;
|
||||
}
|
||||
}
|
||||
|
||||
SWGFeatureActions*
|
||||
@ -202,6 +209,8 @@ SWGFeatureActions::fromJsonObject(QJsonObject &pJson) {
|
||||
|
||||
::SWGSDRangel::setValue(&demod_analyzer_actions, pJson["DemodAnalyzerActions"], "SWGDemodAnalyzerActions", "SWGDemodAnalyzerActions");
|
||||
|
||||
::SWGSDRangel::setValue(&denoiser_actions, pJson["DenoiserActions"], "SWGDenoiserActions", "SWGDenoiserActions");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
@ -269,6 +278,9 @@ SWGFeatureActions::asJsonObject() {
|
||||
if((demod_analyzer_actions != nullptr) && (demod_analyzer_actions->isSet())){
|
||||
toJsonValue(QString("DemodAnalyzerActions"), demod_analyzer_actions, obj, QString("SWGDemodAnalyzerActions"));
|
||||
}
|
||||
if((denoiser_actions != nullptr) && (denoiser_actions->isSet())){
|
||||
toJsonValue(QString("DenoiserActions"), denoiser_actions, obj, QString("SWGDenoiserActions"));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -443,6 +455,16 @@ SWGFeatureActions::setDemodAnalyzerActions(SWGDemodAnalyzerActions* demod_analyz
|
||||
this->m_demod_analyzer_actions_isSet = true;
|
||||
}
|
||||
|
||||
SWGDenoiserActions*
|
||||
SWGFeatureActions::getDenoiserActions() {
|
||||
return denoiser_actions;
|
||||
}
|
||||
void
|
||||
SWGFeatureActions::setDenoiserActions(SWGDenoiserActions* denoiser_actions) {
|
||||
this->denoiser_actions = denoiser_actions;
|
||||
this->m_denoiser_actions_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGFeatureActions::isSet(){
|
||||
@ -499,6 +521,9 @@ SWGFeatureActions::isSet(){
|
||||
if(demod_analyzer_actions && demod_analyzer_actions->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(denoiser_actions && denoiser_actions->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "SWGAFCActions.h"
|
||||
#include "SWGAMBEActions.h"
|
||||
#include "SWGDemodAnalyzerActions.h"
|
||||
#include "SWGDenoiserActions.h"
|
||||
#include "SWGGS232ControllerActions.h"
|
||||
#include "SWGLimeRFEActions.h"
|
||||
#include "SWGMapActions.h"
|
||||
@ -107,6 +108,9 @@ public:
|
||||
SWGDemodAnalyzerActions* getDemodAnalyzerActions();
|
||||
void setDemodAnalyzerActions(SWGDemodAnalyzerActions* demod_analyzer_actions);
|
||||
|
||||
SWGDenoiserActions* getDenoiserActions();
|
||||
void setDenoiserActions(SWGDenoiserActions* denoiser_actions);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
@ -162,6 +166,9 @@ private:
|
||||
SWGDemodAnalyzerActions* demod_analyzer_actions;
|
||||
bool m_demod_analyzer_actions_isSet;
|
||||
|
||||
SWGDenoiserActions* denoiser_actions;
|
||||
bool m_denoiser_actions_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -46,6 +46,8 @@ SWGFeatureSettings::SWGFeatureSettings() {
|
||||
m_aprs_settings_isSet = false;
|
||||
demod_analyzer_settings = nullptr;
|
||||
m_demod_analyzer_settings_isSet = false;
|
||||
denoiser_settings = nullptr;
|
||||
m_denoiser_settings_isSet = false;
|
||||
jogdial_controller_settings = nullptr;
|
||||
m_jogdial_controller_settings_isSet = false;
|
||||
gs232_controller_settings = nullptr;
|
||||
@ -100,6 +102,8 @@ SWGFeatureSettings::init() {
|
||||
m_aprs_settings_isSet = false;
|
||||
demod_analyzer_settings = new SWGDemodAnalyzerSettings();
|
||||
m_demod_analyzer_settings_isSet = false;
|
||||
denoiser_settings = new SWGDenoiserSettings();
|
||||
m_denoiser_settings_isSet = false;
|
||||
jogdial_controller_settings = new SWGJogdialControllerSettings();
|
||||
m_jogdial_controller_settings_isSet = false;
|
||||
gs232_controller_settings = new SWGGS232ControllerSettings();
|
||||
@ -155,6 +159,9 @@ SWGFeatureSettings::cleanup() {
|
||||
if(demod_analyzer_settings != nullptr) {
|
||||
delete demod_analyzer_settings;
|
||||
}
|
||||
if(denoiser_settings != nullptr) {
|
||||
delete denoiser_settings;
|
||||
}
|
||||
if(jogdial_controller_settings != nullptr) {
|
||||
delete jogdial_controller_settings;
|
||||
}
|
||||
@ -228,6 +235,8 @@ SWGFeatureSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
|
||||
::SWGSDRangel::setValue(&demod_analyzer_settings, pJson["DemodAnalyzerSettings"], "SWGDemodAnalyzerSettings", "SWGDemodAnalyzerSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&denoiser_settings, pJson["DenoiserSettings"], "SWGDenoiserSettings", "SWGDenoiserSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&jogdial_controller_settings, pJson["JogdialControllerSettings"], "SWGJogdialControllerSettings", "SWGJogdialControllerSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&gs232_controller_settings, pJson["GS232ControllerSettings"], "SWGGS232ControllerSettings", "SWGGS232ControllerSettings");
|
||||
@ -299,6 +308,9 @@ SWGFeatureSettings::asJsonObject() {
|
||||
if((demod_analyzer_settings != nullptr) && (demod_analyzer_settings->isSet())){
|
||||
toJsonValue(QString("DemodAnalyzerSettings"), demod_analyzer_settings, obj, QString("SWGDemodAnalyzerSettings"));
|
||||
}
|
||||
if((denoiser_settings != nullptr) && (denoiser_settings->isSet())){
|
||||
toJsonValue(QString("DenoiserSettings"), denoiser_settings, obj, QString("SWGDenoiserSettings"));
|
||||
}
|
||||
if((jogdial_controller_settings != nullptr) && (jogdial_controller_settings->isSet())){
|
||||
toJsonValue(QString("JogdialControllerSettings"), jogdial_controller_settings, obj, QString("SWGJogdialControllerSettings"));
|
||||
}
|
||||
@ -435,6 +447,16 @@ SWGFeatureSettings::setDemodAnalyzerSettings(SWGDemodAnalyzerSettings* demod_ana
|
||||
this->m_demod_analyzer_settings_isSet = true;
|
||||
}
|
||||
|
||||
SWGDenoiserSettings*
|
||||
SWGFeatureSettings::getDenoiserSettings() {
|
||||
return denoiser_settings;
|
||||
}
|
||||
void
|
||||
SWGFeatureSettings::setDenoiserSettings(SWGDenoiserSettings* denoiser_settings) {
|
||||
this->denoiser_settings = denoiser_settings;
|
||||
this->m_denoiser_settings_isSet = true;
|
||||
}
|
||||
|
||||
SWGJogdialControllerSettings*
|
||||
SWGFeatureSettings::getJogdialControllerSettings() {
|
||||
return jogdial_controller_settings;
|
||||
@ -607,6 +629,9 @@ SWGFeatureSettings::isSet(){
|
||||
if(demod_analyzer_settings && demod_analyzer_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(denoiser_settings && denoiser_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(jogdial_controller_settings && jogdial_controller_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "SWGAPRSSettings.h"
|
||||
#include "SWGAntennaToolsSettings.h"
|
||||
#include "SWGDemodAnalyzerSettings.h"
|
||||
#include "SWGDenoiserSettings.h"
|
||||
#include "SWGGS232ControllerSettings.h"
|
||||
#include "SWGJogdialControllerSettings.h"
|
||||
#include "SWGLimeRFESettings.h"
|
||||
@ -89,6 +90,9 @@ public:
|
||||
SWGDemodAnalyzerSettings* getDemodAnalyzerSettings();
|
||||
void setDemodAnalyzerSettings(SWGDemodAnalyzerSettings* demod_analyzer_settings);
|
||||
|
||||
SWGDenoiserSettings* getDenoiserSettings();
|
||||
void setDenoiserSettings(SWGDenoiserSettings* denoiser_settings);
|
||||
|
||||
SWGJogdialControllerSettings* getJogdialControllerSettings();
|
||||
void setJogdialControllerSettings(SWGJogdialControllerSettings* jogdial_controller_settings);
|
||||
|
||||
@ -162,6 +166,9 @@ private:
|
||||
SWGDemodAnalyzerSettings* demod_analyzer_settings;
|
||||
bool m_demod_analyzer_settings_isSet;
|
||||
|
||||
SWGDenoiserSettings* denoiser_settings;
|
||||
bool m_denoiser_settings_isSet;
|
||||
|
||||
SWGJogdialControllerSettings* jogdial_controller_settings;
|
||||
bool m_jogdial_controller_settings_isSet;
|
||||
|
||||
|
||||
@ -115,6 +115,8 @@
|
||||
#include "SWGDVSerialDevices.h"
|
||||
#include "SWGDemodAnalyzerActions.h"
|
||||
#include "SWGDemodAnalyzerSettings.h"
|
||||
#include "SWGDenoiserActions.h"
|
||||
#include "SWGDenoiserSettings.h"
|
||||
#include "SWGDeviceActions.h"
|
||||
#include "SWGDeviceConfig.h"
|
||||
#include "SWGDeviceListItem.h"
|
||||
@ -897,6 +899,16 @@ namespace SWGSDRangel {
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGDenoiserActions").compare(type) == 0) {
|
||||
SWGDenoiserActions *obj = new SWGDenoiserActions();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGDenoiserSettings").compare(type) == 0) {
|
||||
SWGDenoiserSettings *obj = new SWGDenoiserSettings();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGDeviceActions").compare(type) == 0) {
|
||||
SWGDeviceActions *obj = new SWGDeviceActions();
|
||||
obj->init();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user