Audio CAT SISO: initial commit

pull/1718/head
f4exb 2023-04-15 18:01:27 +02:00
rodzic 29202a97d0
commit 537653999a
29 zmienionych plików z 6001 dodań i 924 usunięć

Wyświetl plik

@ -16,6 +16,7 @@ if(ENABLE_IIO AND LIBIIO_FOUND)
add_subdirectory(plutosdrmimo)
endif()
add_subdirectory(audiocatsiso)
add_subdirectory(metismiso)
add_subdirectory(testmi)
add_subdirectory(testmosync)

Wyświetl plik

@ -0,0 +1,64 @@
project(audiocatsiso)
set(audiocatsiso_SOURCES
audiocatinputworker.cpp
audiocatoutputworker.cpp
audiocatsiso.cpp
audiocatsisoplugin.cpp
audiocatsisosettings.cpp
audiocatsisowebapiadapter.cpp
)
set(audiocatsiso_HEADERS
audiocatinputworker.h
audiocatoutputworker.h
audiocatsiso.h
audiocatsisoplugin.h
audiocatsisosettings.h
audiocatsisowebapiadapter.h
)
include_directories(
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${CMAKE_SOURCE_DIR}/devices
)
if (NOT SERVER_MODE)
set (audiocatsiso_SOURCES
${audiocatsiso_SOURCES}
audiocatsisogui.cpp
audiocatsisogui.ui
)
set(audiocatsiso_HEADERS
${audiocatsiso_HEADERS}
audiocatsisogui.h
)
set(TARGET_NAME mimoaudiocatsiso)
set(TARGET_LIB "Qt::Widgets")
set(TARGET_LIB_GUI "sdrgui")
set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
else()
set(TARGET_NAME mimoaudiocatsisosrv)
set(TARGET_LIB "")
set(TARGET_LIB_GUI "")
set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR})
endif()
add_library(${TARGET_NAME} SHARED
${audiocatsiso_SOURCES}
)
target_link_libraries(${TARGET_NAME}
Qt::Core
${TARGET_LIB}
sdrbase
${TARGET_LIB_GUI}
swagger
)
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()

Wyświetl plik

@ -0,0 +1,205 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// 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 <stdio.h>
#include <errno.h>
#include "dsp/samplemififo.h"
#include "audio/audiofifo.h"
#include "audiocatinputworker.h"
AudioCATInputWorker::AudioCATInputWorker(SampleMIFifo* sampleFifo, AudioFifo *fifo, QObject* parent) :
QObject(parent),
m_fifo(fifo),
m_running(false),
m_log2Decim(0),
m_iqMapping(AudioCATSISOSettings::IQMapping::L),
m_convertBuffer(m_convBufSamples),
m_sampleFifo(sampleFifo),
m_quNCOPhase(0)
{
}
AudioCATInputWorker::~AudioCATInputWorker()
{
}
void AudioCATInputWorker::startWork()
{
connect(m_fifo, SIGNAL(dataReady()), this, SLOT(handleAudio()));
m_running = true;
}
void AudioCATInputWorker::stopWork()
{
disconnect(m_fifo, SIGNAL(dataReady()), this, SLOT(handleAudio()));
m_running = false;
}
void AudioCATInputWorker::workIQ(unsigned int nbRead)
{
// Map between left and right audio channels and IQ channels
if ((m_iqMapping == AudioCATSISOSettings::IQMapping::L) || // mono
(m_iqMapping == AudioCATSISOSettings::IQMapping::R))
{
for (uint32_t i = 0; i < nbRead; i++)
{
qint16 r = m_buf[i*2 + (m_iqMapping == AudioCATSISOSettings::IQMapping::R ? 1 : 0)]; // real sample
if (m_quNCOPhase == 0) // 0
{
m_buf[i*2] = r; // 1
m_buf[i*2+1] = 0; // 0
m_quNCOPhase = 1; // next phase
}
else if (m_quNCOPhase == 1) // -pi/2
{
m_buf[i*2] = 0; // 0
m_buf[i*2+1] = -r; // -1
m_quNCOPhase = 2; // next phase
}
else if (m_quNCOPhase == 2) // pi or -pi
{
m_buf[i*2] = -r; // -1
m_buf[i*2+1] = 0; // 0
m_quNCOPhase = 3; // next phase
}
else if (m_quNCOPhase == 3) // pi/2
{
m_buf[i*2] = 0; // 0
m_buf[i*2+1] = r; // 1
m_quNCOPhase = 0; // next phase
}
}
}
else if (m_iqMapping == AudioCATSISOSettings::IQMapping::LR) // stereo - reverse
{
for (uint32_t i = 0; i < nbRead; i++)
{
qint16 t = m_buf[i*2];
m_buf[i*2] = m_buf[i*2+1];
m_buf[i*2+1] = t;
}
}
decimate(m_buf, nbRead);
}
void AudioCATInputWorker::decimate(qint16 *buf, unsigned int nbRead)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimatorsIQ.decimate1(&it, buf, 2*nbRead);
}
else
{
if (m_fcPos == 0) // Infradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsIQ.decimate2_inf(&it, buf, 2*nbRead);
break;
case 2:
m_decimatorsIQ.decimate4_inf(&it, buf, 2*nbRead);
break;
case 3:
m_decimatorsIQ.decimate8_inf(&it, buf, 2*nbRead);
break;
case 4:
m_decimatorsIQ.decimate16_inf(&it, buf, 2*nbRead);
break;
case 5:
m_decimatorsIQ.decimate32_inf(&it, buf, 2*nbRead);
break;
case 6:
m_decimatorsIQ.decimate64_inf(&it, buf, 2*nbRead);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsIQ.decimate2_sup(&it, buf, 2*nbRead);
break;
case 2:
m_decimatorsIQ.decimate4_sup(&it, buf, 2*nbRead);
break;
case 3:
m_decimatorsIQ.decimate8_sup(&it, buf, 2*nbRead);
break;
case 4:
m_decimatorsIQ.decimate16_sup(&it, buf, 2*nbRead);
break;
case 5:
m_decimatorsIQ.decimate32_sup(&it, buf, 2*nbRead);
break;
case 6:
m_decimatorsIQ.decimate64_sup(&it, buf, 2*nbRead);
break;
default:
break;
}
}
else // centered
{
switch (m_log2Decim)
{
case 1:
m_decimatorsIQ.decimate2_cen(&it, buf, 2*nbRead);
break;
case 2:
m_decimatorsIQ.decimate4_cen(&it, buf, 2*nbRead);
break;
case 3:
m_decimatorsIQ.decimate8_cen(&it, buf, 2*nbRead);
break;
case 4:
m_decimatorsIQ.decimate16_cen(&it, buf, 2*nbRead);
break;
case 5:
m_decimatorsIQ.decimate32_cen(&it, buf, 2*nbRead);
break;
case 6:
m_decimatorsIQ.decimate64_cen(&it, buf, 2*nbRead);
break;
default:
break;
}
}
}
// qDebug("AudioCATInputWorker::decimate: %ld to write - in: %u", it - m_convertBuffer.begin(), nbRead );
m_sampleFifo->writeAsync(m_convertBuffer.begin(), it - m_convertBuffer.begin(), 0);
}
void AudioCATInputWorker::handleAudio()
{
uint32_t nbRead;
while ((nbRead = m_fifo->read((unsigned char *) m_buf, m_convBufSamples)) != 0) {
workIQ(nbRead);
}
}

Wyświetl plik

@ -0,0 +1,64 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// 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_AUDIOCATINPUTWORKER_H
#define INCLUDE_AUDIOCATINPUTWORKER_H
#include <QObject>
#include "dsp/decimators.h"
#include "audiocatsisosettings.h"
class AudioFifo;
class SampleMIFifo;
class AudioCATInputWorker : public QObject {
Q_OBJECT
public:
AudioCATInputWorker(SampleMIFifo* sampleFifo, AudioFifo *fifo, QObject* parent = nullptr);
~AudioCATInputWorker();
void startWork();
void stopWork();
void setLog2Decimation(unsigned int log2_decim) {m_log2Decim = log2_decim;}
void setFcPos(int fcPos) { m_fcPos = fcPos; }
void setIQMapping(AudioCATSISOSettings::IQMapping iqMapping) {m_iqMapping = iqMapping;}
static const int m_convBufSamples = 4096;
private:
AudioFifo* m_fifo;
bool m_running;
unsigned int m_log2Decim;
int m_fcPos;
AudioCATSISOSettings::IQMapping m_iqMapping;
qint16 m_buf[m_convBufSamples*2]; // stereo (I, Q)
SampleVector m_convertBuffer;
SampleMIFifo* m_sampleFifo;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16, true> m_decimatorsIQ;
int m_quNCOPhase; //!< Quarter sample rate pseudo NCO phase index (0, 90, 180, 270)
void workIQ(unsigned int nbRead);
void decimate(qint16 *buf, unsigned int nbRead);
private slots:
void handleAudio();
};
#endif // INCLUDE_AUDIOCATINPUTWORKER_H

Wyświetl plik

@ -0,0 +1,158 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// //
// 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 <QTimer>
#include <QDebug>
#include "dsp/samplemofifo.h"
#include "dsp/samplesourcefifo.h"
#include "audio/audiofifo.h"
#include "audiocatoutputworker.h"
#define AUDIOOUTPUT_THROTTLE_MS 50
AudioCATOutputWorker::AudioCATOutputWorker(SampleMOFifo* sampleFifo, AudioFifo *fifo, QObject* parent) :
QObject(parent),
m_running(false),
m_samplerate(0),
m_throttlems(AUDIOOUTPUT_THROTTLE_MS),
m_maxThrottlems(50),
m_throttleToggle(false),
m_iqMapping(AudioCATSISOSettings::IQMapping::LR),
m_buf(nullptr),
m_samplesChunkSize(0),
m_sampleFifo(sampleFifo),
m_audioFifo(fifo)
{
m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0;
}
AudioCATOutputWorker::~AudioCATOutputWorker()
{
}
void AudioCATOutputWorker::startWork()
{
qDebug("AudioCATOutputWorker::startWork");
m_running = true;
}
void AudioCATOutputWorker::stopWork()
{
qDebug("AudioCATOutputWorker::stopWork");
m_running = false;
}
void AudioCATOutputWorker::connectTimer(const QTimer& timer)
{
qDebug() << "AudioCATOutputWorker::connectTimer";
connect(&timer, SIGNAL(timeout()), this, SLOT(tick()));
}
void AudioCATOutputWorker::setSamplerate(int samplerate)
{
if (samplerate != m_samplerate)
{
bool wasRunning = false;
if (m_running)
{
stopWork();
wasRunning = true;
}
// resize sample FIFO
if (m_sampleFifo) {
m_sampleFifo->init(1, SampleSourceFifo::getSizePolicy(samplerate)); // 1s buffer
}
qDebug() << "AudioCATOutputWorker::setSamplerate:"
<< " new:" << samplerate
<< " old:" << m_samplerate
<< " m_sampleFifo size:" << SampleSourceFifo::getSizePolicy(samplerate)
<< " m_audioFifo size:" << m_audioFifo->size()
<< " sample i/q size" << sizeof(FixReal);
// resize output buffer
if (m_buf) {
delete[] m_buf;
}
m_buf = new int16_t[samplerate*2];
m_samplerate = samplerate;
m_samplesChunkSize = (m_samplerate * m_throttlems) / 1000;
if (wasRunning) {
startWork();
}
}
}
void AudioCATOutputWorker::tick()
{
if (m_running)
{
qint64 throttlems = m_elapsedTimer.restart();
if (throttlems != m_throttlems)
{
m_throttlems = throttlems;
m_samplesChunkSize = (m_samplerate * (m_throttlems+(m_throttleToggle ? 1 : 0))) / 1000;
m_throttleToggle = !m_throttleToggle;
}
unsigned int iPart1Begin, iPart1End, iPart2Begin, iPart2End;
SampleVector& data = m_sampleFifo->getData(0);
m_sampleFifo->readAsync(m_samplesChunkSize, iPart1Begin, iPart1End, iPart2Begin, iPart2End, 0);
if (iPart1Begin != iPart1End) {
callbackPart(data, iPart1Begin, iPart1End);
}
if (iPart2Begin != iPart2End) {
callbackPart(data, iPart2Begin, iPart2End);
}
// qDebug("AudioCATOutputWorker::tick: %d samples fill: %u", m_samplesChunkSize, m_audioFifo->fill());
}
}
void AudioCATOutputWorker::callbackPart(SampleVector& data, unsigned int iBegin, unsigned int iEnd)
{
for (unsigned int i = iBegin; i < iEnd; i++)
{
m_audioBuffer[m_audioBufferFill].l = m_iqMapping == AudioCATSISOSettings::LR ? data[i].m_real : data[i].m_imag;
m_audioBuffer[m_audioBufferFill].r = m_iqMapping == AudioCATSISOSettings::LR ? data[i].m_imag : data[i].m_real;
m_audioBufferFill++;
if (m_audioBufferFill >= m_audioBuffer.size())
{
uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill);
if (res != m_audioBufferFill)
{
qDebug("AudioCATOutputWorker::callbackPart: %u/%u audio samples written", res, m_audioBufferFill);
m_audioFifo->clear();
}
m_audioBufferFill = 0;
}
}
}

Wyświetl plik

@ -0,0 +1,66 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// //
// 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_AUDIOCATOUTPUTWORKER_H
#define INCLUDE_AUDIOCATOUTPUTWORKER_H
#include <QObject>
#include <QElapsedTimer>
#include "dsp/interpolators.h"
#include "audiocatsisosettings.h"
class QTimer;
class SampleMOFifo;
class AudioFifo;
class AudioCATOutputWorker : public QObject {
Q_OBJECT
public:
AudioCATOutputWorker(SampleMOFifo* sampleFifo, AudioFifo *fifo, QObject* parent = nullptr);
~AudioCATOutputWorker();
void startWork();
void stopWork();
void setSamplerate(int samplerate);
void setIQMapping(AudioCATSISOSettings::IQMapping iqMapping) {m_iqMapping = iqMapping;}
void connectTimer(const QTimer& timer);
private:
bool m_running;
int m_samplerate;
int m_throttlems;
int m_maxThrottlems;
QElapsedTimer m_elapsedTimer;
bool m_throttleToggle;
AudioCATSISOSettings::IQMapping m_iqMapping;
AudioVector m_audioBuffer;
uint32_t m_audioBufferFill;
qint16 *m_buf; // stereo (I, Q)
unsigned int m_samplesChunkSize;
SampleMOFifo* m_sampleFifo;
AudioFifo* m_audioFifo;
Interpolators<qint16, SDR_TX_SAMP_SZ, 16> m_interpolators;
void callbackPart(SampleVector& data, unsigned int iBegin, unsigned int iEnd);
private slots:
void tick();
};
#endif // INCLUDE_AUDIOCATOUTPUTWORKER_H

Wyświetl plik

@ -0,0 +1,838 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB //
// Copyright (C) 2020 Jon Beniston, M7RCE //
// //
// 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 <string.h>
#include <errno.h>
#include <QDebug>
#include <QNetworkReply>
#include <QBuffer>
#include <QThread>
#include "SWGDeviceSettings.h"
#include "SWGDeviceState.h"
#include "dsp/dspcommands.h"
#include "dsp/dspengine.h"
#include "dsp/samplesourcefifo.h"
#include "dsp/samplesinkfifo.h"
#include "dsp/devicesamplesource.h"
#include "dsp/devicesamplesink.h"
#include "device/deviceapi.h"
#include "audiocatsiso.h"
#include "audiocatinputworker.h"
#include "audiocatoutputworker.h"
MESSAGE_CLASS_DEFINITION(AudioCATSISO::MsgConfigureAudioCATSISO, Message)
MESSAGE_CLASS_DEFINITION(AudioCATSISO::MsgStartStop, Message)
AudioCATSISO::AudioCATSISO(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_inputFifo(48000),
m_outputFifo(48000),
m_settings(),
m_inputWorker(nullptr),
m_outputWorker(nullptr),
m_inputWorkerThread(nullptr),
m_outputWorkerThread(nullptr),
m_deviceDescription("AudioCATSISO"),
m_rxRunning(false),
m_rxAudioDeviceIndex(-1),
m_txRunning(false),
m_txAudioDeviceIndex(-1),
m_masterTimer(deviceAPI->getMasterTimer())
{
m_mimoType = MIMOAsynchronous;
m_deviceAPI->setNbSourceStreams(1);
m_deviceAPI->setNbSinkStreams(1);
m_inputFifo.setLabel("Input");
m_outputFifo.setLabel("Output");
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
m_rxSampleRate = audioDeviceManager->getInputSampleRate(m_rxAudioDeviceIndex);
m_settings.m_rxDeviceName = AudioDeviceManager::m_defaultDeviceName;
m_sampleMIFifo.init(1, SampleSinkFifo::getSizePolicy(m_rxSampleRate));
m_txSampleRate = audioDeviceManager->getOutputSampleRate(m_txAudioDeviceIndex);
m_settings.m_txDeviceName = AudioDeviceManager::m_defaultDeviceName;
m_sampleMOFifo.init(1, SampleSourceFifo::getSizePolicy(m_txSampleRate));
m_networkManager = new QNetworkAccessManager();
QObject::connect(
m_networkManager,
&QNetworkAccessManager::finished,
this,
&AudioCATSISO::networkManagerFinished
);
}
AudioCATSISO::~AudioCATSISO()
{
QObject::disconnect(
m_networkManager,
&QNetworkAccessManager::finished,
this,
&AudioCATSISO::networkManagerFinished
);
delete m_networkManager;
if (m_rxRunning) {
stopRx();
}
if (m_txRunning) {
stopTx();
}
}
void AudioCATSISO::destroy()
{
delete this;
}
void AudioCATSISO::init()
{
applySettings(m_settings, QList<QString>(), true);
}
bool AudioCATSISO::startRx()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_rxRunning) {
return true;
}
qDebug() << "AudioCATSISO::startRx";
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
audioDeviceManager->addAudioSource(&m_inputFifo, getInputMessageQueue(), m_rxAudioDeviceIndex);
m_inputWorkerThread = new QThread();
m_inputWorker = new AudioCATInputWorker(&m_sampleMIFifo, &m_inputFifo);
m_inputWorker->moveToThread(m_inputWorkerThread);
QObject::connect(m_inputWorkerThread, &QThread::started, m_inputWorker, &AudioCATInputWorker::startWork);
QObject::connect(m_inputWorkerThread, &QThread::finished, m_inputWorker, &QObject::deleteLater);
QObject::connect(m_inputWorkerThread, &QThread::finished, m_inputWorkerThread, &QThread::deleteLater);
m_inputWorker->setLog2Decimation(m_settings.m_log2Decim);
m_inputWorker->setFcPos(m_settings.m_fcPosRx);
m_inputWorker->setIQMapping(m_settings.m_rxIQMapping);
m_inputWorker->startWork();
m_inputWorkerThread->start();
qDebug("AudioCATSISO::startRx: started");
m_rxRunning = true;
return true;
}
bool AudioCATSISO::startTx()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_txRunning) {
return true;
}
qDebug("AudioCATSISO::startTx");
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
audioDeviceManager->addAudioSink(&m_outputFifo, getInputMessageQueue(), m_txAudioDeviceIndex);
m_outputWorkerThread = new QThread();
m_outputWorker = new AudioCATOutputWorker(&m_sampleMOFifo, &m_outputFifo);
m_outputWorker->moveToThread(m_outputWorkerThread);
QObject::connect(m_outputWorkerThread, &QThread::started, m_outputWorker, &AudioCATOutputWorker::startWork);
QObject::connect(m_outputWorkerThread, &QThread::finished, m_outputWorker, &QObject::deleteLater);
QObject::connect(m_outputWorkerThread, &QThread::finished, m_outputWorkerThread, &QThread::deleteLater);
m_outputWorker->setSamplerate(m_txSampleRate);
m_outputWorker->setIQMapping(m_settings.m_txIQMapping);
m_outputWorker->connectTimer(m_deviceAPI->getMasterTimer());
m_outputWorkerThread->start();
m_txRunning = true;
mutexLocker.unlock();
qDebug("AudioCATSISO::startTx: started");
return true;
}
void AudioCATSISO::stopRx()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_rxRunning) {
return;
}
qDebug("AudioCATSISO::stopRx");
m_rxRunning = false;
if (m_inputWorkerThread)
{
m_inputWorkerThread->quit();
m_inputWorkerThread->wait();
m_inputWorkerThread = nullptr;
m_inputWorker = nullptr;
}
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
audioDeviceManager->removeAudioSource(&m_inputFifo);
qDebug("AudioCATSISO::stopRx: stopped");
}
void AudioCATSISO::stopTx()
{
if (!m_txRunning) {
return;
}
qDebug("AudioCATSISO::stopTx");
m_txRunning = false;
if (m_outputWorkerThread)
{
m_outputWorker->stopWork();
m_outputWorkerThread->quit();
m_outputWorkerThread->wait();
m_outputWorker = nullptr;
m_outputWorkerThread = nullptr;
}
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
audioDeviceManager->removeAudioSink(&m_outputFifo);
qDebug("AudioCATSISO::stopTx: stopped");
}
QByteArray AudioCATSISO::serialize() const
{
return m_settings.serialize();
}
bool AudioCATSISO::deserialize(const QByteArray& data)
{
bool success = true;
if (!m_settings.deserialize(data))
{
m_settings.resetToDefaults();
success = false;
}
MsgConfigureAudioCATSISO* message = MsgConfigureAudioCATSISO::create(m_settings, QList<QString>(), true);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue)
{
MsgConfigureAudioCATSISO* messageToGUI = MsgConfigureAudioCATSISO::create(m_settings, QList<QString>(), true);
m_guiMessageQueue->push(messageToGUI);
}
return success;
}
const QString& AudioCATSISO::getDeviceDescription() const
{
return m_deviceDescription;
}
int AudioCATSISO::getSourceSampleRate(int) const
{
return m_rxSampleRate / (1<<m_settings.m_log2Decim);
}
quint64 AudioCATSISO::getSourceCenterFrequency(int) const
{
return m_settings.m_rxCenterFrequency;
}
void AudioCATSISO::setSourceCenterFrequency(qint64 centerFrequency, int)
{
AudioCATSISOSettings settings = m_settings;
settings.m_rxCenterFrequency = centerFrequency;
MsgConfigureAudioCATSISO* message = MsgConfigureAudioCATSISO::create(settings, QList<QString>{"rxCenterFrequency"}, false);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue)
{
MsgConfigureAudioCATSISO* messageToGUI = MsgConfigureAudioCATSISO::create(settings, QList<QString>{"rxCenterFrequency"}, false);
m_guiMessageQueue->push(messageToGUI);
}
}
int AudioCATSISO::getSinkSampleRate(int) const
{
return m_txSampleRate;
}
quint64 AudioCATSISO::getSinkCenterFrequency(int) const
{
return m_settings.m_txCenterFrequency;
}
void AudioCATSISO::setSinkCenterFrequency(qint64 centerFrequency, int)
{
AudioCATSISOSettings settings = m_settings;
settings.m_txCenterFrequency = centerFrequency;
MsgConfigureAudioCATSISO* message = MsgConfigureAudioCATSISO::create(settings, QList<QString>{"txCenterFrequency"}, false);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue)
{
MsgConfigureAudioCATSISO* messageToGUI = MsgConfigureAudioCATSISO::create(settings, QList<QString>{"txCenterFrequency"}, false);
m_guiMessageQueue->push(messageToGUI);
}
}
bool AudioCATSISO::handleMessage(const Message& message)
{
if (MsgConfigureAudioCATSISO::match(message))
{
qDebug() << "AudioCATSISO::handleMessage: MsgConfigureAudioCATSISO";
MsgConfigureAudioCATSISO& conf = (MsgConfigureAudioCATSISO&) message;
applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce());
return true;
}
else if (MsgStartStop::match(message))
{
MsgStartStop& cmd = (MsgStartStop&) message;
qDebug() << "AudioCATSISO::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
if (cmd.getStartStop())
{
if (m_deviceAPI->initDeviceEngine(0)) {
m_deviceAPI->startDeviceEngine(0);
}
if (m_settings.m_txEnable)
{
if (m_deviceAPI->initDeviceEngine(1)) {
m_deviceAPI->startDeviceEngine(1);
}
}
}
else
{
m_deviceAPI->stopDeviceEngine(0);
m_deviceAPI->stopDeviceEngine(1);
}
if (m_settings.m_useReverseAPI) {
webapiReverseSendStartStop(cmd.getStartStop());
}
return true;
}
else
{
return false;
}
}
void AudioCATSISO::applySettings(const AudioCATSISOSettings& settings, const QList<QString>& settingsKeys, bool force)
{
bool forwardRxChange = false;
bool forwardTxChange = false;
qDebug() << "AudioCATSISO::applySettings: "
<< " force:" << force
<< settings.getDebugString(settingsKeys, force);
if (settingsKeys.contains("rxDeviceName") || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
m_rxAudioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_rxDeviceName);
m_rxSampleRate = audioDeviceManager->getInputSampleRate(m_rxAudioDeviceIndex);
forwardRxChange = true;
if (m_rxRunning)
{
audioDeviceManager->removeAudioSource(&m_inputFifo);
audioDeviceManager->addAudioSource(&m_inputFifo, getInputMessageQueue(), m_rxAudioDeviceIndex);
}
}
if (settingsKeys.contains("txDeviceName") || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
m_txAudioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_txDeviceName);
m_txSampleRate = audioDeviceManager->getOutputSampleRate(m_txAudioDeviceIndex);
forwardTxChange = true;
if (m_txRunning)
{
audioDeviceManager->removeAudioSink(&m_outputFifo);
audioDeviceManager->addAudioSink(&m_outputFifo, getInputMessageQueue(), m_txAudioDeviceIndex);
}
}
if (settingsKeys.contains("rxVolume") || force)
{
m_audioInput.setVolume(settings.m_rxVolume);
qDebug() << "AudioCATSISO::applySettings: set Rx volume to " << settings.m_rxVolume;
}
if (settingsKeys.contains("txVolume") || force)
{
m_audioOutput.setVolume(settings.m_txVolume);
qDebug() << "AudioCATSISO::applySettings: set Tx volume to " << settings.m_txVolume;
}
if (settingsKeys.contains("log2Decim") || force)
{
forwardRxChange = true;
if (m_rxRunning)
{
m_inputWorker->setLog2Decimation(settings.m_log2Decim);
qDebug() << "AudioCATSISO::applySettings: set decimation to " << (1<<settings.m_log2Decim);
}
}
if (settingsKeys.contains("fcPosRx") || force)
{
if (m_inputWorker) {
m_inputWorker->setFcPos((int) settings.m_fcPosRx);
}
qDebug() << "AudioCATSISO::applySettings: set Rx fc pos (enum) to " << (int) settings.m_fcPosRx;
}
if (settingsKeys.contains("rxIQMapping") || force)
{
if (m_rxRunning) {
m_inputWorker->setIQMapping(settings.m_rxIQMapping);
}
}
if (settingsKeys.contains("txIQMapping") || force)
{
if (m_txRunning) {
m_outputWorker->setIQMapping(settings.m_txIQMapping);
}
}
if (settingsKeys.contains("dcBlock") || settingsKeys.contains("iqCorrection") || force)
{
m_deviceAPI->configureCorrections(settings.m_dcBlock, settings.m_iqCorrection);
qDebug("AudioInput::applySettings: corrections: DC block: %s IQ imbalance: %s",
settings.m_dcBlock ? "true" : "false",
settings.m_iqCorrection ? "true" : "false");
}
if (settingsKeys.contains("rxCenterFrequency") || force)
{
// TBD with CAT
forwardRxChange = true;
}
if (settingsKeys.contains("txCenterFrequency") || force)
{
// TBD with CAT
forwardTxChange = true;
}
if (settingsKeys.contains("useReverseAPI"))
{
bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) ||
settingsKeys.contains("reverseAPIAddress") ||
settingsKeys.contains("reverseAPIPort") ||
settingsKeys.contains("reverseAPIDeviceIndex");
webapiReverseSendSettings(settingsKeys, settings, fullUpdate || force);
}
if (force) {
m_settings = settings;
} else {
m_settings.applySettings(settingsKeys, settings);
}
if (forwardRxChange)
{
int sampleRate = m_rxSampleRate / (1<<m_settings.m_log2Decim);
DSPMIMOSignalNotification *notif = new DSPMIMOSignalNotification(sampleRate, settings.m_rxCenterFrequency, true, 0);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
if (forwardTxChange)
{
if (m_txRunning) {
m_outputWorker->setSamplerate(m_txSampleRate);
}
DSPMIMOSignalNotification *notif = new DSPMIMOSignalNotification(m_txSampleRate, settings.m_txCenterFrequency, false, 0);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
}
int AudioCATSISO::webapiRunGet(
int subsystemIndex,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage
)
{
(void) subsystemIndex;
(void) errorMessage;
m_deviceAPI->getDeviceEngineStateStr(*response.getState());
return 200;
}
int AudioCATSISO::webapiRun(
bool run,
int subsystemIndex,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage
)
{
(void) subsystemIndex;
(void) errorMessage;
m_deviceAPI->getDeviceEngineStateStr(*response.getState());
MsgStartStop *message = MsgStartStop::create(run);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgStartStop *msgToGUI = MsgStartStop::create(run);
m_guiMessageQueue->push(msgToGUI);
}
return 200;
}
int AudioCATSISO::webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage
)
{
(void) errorMessage;
response.setAudioInputSettings(new SWGSDRangel::SWGAudioInputSettings());
response.getAudioInputSettings()->init();
webapiFormatDeviceSettings(response, m_settings);
return 200;
}
int AudioCATSISO::webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage
)
{
(void) errorMessage;
AudioCATSISOSettings settings = m_settings;
webapiUpdateDeviceSettings(settings, deviceSettingsKeys, response);
MsgConfigureAudioCATSISO *msg = MsgConfigureAudioCATSISO::create(settings, deviceSettingsKeys, force);
m_inputMessageQueue.push(msg);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgConfigureAudioCATSISO *msgToGUI = MsgConfigureAudioCATSISO::create(settings, deviceSettingsKeys, force);
m_guiMessageQueue->push(msgToGUI);
}
webapiFormatDeviceSettings(response, settings);
return 200;
}
void AudioCATSISO::webapiUpdateDeviceSettings(
AudioCATSISOSettings& settings,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response)
{
if (deviceSettingsKeys.contains("rxCenterFrequency")) {
settings.m_rxCenterFrequency = response.getAudioCatsisoSettings()->getRxCenterFrequency();
}
if (deviceSettingsKeys.contains("txCenterFrequency")) {
settings.m_txCenterFrequency = response.getAudioCatsisoSettings()->getTxCenterFrequency();
}
if (deviceSettingsKeys.contains("transverterMode")) {
settings.m_transverterMode = response.getAudioCatsisoSettings()->getTransverterMode() != 0;
}
if (deviceSettingsKeys.contains("transverterDeltaFrequency")) {
settings.m_transverterDeltaFrequency = response.getAudioCatsisoSettings()->getTransverterDeltaFrequency();
}
if (deviceSettingsKeys.contains("iqOrder")) {
settings.m_iqOrder = response.getAudioCatsisoSettings()->getIqOrder() != 0;
}
if (deviceSettingsKeys.contains("spectrumStreamIndex")) {
settings.m_spectrumStreamIndex = response.getAudioCatsisoSettings()->getSpectrumStreamIndex();
}
if (deviceSettingsKeys.contains("streamIndex")) {
settings.m_streamIndex = response.getAudioCatsisoSettings()->getStreamIndex();
}
if (deviceSettingsKeys.contains("rxDeviceName")) {
settings.m_rxDeviceName = *response.getAudioCatsisoSettings()->getRxDeviceName();
}
if (deviceSettingsKeys.contains("rxIQMapping")) {
settings.m_rxIQMapping = (AudioCATSISOSettings::IQMapping)response.getAudioCatsisoSettings()->getRxIqMapping();
}
if (deviceSettingsKeys.contains("log2Decim")) {
settings.m_log2Decim = response.getAudioCatsisoSettings()->getLog2Decim();
}
if (deviceSettingsKeys.contains("fcPosRx")) {
settings.m_fcPosRx = (AudioCATSISOSettings::fcPos_t) response.getAudioCatsisoSettings()->getFcPosRx();
}
if (deviceSettingsKeys.contains("dcBlock")) {
settings.m_dcBlock = response.getAudioCatsisoSettings()->getDcBlock() != 0;
}
if (deviceSettingsKeys.contains("iqCorrection")) {
settings.m_iqCorrection = response.getAudioCatsisoSettings()->getIqCorrection() != 0;
}
if (deviceSettingsKeys.contains("rxVolume")) {
settings.m_rxVolume = response.getAudioCatsisoSettings()->getRxVolume();
}
if (deviceSettingsKeys.contains("txDeviceName")) {
settings.m_txDeviceName = *response.getAudioCatsisoSettings()->getTxDeviceName();
}
if (deviceSettingsKeys.contains("txIQMapping")) {
settings.m_txIQMapping = (AudioCATSISOSettings::IQMapping)response.getAudioCatsisoSettings()->getTxIqMapping();
}
if (deviceSettingsKeys.contains("log2Interp")) {
settings.m_log2Interp = response.getAudioCatsisoSettings()->getLog2Interp();
}
if (deviceSettingsKeys.contains("fcPosTx")) {
settings.m_fcPosTx = (AudioCATSISOSettings::fcPos_t) response.getAudioCatsisoSettings()->getFcPosTx();
}
if (deviceSettingsKeys.contains("txVolume")) {
settings.m_txVolume = response.getAudioCatsisoSettings()->getTxVolume();
}
if (deviceSettingsKeys.contains("streamIndex")) {
settings.m_streamIndex = response.getAudioCatsisoSettings()->getStreamIndex();
}
if (deviceSettingsKeys.contains("spectrumStreamIndex")) {
settings.m_spectrumStreamIndex = response.getAudioCatsisoSettings()->getSpectrumStreamIndex();
}
if (deviceSettingsKeys.contains("txEnable")) {
settings.m_txEnable = response.getAudioCatsisoSettings()->getTxEnable() != 0;
}
if (deviceSettingsKeys.contains("useReverseAPI")) {
settings.m_useReverseAPI = response.getAudioCatsisoSettings()->getUseReverseApi() != 0;
}
if (deviceSettingsKeys.contains("reverseAPIAddress")) {
settings.m_reverseAPIAddress = *response.getAudioCatsisoSettings()->getReverseApiAddress();
}
if (deviceSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getAudioCatsisoSettings()->getReverseApiPort();
}
if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getAudioCatsisoSettings()->getReverseApiDeviceIndex();
}
}
void AudioCATSISO::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const AudioCATSISOSettings& settings)
{
response.getAudioCatsisoSettings()->setRxCenterFrequency(settings.m_rxCenterFrequency);
response.getAudioCatsisoSettings()->setTxCenterFrequency(settings.m_txCenterFrequency);
response.getAudioCatsisoSettings()->setIqCorrection(settings.m_iqCorrection ? 1 : 0);
response.getAudioCatsisoSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency);
response.getAudioCatsisoSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0);
response.getAudioCatsisoSettings()->setSpectrumStreamIndex(settings.m_spectrumStreamIndex);
response.getAudioCatsisoSettings()->setStreamIndex(settings.m_streamIndex);
response.getAudioCatsisoSettings()->setRxDeviceName(new QString(settings.m_rxDeviceName));
response.getAudioCatsisoSettings()->setRxIqMapping((int)settings.m_rxIQMapping);
response.getAudioCatsisoSettings()->setLog2Decim(settings.m_log2Decim);
response.getAudioCatsisoSettings()->setFcPosRx((int) settings.m_fcPosRx);
response.getAudioCatsisoSettings()->setDcBlock(settings.m_dcBlock ? 1 : 0);
response.getAudioCatsisoSettings()->setIqCorrection(settings.m_iqCorrection ? 1 : 0);
response.getAudioCatsisoSettings()->setRxVolume(settings.m_rxVolume);
response.getAudioCatsisoSettings()->setTxDeviceName(new QString(settings.m_txDeviceName));
response.getAudioCatsisoSettings()->setTxIqMapping((int)settings.m_txIQMapping);
response.getAudioCatsisoSettings()->setLog2Interp(settings.m_log2Interp);
response.getAudioCatsisoSettings()->setFcPosTx((int) settings.m_fcPosTx);
response.getAudioCatsisoSettings()->setTxVolume(settings.m_txVolume);
response.getAudioCatsisoSettings()->setStreamIndex(settings.m_streamIndex);
response.getAudioCatsisoSettings()->setSpectrumStreamIndex(settings.m_spectrumStreamIndex);
response.getAudioCatsisoSettings()->setTxEnable(settings.m_txEnable ? 1 : 0);
response.getAudioCatsisoSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
if (response.getAudioCatsisoSettings()->getReverseApiAddress()) {
*response.getAudioCatsisoSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress;
} else {
response.getAudioCatsisoSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
}
response.getAudioCatsisoSettings()->setReverseApiPort(settings.m_reverseAPIPort);
response.getAudioCatsisoSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
}
void AudioCATSISO::webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const AudioCATSISOSettings& settings, bool force)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("AudioCATSISO"));
swgDeviceSettings->setAudioCatsisoSettings(new SWGSDRangel::SWGAudioCATSISOSettings());
SWGSDRangel::SWGAudioCATSISOSettings *swgAudioCATSISOSettings = swgDeviceSettings->getAudioCatsisoSettings();
// transfer data that has been modified. When force is on transfer all data except reverse API data
if (deviceSettingsKeys.contains("rxCenterFrequency")) {
swgAudioCATSISOSettings->setRxCenterFrequency(settings.m_rxCenterFrequency);
}
if (deviceSettingsKeys.contains("txCenterFrequency")) {
swgAudioCATSISOSettings->setTxCenterFrequency(settings.m_txCenterFrequency);
}
if (deviceSettingsKeys.contains("transverterMode")) {
swgAudioCATSISOSettings->setTransverterMode(settings.m_transverterMode ? 1 : 0);
}
if (deviceSettingsKeys.contains("transverterDeltaFrequency")) {
swgAudioCATSISOSettings->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency);
}
if (deviceSettingsKeys.contains("iqOrder")) {
swgAudioCATSISOSettings->setIqOrder(settings.m_iqOrder ? 1 : 0);
}
if (deviceSettingsKeys.contains("spectrumStreamIndex")) {
swgAudioCATSISOSettings->setSpectrumStreamIndex(settings.m_spectrumStreamIndex);
}
if (deviceSettingsKeys.contains("streamIndex")) {
swgAudioCATSISOSettings->setStreamIndex(settings.m_streamIndex);
}
if (deviceSettingsKeys.contains("rxDeviceName") || force) {
swgAudioCATSISOSettings->setRxDeviceName(new QString(settings.m_rxDeviceName));
}
if (deviceSettingsKeys.contains("rxIQMapping")) {
swgAudioCATSISOSettings->setRxIqMapping((int) settings.m_rxIQMapping);
}
if (deviceSettingsKeys.contains("log2Decim")) {
swgAudioCATSISOSettings->setLog2Decim(settings.m_log2Decim);
}
if (deviceSettingsKeys.contains("fcPosRx")) {
swgAudioCATSISOSettings->setFcPosRx((int) settings.m_fcPosRx);
}
if (deviceSettingsKeys.contains("dcBlock")) {
swgAudioCATSISOSettings->setDcBlock(settings.m_dcBlock ? 1 : 0);
}
if (deviceSettingsKeys.contains("iqCorrection")) {
swgAudioCATSISOSettings->setIqCorrection(settings.m_iqCorrection ? 1 : 0);
}
if (deviceSettingsKeys.contains("rxVolume")) {
swgAudioCATSISOSettings->setRxVolume(settings.m_rxVolume);
}
if (deviceSettingsKeys.contains("txDeviceName")) {
swgAudioCATSISOSettings->setTxDeviceName(new QString(settings.m_txDeviceName));
}
if (deviceSettingsKeys.contains("txIQMapping")) {
swgAudioCATSISOSettings->setTxIqMapping((int) settings.m_txIQMapping);
}
if (deviceSettingsKeys.contains("log2Interp")) {
swgAudioCATSISOSettings->setLog2Interp(settings.m_log2Interp);
}
if (deviceSettingsKeys.contains("fcPosTx")) {
swgAudioCATSISOSettings->setFcPosTx((int) settings.m_fcPosTx);
}
if (deviceSettingsKeys.contains("txVolume")) {
swgAudioCATSISOSettings->setTxVolume(settings.m_txVolume);
}
if (deviceSettingsKeys.contains("streamIndex")) {
swgAudioCATSISOSettings->setStreamIndex(settings.m_streamIndex);
}
if (deviceSettingsKeys.contains("spectrumStreamIndex")) {
swgAudioCATSISOSettings->setSpectrumStreamIndex(settings.m_spectrumStreamIndex);
}
if (deviceSettingsKeys.contains("txEnable")) {
swgAudioCATSISOSettings->setTxEnable(settings.m_txEnable ? 1 : 0);
}
QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings")
.arg(settings.m_reverseAPIAddress)
.arg(settings.m_reverseAPIPort)
.arg(settings.m_reverseAPIDeviceIndex);
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
buffer->write(swgDeviceSettings->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 swgDeviceSettings;
}
void AudioCATSISO::webapiReverseSendStartStop(bool start)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("AudioCATSISO"));
QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run")
.arg(m_settings.m_reverseAPIAddress)
.arg(m_settings.m_reverseAPIPort)
.arg(m_settings.m_reverseAPIDeviceIndex);
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
QNetworkReply *reply;
if (start) {
reply = m_networkManager->sendCustomRequest(m_networkRequest, "POST", buffer);
} else {
reply = m_networkManager->sendCustomRequest(m_networkRequest, "DELETE", buffer);
}
buffer->setParent(reply);
delete swgDeviceSettings;
}
void AudioCATSISO::networkManagerFinished(QNetworkReply *reply)
{
QNetworkReply::NetworkError replyError = reply->error();
if (replyError)
{
qWarning() << "AudioCATSISO::networkManagerFinished:"
<< " error(" << (int) replyError
<< "): " << replyError
<< ": " << reply->errorString();
}
else
{
QString answer = reply->readAll();
answer.chop(1); // remove last \n
qDebug("AudioCATSISO::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
}
reply->deleteLater();
}

Wyświetl plik

@ -0,0 +1,187 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// 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 _AUDIOCATSISO_AUDIOCATSISO_H_
#define _AUDIOCATSISO_AUDIOCATSISO_H_
#include <QString>
#include <QByteArray>
#include <QTimer>
#include <QNetworkRequest>
#include <QThread>
#include "dsp/devicesamplemimo.h"
#include "audio/audioinputdevice.h"
#include "audio/audiooutputdevice.h"
#include "audio/audiofifo.h"
#include "audiocatsisosettings.h"
class DeviceAPI;
class QNetworkAccessManager;
class QNetworkReply;
class QThread;
class AudioCATInputWorker;
class AudioCATOutputWorker;
class AudioCATSISO : public DeviceSampleMIMO {
Q_OBJECT
public:
class MsgConfigureAudioCATSISO : public Message {
MESSAGE_CLASS_DECLARATION
public:
const AudioCATSISOSettings& getSettings() const { return m_settings; }
const QList<QString>& getSettingsKeys() const { return m_settingsKeys; }
bool getForce() const { return m_force; }
static MsgConfigureAudioCATSISO* create(const AudioCATSISOSettings& settings, const QList<QString>& settingsKeys, bool force) {
return new MsgConfigureAudioCATSISO(settings, settingsKeys, force);
}
private:
AudioCATSISOSettings m_settings;
QList<QString> m_settingsKeys;
bool m_force;
MsgConfigureAudioCATSISO(const AudioCATSISOSettings& 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)
{ }
};
AudioCATSISO(DeviceAPI *deviceAPI);
virtual ~AudioCATSISO();
virtual void destroy();
virtual void init();
virtual bool startRx();
virtual void stopRx();
virtual bool startTx();
virtual void stopTx();
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
virtual const QString& getDeviceDescription() const;
const QString& getInputDeviceName() { return m_settings.m_rxDeviceName; }
virtual int getSourceSampleRate(int index) const;
virtual void setSourceSampleRate(int sampleRate, int index) { (void) sampleRate; (void) index; }
virtual quint64 getSourceCenterFrequency(int index) const;
virtual void setSourceCenterFrequency(qint64 centerFrequency, int index);
const QString& getOutputDeviceName() { return m_settings.m_txDeviceName; }
virtual int getSinkSampleRate(int index) const;
virtual void setSinkSampleRate(int sampleRate, int index) { (void) sampleRate; (void) index; }
virtual quint64 getSinkCenterFrequency(int index) const;
virtual void setSinkCenterFrequency(qint64 centerFrequency, int index);
virtual quint64 getMIMOCenterFrequency() const { return getSourceCenterFrequency(0); }
virtual unsigned int getMIMOSampleRate() const { return getSourceSampleRate(0); }
virtual bool handleMessage(const Message& message);
virtual int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
virtual int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage);
virtual int webapiRunGet(
int subsystemIndex,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
virtual int webapiRun(
bool run,
int subsystemIndex,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
static void webapiFormatDeviceSettings(
SWGSDRangel::SWGDeviceSettings& response,
const AudioCATSISOSettings& settings);
static void webapiUpdateDeviceSettings(
AudioCATSISOSettings& settings,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response);
private:
struct DeviceSettingsKeys
{
QList<QString> m_commonSettingsKeys;
QList<QList<QString>> m_streamsSettingsKeys;
};
DeviceAPI *m_deviceAPI;
AudioInputDevice m_audioInput;
AudioFifo m_inputFifo;
AudioOutputDevice m_audioOutput;
AudioFifo m_outputFifo;
QMutex m_mutex;
AudioCATSISOSettings m_settings;
AudioCATInputWorker* m_inputWorker;
AudioCATOutputWorker* m_outputWorker;
QThread *m_inputWorkerThread;
QThread *m_outputWorkerThread;
QString m_deviceDescription;
bool m_rxRunning;
int m_rxAudioDeviceIndex;
int m_rxSampleRate;
bool m_txRunning;
int m_txAudioDeviceIndex;
int m_txSampleRate;
const QTimer& m_masterTimer;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
void applySettings(const AudioCATSISOSettings& settings, const QList<QString>& settingsKeys, bool force);
void webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const AudioCATSISOSettings& settings, bool force);
void webapiReverseSendStartStop(bool start);
private slots:
void networkManagerFinished(QNetworkReply *reply);
};
#endif // _AUDIOCATSISO_AUDIOCATSISO_H_

Wyświetl plik

@ -0,0 +1,622 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// 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 <QTime>
#include <QDateTime>
#include <QString>
#include <QMessageBox>
#include <QFileDialog>
#include "plugin/pluginapi.h"
#include "device/deviceapi.h"
#include "device/deviceuiset.h"
#include "gui/colormapper.h"
#include "gui/glspectrum.h"
#include "gui/dialpopup.h"
#include "gui/dialogpositioner.h"
#include "gui/basicdevicesettingsdialog.h"
#include "gui/audioselectdialog.h"
#include "dsp/dspengine.h"
#include "dsp/dspdevicemimoengine.h"
#include "dsp/dspcommands.h"
#include "dsp/devicesamplesource.h"
#include "util/db.h"
#include "mainwindow.h"
#include "ui_audiocatsisogui.h"
#include "audiocatsisogui.h"
AudioCATSISOGUI::AudioCATSISOGUI(DeviceUISet *deviceUISet, QWidget* parent) :
DeviceGUI(parent),
ui(new Ui::AudioCATSISOGUI),
m_settings(),
m_doApplySettings(true),
m_forceSettings(true),
m_sampleMIMO(nullptr),
m_tickCount(0),
m_lastEngineState(DeviceAPI::StNotStarted)
{
qDebug("AudioCATSISOGUI::AudioCATSISOGUI");
m_deviceUISet = deviceUISet;
setAttribute(Qt::WA_DeleteOnClose, true);
m_sampleMIMO = (AudioCATSISO*) m_deviceUISet->m_deviceAPI->getSampleMIMO();
m_rxSampleRate = m_sampleMIMO->getSourceSampleRate(0);
m_settings.m_rxCenterFrequency = m_sampleMIMO->getSourceCenterFrequency(0);
m_settings.m_rxDeviceName = m_sampleMIMO->getInputDeviceName();
m_txSampleRate = m_sampleMIMO->getSinkSampleRate(0);
m_settings.m_txCenterFrequency = m_sampleMIMO->getSinkCenterFrequency(0);
m_settings.m_txDeviceName = m_sampleMIMO->getOutputDeviceName();
ui->setupUi(getContents());
sizeToContents();
getContents()->setStyleSheet("#AudioCATSISOGUI { background-color: rgb(64, 64, 64); }");
m_helpURL = "plugins/samplemimo/metismiso/readme.md";
ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->centerFrequency->setValueRange(9, 0, m_absMaxFreq);
displaySettings();
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
m_statusTimer.start(500);
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
m_sampleMIMO->setMessageQueueToGUI(&m_inputMessageQueue);
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
makeUIConnections();
DialPopup::addPopupsToChildDials(this);
}
AudioCATSISOGUI::~AudioCATSISOGUI()
{
delete ui;
}
void AudioCATSISOGUI::destroy()
{
delete this;
}
void AudioCATSISOGUI::resetToDefaults()
{
m_settings.resetToDefaults();
displaySettings();
m_forceSettings = true;
sendSettings();
}
void AudioCATSISOGUI::setCenterFrequency(qint64 centerFrequency)
{
if (m_settings.m_streamIndex == 0)
{
m_settings.m_rxCenterFrequency = centerFrequency;
m_settingsKeys.append("rxCenterFrequency");
}
else if (m_settings.m_streamIndex == 1)
{
m_settings.m_txCenterFrequency = centerFrequency;
m_settingsKeys.append("txCenterFrequency");
}
displaySettings();
sendSettings();
}
QByteArray AudioCATSISOGUI::serialize() const
{
return m_settings.serialize();
}
bool AudioCATSISOGUI::deserialize(const QByteArray& data)
{
if(m_settings.deserialize(data)) {
displaySettings();
m_forceSettings = true;
sendSettings();
return true;
} else {
resetToDefaults();
return false;
}
}
void AudioCATSISOGUI::on_startStop_toggled(bool checked)
{
if (m_doApplySettings)
{
AudioCATSISO::MsgStartStop *message = AudioCATSISO::MsgStartStop::create(checked);
m_sampleMIMO->getInputMessageQueue()->push(message);
}
}
void AudioCATSISOGUI::on_streamIndex_currentIndexChanged(int index)
{
if (ui->streamLock->isChecked())
{
m_settings.m_spectrumStreamIndex = index;
m_settingsKeys.append("spectrumStreamIndex");
if (m_settings.m_spectrumStreamIndex == 0)
{
m_deviceUISet->m_spectrum->setDisplayedStream(true, index);
m_deviceUISet->m_deviceAPI->setSpectrumSinkInput(true, 0);
m_deviceUISet->setSpectrumScalingFactor(SDR_RX_SCALEF);
}
else
{
m_deviceUISet->m_spectrum->setDisplayedStream(false, 0);
m_deviceUISet->m_deviceAPI->setSpectrumSinkInput(false, 0);
m_deviceUISet->setSpectrumScalingFactor(SDR_TX_SCALEF);
}
updateSpectrum();
ui->spectrumSource->blockSignals(true);
ui->spectrumSource->setCurrentIndex(index);
ui->spectrumSource->blockSignals(false);
}
m_settings.m_streamIndex = index;
m_settingsKeys.append("streamIndex");
sendSettings();
displayFrequency();
displaySampleRate();
}
void AudioCATSISOGUI::on_spectrumSource_currentIndexChanged(int index)
{
m_settings.m_spectrumStreamIndex = index;
m_settingsKeys.append("spectrumStreamIndex");
if (m_settings.m_spectrumStreamIndex == 0)
{
m_deviceUISet->m_spectrum->setDisplayedStream(true, index);
m_deviceUISet->m_deviceAPI->setSpectrumSinkInput(true, 0);
m_deviceUISet->setSpectrumScalingFactor(SDR_RX_SCALEF);
}
else
{
m_deviceUISet->m_spectrum->setDisplayedStream(false, 0);
m_deviceUISet->m_deviceAPI->setSpectrumSinkInput(false, 0);
m_deviceUISet->setSpectrumScalingFactor(SDR_TX_SCALEF);
}
updateSpectrum();
if (ui->streamLock->isChecked())
{
ui->streamIndex->blockSignals(true);
ui->streamIndex->setCurrentIndex(index);
ui->streamIndex->blockSignals(false);
m_settings.m_streamIndex = index;
m_settingsKeys.append("streamIndex");
displayFrequency();
displaySampleRate();
}
sendSettings();
}
void AudioCATSISOGUI::on_streamLock_toggled(bool checked)
{
if (checked && (ui->streamIndex->currentIndex() != ui->spectrumSource->currentIndex())) {
ui->spectrumSource->setCurrentIndex(ui->streamIndex->currentIndex());
}
}
void AudioCATSISOGUI::on_centerFrequency_changed(quint64 value)
{
if (m_settings.m_streamIndex == 0)
{
m_settings.m_rxCenterFrequency = value * 1000;
m_settingsKeys.append("rxCenterFrequency");
}
else if (m_settings.m_streamIndex == 1)
{
m_settings.m_txCenterFrequency = value * 1000;
m_settingsKeys.append("txCenterFrequency");
}
sendSettings();
}
void AudioCATSISOGUI::on_log2Decim_currentIndexChanged(int index)
{
m_settings.m_log2Decim = index < 0 ? 0 : index > 3 ? 3 : index;
// displaySampleRate();
displayFcRxTooltip();
m_settingsKeys.append("log2Decim");
sendSettings();
}
void AudioCATSISOGUI::on_dcBlock_toggled(bool checked)
{
m_settings.m_dcBlock = checked;
m_settingsKeys.append("dcBlock");
sendSettings();
}
void AudioCATSISOGUI::on_iqCorrection_toggled(bool checked)
{
m_settings.m_iqCorrection = checked;
m_settingsKeys.append("iqCorrection");
sendSettings();
}
void AudioCATSISOGUI::on_txEnable_toggled(bool checked)
{
m_settings.m_txEnable = checked;
m_settingsKeys.append("txEnable");
sendSettings();
}
void AudioCATSISOGUI::on_transverter_clicked()
{
m_settings.m_transverterMode = ui->transverter->getDeltaFrequencyAcive();
m_settings.m_transverterDeltaFrequency = ui->transverter->getDeltaFrequency();
m_settings.m_iqOrder = ui->transverter->getIQOrder();
m_settingsKeys.append("transverterMode");
m_settingsKeys.append("transverterDeltaFrequency");
m_settingsKeys.append("iqOrder");
qDebug("AudioCATSISOGUI::on_transverter_clicked: Rx: %lld Hz %s",
m_settings.m_transverterDeltaFrequency, m_settings.m_transverterMode ? "on" : "off");
displayFrequency();
setCenterFrequency(ui->centerFrequency->getValueNew() * 1000);
sendSettings();
}
void AudioCATSISOGUI::on_rxDeviceSelect_clicked()
{
AudioSelectDialog audioSelect(DSPEngine::instance()->getAudioDeviceManager(), m_settings.m_txDeviceName, true, this);
audioSelect.exec();
if (audioSelect.m_selected)
{
m_settings.m_rxDeviceName = audioSelect.m_audioDeviceName;
m_settingsKeys.append("rxDeviceName");
ui->rxDeviceLabel->setText(m_settings.m_rxDeviceName);
sendSettings();
}
}
void AudioCATSISOGUI::on_txDeviceSelect_clicked()
{
AudioSelectDialog audioSelect(DSPEngine::instance()->getAudioDeviceManager(), m_settings.m_txDeviceName, false, this);
audioSelect.exec();
if (audioSelect.m_selected)
{
m_settings.m_txDeviceName = audioSelect.m_audioDeviceName;
m_settingsKeys.append("txDeviceName");
ui->txDeviceLabel->setText(m_settings.m_txDeviceName);
sendSettings();
}
}
void AudioCATSISOGUI::on_rxChannels_currentIndexChanged(int index)
{
m_settings.m_rxIQMapping = (AudioCATSISOSettings::IQMapping)index;
// updateSampleRateAndFrequency();
m_settingsKeys.append("rxIQMapping");
sendSettings();
}
void AudioCATSISOGUI::on_rxVolume_valueChanged(int value)
{
m_settings.m_rxVolume = value/10.0f;
ui->rxVolumeText->setText(QString("%1").arg(m_settings.m_rxVolume, 3, 'f', 1));
m_settingsKeys.append("rxVolume");
sendSettings();
}
void AudioCATSISOGUI::on_txChannels_currentIndexChanged(int index)
{
m_settings.m_txIQMapping = (AudioCATSISOSettings::IQMapping) index;
m_settingsKeys.append("txIQMapping");
// updateSampleRateAndFrequency();
sendSettings();
}
void AudioCATSISOGUI::on_txVolume_valueChanged(int value)
{
m_settings.m_txVolume = value/10.0f;
ui->txVolumeText->setText(QString("%1").arg(m_settings.m_txVolume, 3, 'f', 1));
m_settingsKeys.append("txVolume");
sendSettings();
}
void AudioCATSISOGUI::on_fcPosRx_currentIndexChanged(int index)
{
m_settings.m_fcPosRx = (AudioCATSISOSettings::fcPos_t) (index < 0 ? 0 : index > 2 ? 2 : index);
displayFcRxTooltip();
m_settingsKeys.append("fcPosRx");
sendSettings();
}
void AudioCATSISOGUI::displaySettings()
{
blockApplySettings(true);
ui->rxDeviceLabel->setText(m_settings.m_rxDeviceName);
ui->txDeviceLabel->setText(m_settings.m_txDeviceName);
ui->streamIndex->setCurrentIndex(m_settings.m_streamIndex);
ui->spectrumSource->setCurrentIndex(m_settings.m_spectrumStreamIndex);
ui->log2Decim->setCurrentIndex(m_settings.m_log2Decim);
ui->dcBlock->setChecked(m_settings.m_dcBlock);
ui->iqCorrection->setChecked(m_settings.m_iqCorrection);
ui->txEnable->setChecked(m_settings.m_txEnable);
ui->rxVolume->setValue((int)(m_settings.m_rxVolume*10.0f));
ui->rxVolumeText->setText(QString("%1").arg(m_settings.m_rxVolume, 3, 'f', 1));
ui->rxChannels->setCurrentIndex((int)m_settings.m_rxIQMapping);
ui->txVolume->setValue((int)(m_settings.m_txVolume*10.0f));
ui->txVolumeText->setText(QString("%1").arg(m_settings.m_txVolume, 3, 'f', 1));
ui->txChannels->setCurrentIndex((int)m_settings.m_txIQMapping);
ui->fcPosRx->setCurrentIndex(m_settings.m_fcPosRx);
displayFrequency();
displaySampleRate();
updateSpectrum();
displayFcRxTooltip();
blockApplySettings(false);
}
void AudioCATSISOGUI::displayFcRxTooltip()
{
int32_t fShift = DeviceSampleSource::calculateFrequencyShift(
m_settings.m_log2Decim,
(DeviceSampleSource::fcPos_t) m_settings.m_fcPosRx,
m_rxSampleRate,
DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD
);
ui->fcPosRx->setToolTip(tr("Relative position of device center frequency: %1 kHz").arg(QString::number(fShift / 1000.0f, 'g', 5)));
}
void AudioCATSISOGUI::sendSettings()
{
if (!m_updateTimer.isActive()) {
m_updateTimer.start(100);
}
}
void AudioCATSISOGUI::updateHardware()
{
if (m_doApplySettings)
{
AudioCATSISO::MsgConfigureAudioCATSISO* message = AudioCATSISO::MsgConfigureAudioCATSISO::create(m_settings, m_settingsKeys, m_forceSettings);
m_sampleMIMO->getInputMessageQueue()->push(message);
m_forceSettings = false;
m_settingsKeys.clear();
m_updateTimer.stop();
}
}
void AudioCATSISOGUI::updateStatus()
{
int state = m_deviceUISet->m_deviceAPI->state();
if (m_lastEngineState != state)
{
switch(state)
{
case DeviceAPI::StNotStarted:
ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
break;
case DeviceAPI::StIdle:
ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
break;
case DeviceAPI::StRunning:
ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
break;
case DeviceAPI::StError:
ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage());
break;
default:
break;
}
m_lastEngineState = state;
}
}
bool AudioCATSISOGUI::handleMessage(const Message& message)
{
if (AudioCATSISO::MsgConfigureAudioCATSISO::match(message))
{
qDebug("AudioCATSISOGUI::handleMessage: MsgConfigureAudioCATSISO");
const AudioCATSISO::MsgConfigureAudioCATSISO& cfg = (AudioCATSISO::MsgConfigureAudioCATSISO&) message;
if (cfg.getForce()) {
m_settings = cfg.getSettings();
} else {
m_settings.applySettings(cfg.getSettingsKeys(), cfg.getSettings());
}
if ((m_settings.m_spectrumStreamIndex != m_settings.m_streamIndex) && (ui->streamLock->isChecked()))
{
m_settings.m_spectrumStreamIndex = m_settings.m_streamIndex;
m_settingsKeys.append("spectrumStreamIndex");
sendSettings();
}
displaySettings();
return true;
}
else if (AudioCATSISO::MsgStartStop::match(message))
{
qDebug("AudioCATSISOGUI::handleMessage: MsgStartStop");
AudioCATSISO::MsgStartStop& notif = (AudioCATSISO::MsgStartStop&) message;
blockApplySettings(true);
ui->startStop->setChecked(notif.getStartStop());
blockApplySettings(false);
return true;
}
else
{
return false;
}
}
void AudioCATSISOGUI::handleInputMessages()
{
Message* message;
while ((message = m_inputMessageQueue.pop()) != 0)
{
if (DSPMIMOSignalNotification::match(*message))
{
DSPMIMOSignalNotification* notif = (DSPMIMOSignalNotification*) message;
int istream = notif->getIndex();
bool sourceOrSink = notif->getSourceOrSink();
qint64 frequency = notif->getCenterFrequency();
if (sourceOrSink)
{
m_rxSampleRate = notif->getSampleRate();
m_settings.m_rxCenterFrequency = frequency;
}
else
{
m_txSampleRate = notif->getSampleRate();
m_settings.m_txCenterFrequency = frequency;
}
qDebug() << "AudioCATSISOGUI::handleInputMessages: DSPMIMOSignalNotification: "
<< "sourceOrSink:" << sourceOrSink
<< "istream:" << istream
<< "m_rxSampleRate:" << m_rxSampleRate
<< "m_txSampleRate:" << m_txSampleRate
<< "frequency:" << frequency;
displayFrequency();
displaySampleRate();
updateSpectrum();
delete message;
}
else
{
if (handleMessage(*message))
{
delete message;
}
}
}
}
void AudioCATSISOGUI::displayFrequency()
{
qint64 centerFrequency;
if (m_settings.m_streamIndex == 0) {
centerFrequency = m_settings.m_rxCenterFrequency;
} else if (m_settings.m_streamIndex == 1) {
centerFrequency = m_settings.m_txCenterFrequency;
}
ui->centerFrequency->setValueRange(9, 0, 9999999999);
ui->centerFrequency->setValue(centerFrequency / 1000);
}
void AudioCATSISOGUI::displaySampleRate()
{
if (m_settings.m_streamIndex == 0) {
ui->deviceRateText->setText(tr("%1k").arg((float) m_rxSampleRate / 1000));
} else {
ui->deviceRateText->setText(tr("%1k").arg((float) m_txSampleRate / 1000));
}
}
void AudioCATSISOGUI::updateSpectrum()
{
qint64 centerFrequency;
if (m_settings.m_spectrumStreamIndex == 0) {
centerFrequency = m_settings.m_rxCenterFrequency;
} else if (m_settings.m_spectrumStreamIndex == 1) {
centerFrequency = m_settings.m_txCenterFrequency;
} else {
centerFrequency = 0;
}
m_deviceUISet->getSpectrum()->setCenterFrequency(centerFrequency);
if (m_settings.m_spectrumStreamIndex == 0) {
m_deviceUISet->getSpectrum()->setSampleRate(m_rxSampleRate);
} else {
m_deviceUISet->getSpectrum()->setSampleRate(m_txSampleRate);
}
}
void AudioCATSISOGUI::openDeviceSettingsDialog(const QPoint& p)
{
if (m_contextMenuType == ContextMenuDeviceSettings)
{
BasicDeviceSettingsDialog dialog(this);
dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
dialog.move(p);
new DialogPositioner(&dialog, false);
dialog.exec();
m_settings.m_useReverseAPI = dialog.useReverseAPI();
m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
m_settingsKeys.append("useReverseAPI");
m_settingsKeys.append("reverseAPIAddress");
m_settingsKeys.append("reverseAPIPort");
m_settingsKeys.append("reverseAPIDeviceIndex");
sendSettings();
}
resetContextMenuType();
}
void AudioCATSISOGUI::makeUIConnections()
{
QObject::connect(ui->streamIndex, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AudioCATSISOGUI::on_streamIndex_currentIndexChanged);
QObject::connect(ui->spectrumSource, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AudioCATSISOGUI::on_spectrumSource_currentIndexChanged);
QObject::connect(ui->streamLock, &QToolButton::toggled, this, &AudioCATSISOGUI::on_streamLock_toggled);
QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &AudioCATSISOGUI::on_startStop_toggled);
QObject::connect(ui->centerFrequency, &ValueDial::changed, this, &AudioCATSISOGUI::on_centerFrequency_changed);
QObject::connect(ui->log2Decim, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AudioCATSISOGUI::on_log2Decim_currentIndexChanged);
QObject::connect(ui->dcBlock, &ButtonSwitch::toggled, this, &AudioCATSISOGUI::on_dcBlock_toggled);
QObject::connect(ui->iqCorrection, &ButtonSwitch::toggled, this, &AudioCATSISOGUI::on_iqCorrection_toggled);
QObject::connect(ui->txEnable, &ButtonSwitch::toggled, this, &AudioCATSISOGUI::on_txEnable_toggled);
QObject::connect(ui->transverter, &TransverterButton::clicked, this, &AudioCATSISOGUI::on_transverter_clicked);
QObject::connect(ui->rxDeviceSelect, &QPushButton::clicked, this, &AudioCATSISOGUI::on_rxDeviceSelect_clicked);
QObject::connect(ui->txDeviceSelect, &QPushButton::clicked, this, &AudioCATSISOGUI::on_txDeviceSelect_clicked);
QObject::connect(ui->rxChannels, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AudioCATSISOGUI::on_rxChannels_currentIndexChanged);
QObject::connect(ui->rxVolume, &QDial::valueChanged, this, &AudioCATSISOGUI::on_rxVolume_valueChanged);
QObject::connect(ui->txChannels, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AudioCATSISOGUI::on_txChannels_currentIndexChanged);
QObject::connect(ui->txVolume, &QDial::valueChanged, this, &AudioCATSISOGUI::on_txVolume_valueChanged);
QObject::connect(ui->fcPosRx, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AudioCATSISOGUI::on_fcPosRx_currentIndexChanged);
}

Wyświetl plik

@ -0,0 +1,103 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// 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 _AUDIOCATSISO_AUDIOCATSISOGUI_H_
#define _AUDIOCATSISO_AUDIOCATSISOGUI_H_
#include <device/devicegui.h>
#include <QTimer>
#include <QWidget>
#include "util/messagequeue.h"
#include "audiocatsisosettings.h"
#include "audiocatsiso.h"
class DeviceUISet;
namespace Ui {
class AudioCATSISOGUI;
}
class AudioCATSISOGUI : public DeviceGUI {
Q_OBJECT
public:
explicit AudioCATSISOGUI(DeviceUISet *deviceUISet, QWidget* parent = 0);
virtual ~AudioCATSISOGUI();
virtual void destroy();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
private:
Ui::AudioCATSISOGUI* ui;
AudioCATSISOSettings m_settings;
QList<QString> m_settingsKeys;
int m_rxSampleRate;
int m_txSampleRate;
QTimer m_updateTimer;
QTimer m_statusTimer;
bool m_doApplySettings;
bool m_forceSettings;
AudioCATSISO* m_sampleMIMO;
std::size_t m_tickCount;
std::vector<int> m_deviceSampleRates;
std::vector<quint64> m_deviceCenterFrequencies; //!< Center frequency in device
int m_lastEngineState;
MessageQueue m_inputMessageQueue;
static const int m_absMaxFreq = 61440; // kHz
void blockApplySettings(bool block) { m_doApplySettings = !block; }
void displaySettings();
void displayFrequency();
void displaySampleRate();
void displayFcRxTooltip();
void updateSpectrum();
void sendSettings();
void setCenterFrequency(qint64 centerFrequency);
bool handleMessage(const Message& message);
void makeUIConnections();
private slots:
void handleInputMessages();
void on_streamIndex_currentIndexChanged(int index);
void on_spectrumSource_currentIndexChanged(int index);
void on_streamLock_toggled(bool checked);
void on_startStop_toggled(bool checked);
void on_centerFrequency_changed(quint64 value);
void on_log2Decim_currentIndexChanged(int index);
void on_dcBlock_toggled(bool checked);
void on_iqCorrection_toggled(bool checked);
void on_txEnable_toggled(bool checked);
void on_transverter_clicked();
void on_rxDeviceSelect_clicked();
void on_txDeviceSelect_clicked();
void on_rxChannels_currentIndexChanged(int index);
void on_rxVolume_valueChanged(int value);
void on_txChannels_currentIndexChanged(int index);
void on_txVolume_valueChanged(int value);
void on_fcPosRx_currentIndexChanged(int index);
void openDeviceSettingsDialog(const QPoint& p);
void updateStatus();
void updateHardware();
};
#endif // _AUDIOCATSISO_AUDIOCATSISOGUI_H_

Wyświetl plik

@ -0,0 +1,842 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AudioCATSISOGUI</class>
<widget class="QWidget" name="AudioCATSISOGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>360</width>
<height>270</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>360</width>
<height>270</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>360</width>
<height>303</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="windowTitle">
<string>Audio CAT SISO</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="streamLayout">
<item>
<widget class="QLabel" name="streamLabel">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../sdrgui/resources/res.qrc">:/antenna.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="streamIndex">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Select stream to which settings apply (frequency only)</string>
</property>
<item>
<property name="text">
<string>Rx</string>
</property>
</item>
<item>
<property name="text">
<string>Tx</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="spectrumLabel">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../sdrgui/resources/res.qrc">:/dsb.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="spectrumSource">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Select stream for main spectrum source</string>
</property>
<item>
<property name="text">
<string>Rx</string>
</property>
</item>
<item>
<property name="text">
<string>Tx</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QToolButton" name="streamLock">
<property name="toolTip">
<string>Lock spectrum display to stream selection</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/unlocked.png</normaloff>
<normalon>:/locked.png</normalon>:/unlocked.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="txEnable">
<property name="toolTip">
<string>Enable/disable Tx</string>
</property>
<property name="text">
<string>Tx</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<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="TransverterButton" name="transverter">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Transverter frequency translation dialog</string>
</property>
<property name="text">
<string>X</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="frequencyLayout">
<item>
<layout class="QVBoxLayout" name="deviceUILayout">
<item>
<layout class="QHBoxLayout" name="deviceButtonsLayout">
<item>
<widget class="ButtonSwitch" name="startStop">
<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>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="deviceRateLayout">
<item>
<widget class="QLabel" name="deviceRateText">
<property name="minimumSize">
<size>
<width>58</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>I/Q sample rate kS/s</string>
</property>
<property name="text">
<string>0000.00k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="ValueDial" name="centerFrequency" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>16</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Tuner center frequency in kHz</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="freqUnits">
<property name="text">
<string> kHz</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="refreshDevices">
<property name="toolTip">
<string>Refresh list of audio devices</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="rxDeviceLayout">
<item>
<widget class="QPushButton" name="rxDeviceSelect">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Open dialog to select input device (Rx)</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/microphone.png</normaloff>:/microphone.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rxDeviceLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Output device selected</string>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="rxDSPLayout">
<item>
<widget class="QLabel" name="decimLabel">
<property name="text">
<string>Dec</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="log2Decim">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Decimation factor (Rx)</string>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>4</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="fcPosRxLabel">
<property name="text">
<string>Fp</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="fcPosRx">
<property name="minimumSize">
<size>
<width>55</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Relative position of device center frequency (Rx)</string>
</property>
<property name="currentIndex">
<number>2</number>
</property>
<item>
<property name="text">
<string>Inf</string>
</property>
</item>
<item>
<property name="text">
<string>Sup</string>
</property>
</item>
<item>
<property name="text">
<string>Cen</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="dcBlock">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>45</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>DC</string>
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="iqCorrection">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>45</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>IQ</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="rxVolumeLabel">
<property name="text">
<string>Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="rxVolume">
<property name="minimumSize">
<size>
<width>24</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Rx audio volume. Not supported by all devices</string>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rxVolumeText">
<property name="text">
<string>1.0</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<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="rxChannelMapLabel">
<property name="text">
<string>Channel Map</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="rxChannels">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>How Rx audio channels map to IQ data</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>I=L, Q=R</string>
</property>
</item>
<item>
<property name="text">
<string>I=R, Q=L</string>
</property>
</item>
<item>
<property name="text">
<string>Mono L</string>
</property>
</item>
<item>
<property name="text">
<string>Mono R</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="txDeviceLayout">
<item>
<widget class="QPushButton" name="txDeviceSelect">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Open dialog to select output device (Tx)</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/sound_on.png</normaloff>:/sound_on.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="txDeviceLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Output device selected</string>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="txVolumeLabel">
<property name="text">
<string>Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="txVolume">
<property name="minimumSize">
<size>
<width>24</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Tx audio volume. Not supported by all devices</string>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="txVolumeText">
<property name="text">
<string>1.0</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<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="txChannelMapLabel">
<property name="text">
<string>Channel Map</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="txChannels">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>How Tx audio channels map to IQ data</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>I=L, Q=R</string>
</property>
</item>
<item>
<property name="text">
<string>I=R, Q=L</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="catLayout">
<item>
<widget class="QLabel" name="catDeviceLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>CAT</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="catDevice">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>CAT Device</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="catType">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Hamlib device type</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="catSettings">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>CAT settings</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/tool.png</normaloff>:/tool.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ValueDial</class>
<extends>QWidget</extends>
<header>gui/valuedial.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ButtonSwitch</class>
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</customwidget>
<customwidget>
<class>TransverterButton</class>
<extends>QPushButton</extends>
<header>gui/transverterbutton.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>
</resources>
<connections/>
</ui>

Wyświetl plik

@ -0,0 +1,146 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// 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"
#include "util/simpleserializer.h"
#ifdef SERVER_MODE
#include "audiocatsiso.h"
#else
#include "audiocatsisogui.h"
#endif
#include "audiocatsisoplugin.h"
#include "audiocatsisowebapiadapter.h"
const PluginDescriptor AudioCATSISOPlugin::m_pluginDescriptor = {
QStringLiteral("AudioCATSISO"),
QStringLiteral("Audio CAT SISO"),
QStringLiteral("7.15.0"),
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
QStringLiteral("https://github.com/f4exb/sdrangel"),
true,
QStringLiteral("https://github.com/f4exb/sdrangel")
};
static constexpr const char* const m_hardwareID = "AudioCATSISO";
static constexpr const char* const m_deviceTypeID = AUDIOCATSISO_DEVICE_TYPE_ID;
AudioCATSISOPlugin::AudioCATSISOPlugin(QObject* parent) :
QObject(parent)
{
}
const PluginDescriptor& AudioCATSISOPlugin::getPluginDescriptor() const
{
return m_pluginDescriptor;
}
void AudioCATSISOPlugin::initPlugin(PluginAPI* pluginAPI)
{
pluginAPI->registerSampleMIMO(m_deviceTypeID, this);
}
void AudioCATSISOPlugin::enumOriginDevices(QStringList& listedHwIds, OriginDevices& originDevices)
{
if (listedHwIds.contains(m_hardwareID)) { // check if it was done
return;
}
originDevices.append(OriginDevice(
"AudioCATSISO", // Displayable name
m_hardwareID, // Hardware ID
QString(), // Serial
0, // Sequence
1, // Number of Rx streams
1 // Number of Tx streams
));
listedHwIds.append(m_hardwareID);
}
PluginInterface::SamplingDevices AudioCATSISOPlugin::enumSampleMIMO(const OriginDevices& originDevices)
{
SamplingDevices result;
for (OriginDevices::const_iterator it = originDevices.begin(); it != originDevices.end(); ++it)
{
if (it->hardwareId == m_hardwareID)
{
result.append(SamplingDevice(
it->displayableName,
it->hardwareId,
m_deviceTypeID,
it->serial,
it->sequence,
PluginInterface::SamplingDevice::PhysicalDevice,
PluginInterface::SamplingDevice::StreamMIMO,
1, // MIMO is always considered as a single device
0)
);
qDebug("MetisMISOPlugin::enumSampleMIMO: enumerated Metis device #%d", it->sequence);
}
}
return result;
}
#ifdef SERVER_MODE
DeviceGUI* AudioCATSISOPlugin::createSampleMIMOPluginInstanceGUI(
const QString& sourceId,
QWidget **widget,
DeviceUISet *deviceUISet)
{
(void) sourceId;
(void) widget;
(void) deviceUISet;
return 0;
}
#else
DeviceGUI* AudioCATSISOPlugin::createSampleMIMOPluginInstanceGUI(
const QString& sourceId,
QWidget **widget,
DeviceUISet *deviceUISet)
{
if (sourceId == m_deviceTypeID) {
AudioCATSISOGUI* gui = new AudioCATSISOGUI(deviceUISet);
*widget = gui;
return gui;
} else {
return nullptr;
}
}
#endif
DeviceSampleMIMO *AudioCATSISOPlugin::createSampleMIMOPluginInstance(const QString& mimoId, DeviceAPI *deviceAPI)
{
if (mimoId == m_deviceTypeID)
{
AudioCATSISO* input = new AudioCATSISO(deviceAPI);
return input;
}
else
{
return nullptr;
}
}
DeviceWebAPIAdapter *AudioCATSISOPlugin::createDeviceWebAPIAdapter() const
{
return new AudioCATSISOWebAPIAdapter();
}

Wyświetl plik

@ -0,0 +1,53 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// 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 _AUDIOCATSISO_AUDIOCATSISOPLUGIN_H
#define _AUDIOCATSISO_AUDIOCATSISOPLUGIN_H
#include <QObject>
#include "plugin/plugininterface.h"
class PluginAPI;
#define AUDIOCATSISO_DEVICE_TYPE_ID "sdrangel.samplemimo.audiocatsiso"
class AudioCATSISOPlugin : public QObject, public PluginInterface {
Q_OBJECT
Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID AUDIOCATSISO_DEVICE_TYPE_ID)
public:
explicit AudioCATSISOPlugin(QObject* parent = NULL);
const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI);
virtual void enumOriginDevices(QStringList& listedHwIds, OriginDevices& originDevices);
virtual SamplingDevices enumSampleMIMO(const OriginDevices& originDevices);
virtual DeviceGUI* createSampleMIMOPluginInstanceGUI(
const QString& sourceId,
QWidget **widget,
DeviceUISet *deviceUISet);
virtual DeviceSampleMIMO* createSampleMIMOPluginInstance(const QString& sourceId, DeviceAPI *deviceAPI);
virtual DeviceWebAPIAdapter* createDeviceWebAPIAdapter() const;
private:
static const PluginDescriptor m_pluginDescriptor;
};
#endif // _AUDIOCATSISO_AUDIOCATSISOPLUGIN_H

Wyświetl plik

@ -0,0 +1,304 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// 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 <QtGlobal>
#include "util/simpleserializer.h"
#include "audiocatsisosettings.h"
AudioCATSISOSettings::AudioCATSISOSettings()
{
resetToDefaults();
}
void AudioCATSISOSettings::resetToDefaults()
{
m_rxCenterFrequency = 14200000;
m_txCenterFrequency = 14200000;
m_rxDeviceName = "";
m_rxVolume = 1.0f;
m_log2Decim = 0;
m_rxIQMapping = LR;
m_dcBlock = false;
m_iqCorrection = false;
m_fcPosRx = FC_POS_CENTER;
m_txDeviceName = "";
m_txVolume = 1.0f;
m_txIQMapping = LR;
m_log2Interp = 0;
m_fcPosTx = FC_POS_CENTER;
m_streamIndex = 0;
m_spectrumStreamIndex = 0;
m_txEnable = false;
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
m_reverseAPIPort = 8888;
m_reverseAPIDeviceIndex = 0;
}
AudioCATSISOSettings::AudioCATSISOSettings(const AudioCATSISOSettings& other)
{
m_rxCenterFrequency = other.m_rxCenterFrequency;
m_txCenterFrequency = other.m_txCenterFrequency;
m_rxDeviceName = other.m_rxDeviceName;
m_rxVolume = other.m_rxVolume;
m_log2Decim = other.m_log2Decim;
m_rxIQMapping = other.m_rxIQMapping;
m_dcBlock = other.m_dcBlock;
m_iqCorrection = other.m_iqCorrection;
m_fcPosRx = other.m_fcPosRx;
m_txDeviceName = other.m_txDeviceName;
m_txVolume = other.m_txVolume;
m_txIQMapping = other.m_txIQMapping;
m_log2Interp = other.m_log2Interp;
m_fcPosTx = other.m_fcPosTx;
m_streamIndex = other.m_streamIndex;
m_spectrumStreamIndex = other.m_spectrumStreamIndex;
m_txEnable = other.m_txEnable;
m_useReverseAPI = other.m_useReverseAPI;
m_reverseAPIAddress = other.m_reverseAPIAddress;
m_reverseAPIPort = other.m_reverseAPIPort;
m_reverseAPIDeviceIndex = other.m_reverseAPIDeviceIndex;
}
QByteArray AudioCATSISOSettings::serialize() const
{
SimpleSerializer s(1);
s.writeString(1, m_rxDeviceName);
s.writeU64(2, m_rxCenterFrequency);
s.writeFloat(3, m_rxVolume);
s.writeU32(4, m_log2Decim);
s.writeS32(5, (int)m_rxIQMapping);
s.writeBool(6, m_dcBlock);
s.writeBool(7, m_iqCorrection);
s.writeS32(8, (int) m_fcPosRx);
s.writeString(21, m_txDeviceName);
s.writeU64(22, m_rxCenterFrequency);
s.writeFloat(23, m_txVolume);
s.writeS32(24, (int)m_txIQMapping);
s.writeU32(25, m_log2Decim);
s.writeS32(26, (int) m_fcPosTx);
s.writeBool(51, m_useReverseAPI);
s.writeString(52, m_reverseAPIAddress);
s.writeU32(53, m_reverseAPIPort);
s.writeU32(54, m_reverseAPIDeviceIndex);
s.writeS32(55, m_streamIndex);
s.writeS32(56, m_spectrumStreamIndex);
s.writeBool(57, m_txEnable);
return s.final();
}
bool AudioCATSISOSettings::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if (!d.isValid())
{
resetToDefaults();
return false;
}
if (d.getVersion() == 1)
{
uint32_t uintval;
int intval;
d.readString(1, &m_rxDeviceName, "");
d.readU64(2, &m_rxCenterFrequency, 14200000);
d.readFloat(3, &m_rxVolume, 1.0f);
d.readU32(4, &m_log2Decim, 0);
d.readS32(5, (int *)&m_rxIQMapping, IQMapping::L);
d.readBool(6, &m_dcBlock, false);
d.readBool(7, &m_iqCorrection, false);
d.readS32(8, &intval, 2);
m_fcPosRx = (fcPos_t) intval;
d.readString(21, &m_txDeviceName, "");
d.readU64(22, &m_txCenterFrequency, 14200000);
d.readFloat(23, &m_txVolume, 1.0f);
d.readS32(24,(int *)&m_txIQMapping, IQMapping::LR);
d.readU32(25, &m_log2Interp, 0);
d.readS32(26, &intval, 2);
m_fcPosTx = (fcPos_t) intval;
d.readBool(51, &m_useReverseAPI, false);
d.readString(52, &m_reverseAPIAddress, "127.0.0.1");
d.readU32(53, &uintval, 0);
if ((uintval > 1023) && (uintval < 65535)) {
m_reverseAPIPort = uintval;
} else {
m_reverseAPIPort = 8888;
}
d.readU32(54, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readS32(55, &m_streamIndex, 0);
d.readS32(56, &m_spectrumStreamIndex, 0);
d.readBool(57, &m_txEnable, false);
return true;
}
else
{
resetToDefaults();
return false;
}
}
void AudioCATSISOSettings::applySettings(const QStringList& settingsKeys, const AudioCATSISOSettings& settings)
{
if (settingsKeys.contains("rxDeviceName")) {
m_rxDeviceName = settings.m_rxDeviceName;
}
if (settingsKeys.contains("rxCenterFrequency")) {
m_rxCenterFrequency = settings.m_rxCenterFrequency;
}
if (settingsKeys.contains("rxVolume")) {
m_rxVolume = settings.m_rxVolume;
}
if (settingsKeys.contains("log2Decim")) {
m_log2Decim = settings.m_log2Decim;
}
if (settingsKeys.contains("rxIQMapping")) {
m_rxIQMapping = settings.m_rxIQMapping;
}
if (settingsKeys.contains("dcBlock")) {
m_dcBlock = settings.m_dcBlock;
}
if (settingsKeys.contains("iqCorrection")) {
m_iqCorrection = settings.m_iqCorrection;
}
if (settingsKeys.contains("fcPosRx")) {
m_fcPosRx = settings.m_fcPosRx;
}
if (settingsKeys.contains("txDeviceName")) {
m_txDeviceName = settings.m_txDeviceName;
}
if (settingsKeys.contains("txCenterFrequency")) {
m_txCenterFrequency = settings.m_txCenterFrequency;
}
if (settingsKeys.contains("txVolume")) {
m_txVolume = settings.m_txVolume;
}
if (settingsKeys.contains("txIQMapping")) {
m_txIQMapping = settings.m_txIQMapping;
}
if (settingsKeys.contains("log2Interp")) {
m_log2Interp = settings.m_log2Interp;
}
if (settingsKeys.contains("fcPosTx")) {
m_fcPosTx = settings.m_fcPosTx;
}
if (settingsKeys.contains("streamIndex")) {
m_streamIndex = settings.m_streamIndex;
}
if (settingsKeys.contains("spectrumStreamIndex")) {
m_spectrumStreamIndex = settings.m_spectrumStreamIndex;
}
if (settingsKeys.contains("txEnable")) {
m_txEnable = settings.m_txEnable;
}
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("reverseAPIDeviceIndex")) {
m_reverseAPIDeviceIndex = settings.m_reverseAPIDeviceIndex;
}
}
QString AudioCATSISOSettings::getDebugString(const QStringList& settingsKeys, bool force) const
{
std::ostringstream ostr;
if (settingsKeys.contains("rxDeviceName") || force) {
ostr << " m_rxDeviceName: " << m_rxDeviceName.toStdString();
}
if (settingsKeys.contains("rxCenterFrequency") || force) {
ostr << " m_rxCenterFrequency: " << m_rxCenterFrequency;
}
if (settingsKeys.contains("rxVolume") || force) {
ostr << " m_rxVolume: " << m_rxVolume;
}
if (settingsKeys.contains("log2Decim") || force) {
ostr << " m_log2Decim: " << m_log2Decim;
}
if (settingsKeys.contains("rxIQMapping") || force) {
ostr << " m_rxIQMapping: " << m_rxIQMapping;
}
if (settingsKeys.contains("dcBlock") || force) {
ostr << " m_dcBlock: " << m_dcBlock;
}
if (settingsKeys.contains("iqCorrection") || force) {
ostr << " m_iqCorrection: " << m_iqCorrection;
}
if (settingsKeys.contains("fcPosRx") || force) {
ostr << " m_fcPosRx: " << m_fcPosRx;
}
if (settingsKeys.contains("txDeviceName") || force) {
ostr << " m_txDeviceName: " << m_txDeviceName.toStdString();
}
if (settingsKeys.contains("txVolume") || force) {
ostr << " m_txVolume: " << m_txVolume;
}
if (settingsKeys.contains("txIQMapping") || force) {
ostr << " m_txIQMapping: " << m_txIQMapping;
}
if (settingsKeys.contains("log2Interp") || force) {
ostr << " m_log2Interp: " << m_log2Interp;
}
if (settingsKeys.contains("fcPosTx") || force) {
ostr << " m_fcPosTx: " << m_fcPosTx;
}
if (settingsKeys.contains("streamIndex") || force) {
ostr << " m_streamIndex: " << m_streamIndex;
}
if (settingsKeys.contains("spectrumStreamIndex") || force) {
ostr << " m_spectrumStreamIndex: " << m_spectrumStreamIndex;
}
if (settingsKeys.contains("txEnable") || force) {
ostr << " m_txEnable: " << m_txEnable;
}
if (settingsKeys.contains("useReverseAPI") || force) {
ostr << " m_useReverseAPI: " << m_useReverseAPI;
}
if (settingsKeys.contains("reverseAPIAddress") || force) {
ostr << " m_reverseAPIAddress: " << m_reverseAPIAddress.toStdString();
}
if (settingsKeys.contains("reverseAPIPort") || force) {
ostr << " m_reverseAPIPort: " << m_reverseAPIPort;
}
if (settingsKeys.contains("reverseAPIDeviceIndex") || force) {
ostr << " m_reverseAPIDeviceIndex: " << m_reverseAPIDeviceIndex;
}
return QString(ostr.str().c_str());
}

Wyświetl plik

@ -0,0 +1,88 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// 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 _AUDIOCATSISO_AUDIOCATSISOSETTINGS_H_
#define _AUDIOCATSISO_AUDIOCATSISOSETTINGS_H_
#include <QString>
#include "audio/audiodeviceinfo.h"
struct AudioCATSISOSettings {
typedef enum {
FC_POS_INFRA = 0,
FC_POS_SUPRA,
FC_POS_CENTER
} fcPos_t;
enum IQMapping {
LR,
RL,
L,
R
};
quint64 m_rxCenterFrequency;
quint64 m_txCenterFrequency;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
int m_streamIndex;
int m_spectrumStreamIndex; //!< spectrum source
bool m_txEnable;
QString m_rxDeviceName; // Including realm, as from getFullDeviceName below
IQMapping m_rxIQMapping;
unsigned int m_log2Decim;
fcPos_t m_fcPosRx;
bool m_dcBlock;
bool m_iqCorrection;
float m_rxVolume;
QString m_txDeviceName; // Including realm, as from getFullDeviceName below
IQMapping m_txIQMapping;
unsigned int m_log2Interp;
fcPos_t m_fcPosTx; //!< Not implemented yet
float m_txVolume; //!< Not implemented yet
bool m_useReverseAPI;
QString m_reverseAPIAddress;
uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIDeviceIndex;
AudioCATSISOSettings();
AudioCATSISOSettings(const AudioCATSISOSettings& other);
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
AudioCATSISOSettings& operator=(const AudioCATSISOSettings&) = default;
void applySettings(const QStringList& settingsKeys, const AudioCATSISOSettings& settings);
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
// Append realm to device names, because there may be multiple devices with the same name on Windows
static QString getFullDeviceName(const AudioDeviceInfo &deviceInfo)
{
QString realm = deviceInfo.realm();
if (realm != "" && realm != "default" && realm != "alsa")
return deviceInfo.deviceName() + " " + realm;
else
return deviceInfo.deviceName();
}
static int getSampleRateFromIndex(unsigned int index);
};
#endif /* _AUDIOCATSISO_AUDIOCATSISOSETTINGS_H_ */

Wyświetl plik

@ -0,0 +1,52 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// Implementation of static web API adapters used for preset serialization and //
// deserialization //
// //
// 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 "SWGDeviceSettings.h"
#include "audiocatsiso.h"
#include "audiocatsisowebapiadapter.h"
AudioCATSISOWebAPIAdapter::AudioCATSISOWebAPIAdapter()
{}
AudioCATSISOWebAPIAdapter::~AudioCATSISOWebAPIAdapter()
{}
int AudioCATSISOWebAPIAdapter::webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage)
{
(void) errorMessage;
response.setAudioCatsisoSettings(new SWGSDRangel::SWGAudioCATSISOSettings());
response.getAudioCatsisoSettings()->init();
AudioCATSISO::webapiFormatDeviceSettings(response, m_settings);
return 200;
}
int AudioCATSISOWebAPIAdapter::webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage)
{
(void) force; // no action
(void) errorMessage;
AudioCATSISO::webapiUpdateDeviceSettings(m_settings, deviceSettingsKeys, response);
return 200;
}

Wyświetl plik

@ -0,0 +1,49 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Edouard Griffiths, F4EXB //
// //
// Implementation of static web API adapters used for preset serialization and //
// deserialization //
// //
// 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 _AUDIOCATSISO_AUDIOCATSISOWEBAPIADAPTER_H_
#define _AUDIOCATSISO_AUDIOCATSISOWEBAPIADAPTER_H_
#include "device/devicewebapiadapter.h"
#include "audiocatsisosettings.h"
class AudioCATSISOWebAPIAdapter : public DeviceWebAPIAdapter
{
public:
AudioCATSISOWebAPIAdapter();
virtual ~AudioCATSISOWebAPIAdapter();
virtual QByteArray serialize() { return m_settings.serialize(); }
virtual bool deserialize(const QByteArray& data) { return m_settings.deserialize(data); }
virtual int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
virtual int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage);
private:
AudioCATSISOSettings m_settings;
};
#endif // _AUDIOCATSISO_AUDIOCATSISOWEBAPIADAPTER_H_

Wyświetl plik

@ -18,6 +18,7 @@
<file>webapi/doc/swagger/include/APTDemod.yaml</file>
<file>webapi/doc/swagger/include/ATVDemod.yaml</file>
<file>webapi/doc/swagger/include/ATVMod.yaml</file>
<file>webapi/doc/swagger/include/AudioCATSISO.yaml</file>
<file>webapi/doc/swagger/include/AudioInput.yaml</file>
<file>webapi/doc/swagger/include/AudioOutput.yaml</file>
<file>webapi/doc/swagger/include/BeamSteeringCWMod.yaml</file>

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -0,0 +1,99 @@
AudioCATSISOSettings:
description: AudioCATSISO
properties:
rxCenterFrequency:
type: integer
format: int64
txCenterFrequency:
type: integer
format: int64
transverterMode:
type: integer
transverterDeltaFrequency:
type: integer
format: int64
iqOrder:
type: integer
description: >
IQ samples order
* 0 - Q then I (swapped)
* 1 - I then Q (straight)
streamIndex:
type: integer
description: The index of the stream currently in scope
spectrumStreamIndex:
type: integer
description: The index of the stream that is used as source of the main spectrum
txEnable:
type: integer
description: >
Enable or disable transmission
* 0 - Disable transmission
* 1 - Enable transmission
rxDeviceName:
description: The name of the input audio device
type: string
rxIQMapping:
type: integer
description: >
Audio channel to IQ mapping
* 0 - I=L, Q=R
* 1 - I=R, Q=L
* 2 - I=L, Q=0
* 3 - I=R, Q=0
log2Decim:
description: Decimation factor (Rx)
type: integer
fcPosRx:
type: integer
description: >
Decimated bandpass center frequency position
* 0 - Infradyne
* 1 - Supradyne
* 2 - Centered
dcBlock:
type: integer
description: >
Auto DC blocking
* 0 - Off
* 1 - On
iqCorrection:
type: integer
description: >
Auto IQ balance (you need auto DC blocking active)
* 0 - Off
* 1 - On
rxVolume:
type: number
format: float
txDeviceName:
description: The name of the output audio device
type: string
txIQMapping:
type: integer
description: >
Audio channel to IQ mapping
* 0 - I=L, Q=R
* 1 - I=R, Q=L
log2Interp:
description: Interpolation factor (Tx)
type: integer
fcPosTx:
type: integer
description: >
Interpolated bandpass center frequency position
* 0 - Infradyne
* 1 - Supradyne
* 2 - Centered
txVolume:
type: number
format: float
useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no)
type: integer
reverseAPIAddress:
type: string
reverseAPIPort:
type: integer
reverseAPIDeviceIndex:
type: integer

Wyświetl plik

@ -18,6 +18,8 @@ DeviceSettings:
$ref: "/doc/swagger/include/Airspy.yaml#/AirspySettings"
airspyHFSettings:
$ref: "/doc/swagger/include/AirspyHF.yaml#/AirspyHFSettings"
audioCATSISOSettings:
$ref: "/doc/swagger/include/AudioCATSISO.yaml#/AudioCATSISOSettings"
audioInputSettings:
$ref: "/doc/swagger/include/AudioInput.yaml#/AudioInputSettings"
audioOutputSettings:

Wyświetl plik

@ -0,0 +1,99 @@
AudioCATSISOSettings:
description: AudioCATSISO
properties:
rxCenterFrequency:
type: integer
format: int64
txCenterFrequency:
type: integer
format: int64
transverterMode:
type: integer
transverterDeltaFrequency:
type: integer
format: int64
iqOrder:
type: integer
description: >
IQ samples order
* 0 - Q then I (swapped)
* 1 - I then Q (straight)
streamIndex:
type: integer
description: The index of the stream currently in scope
spectrumStreamIndex:
type: integer
description: The index of the stream that is used as source of the main spectrum
txEnable:
type: integer
description: >
Enable or disable transmission
* 0 - Disable transmission
* 1 - Enable transmission
rxDeviceName:
description: The name of the input audio device
type: string
rxIQMapping:
type: integer
description: >
Audio channel to IQ mapping
* 0 - I=L, Q=R
* 1 - I=R, Q=L
* 2 - I=L, Q=0
* 3 - I=R, Q=0
log2Decim:
description: Decimation factor (Rx)
type: integer
fcPosRx:
type: integer
description: >
Decimated bandpass center frequency position
* 0 - Infradyne
* 1 - Supradyne
* 2 - Centered
dcBlock:
type: integer
description: >
Auto DC blocking
* 0 - Off
* 1 - On
iqCorrection:
type: integer
description: >
Auto IQ balance (you need auto DC blocking active)
* 0 - Off
* 1 - On
rxVolume:
type: number
format: float
txDeviceName:
description: The name of the output audio device
type: string
txIQMapping:
type: integer
description: >
Audio channel to IQ mapping
* 0 - I=L, Q=R
* 1 - I=R, Q=L
log2Interp:
description: Interpolation factor (Tx)
type: integer
fcPosTx:
type: integer
description: >
Interpolated bandpass center frequency position
* 0 - Infradyne
* 1 - Supradyne
* 2 - Centered
txVolume:
type: number
format: float
useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no)
type: integer
reverseAPIAddress:
type: string
reverseAPIPort:
type: integer
reverseAPIDeviceIndex:
type: integer

Wyświetl plik

@ -18,6 +18,8 @@ DeviceSettings:
$ref: "http://swgserver:8081/api/swagger/include/Airspy.yaml#/AirspySettings"
airspyHFSettings:
$ref: "http://swgserver:8081/api/swagger/include/AirspyHF.yaml#/AirspyHFSettings"
audioCATSISOSettings:
$ref: "http://swgserver:8081/api/swagger/include/AudioCATSISO.yaml#/AudioCATSISOSettings"
audioInputSettings:
$ref: "http://swgserver:8081/api/swagger/include/AudioInput.yaml#/AudioInputSettings"
audioOutputSettings:

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -0,0 +1,643 @@
/**
* 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 "SWGAudioCATSISOSettings.h"
#include "SWGHelpers.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QObject>
#include <QDebug>
namespace SWGSDRangel {
SWGAudioCATSISOSettings::SWGAudioCATSISOSettings(QString* json) {
init();
this->fromJson(*json);
}
SWGAudioCATSISOSettings::SWGAudioCATSISOSettings() {
rx_center_frequency = 0L;
m_rx_center_frequency_isSet = false;
tx_center_frequency = 0L;
m_tx_center_frequency_isSet = false;
transverter_mode = 0;
m_transverter_mode_isSet = false;
transverter_delta_frequency = 0L;
m_transverter_delta_frequency_isSet = false;
iq_order = 0;
m_iq_order_isSet = false;
stream_index = 0;
m_stream_index_isSet = false;
spectrum_stream_index = 0;
m_spectrum_stream_index_isSet = false;
tx_enable = 0;
m_tx_enable_isSet = false;
rx_device_name = nullptr;
m_rx_device_name_isSet = false;
rx_iq_mapping = 0;
m_rx_iq_mapping_isSet = false;
log2_decim = 0;
m_log2_decim_isSet = false;
fc_pos_rx = 0;
m_fc_pos_rx_isSet = false;
dc_block = 0;
m_dc_block_isSet = false;
iq_correction = 0;
m_iq_correction_isSet = false;
rx_volume = 0.0f;
m_rx_volume_isSet = false;
tx_device_name = nullptr;
m_tx_device_name_isSet = false;
tx_iq_mapping = 0;
m_tx_iq_mapping_isSet = false;
log2_interp = 0;
m_log2_interp_isSet = false;
fc_pos_tx = 0;
m_fc_pos_tx_isSet = false;
tx_volume = 0.0f;
m_tx_volume_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_device_index = 0;
m_reverse_api_device_index_isSet = false;
}
SWGAudioCATSISOSettings::~SWGAudioCATSISOSettings() {
this->cleanup();
}
void
SWGAudioCATSISOSettings::init() {
rx_center_frequency = 0L;
m_rx_center_frequency_isSet = false;
tx_center_frequency = 0L;
m_tx_center_frequency_isSet = false;
transverter_mode = 0;
m_transverter_mode_isSet = false;
transverter_delta_frequency = 0L;
m_transverter_delta_frequency_isSet = false;
iq_order = 0;
m_iq_order_isSet = false;
stream_index = 0;
m_stream_index_isSet = false;
spectrum_stream_index = 0;
m_spectrum_stream_index_isSet = false;
tx_enable = 0;
m_tx_enable_isSet = false;
rx_device_name = new QString("");
m_rx_device_name_isSet = false;
rx_iq_mapping = 0;
m_rx_iq_mapping_isSet = false;
log2_decim = 0;
m_log2_decim_isSet = false;
fc_pos_rx = 0;
m_fc_pos_rx_isSet = false;
dc_block = 0;
m_dc_block_isSet = false;
iq_correction = 0;
m_iq_correction_isSet = false;
rx_volume = 0.0f;
m_rx_volume_isSet = false;
tx_device_name = new QString("");
m_tx_device_name_isSet = false;
tx_iq_mapping = 0;
m_tx_iq_mapping_isSet = false;
log2_interp = 0;
m_log2_interp_isSet = false;
fc_pos_tx = 0;
m_fc_pos_tx_isSet = false;
tx_volume = 0.0f;
m_tx_volume_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_device_index = 0;
m_reverse_api_device_index_isSet = false;
}
void
SWGAudioCATSISOSettings::cleanup() {
if(rx_device_name != nullptr) {
delete rx_device_name;
}
if(tx_device_name != nullptr) {
delete tx_device_name;
}
if(reverse_api_address != nullptr) {
delete reverse_api_address;
}
}
SWGAudioCATSISOSettings*
SWGAudioCATSISOSettings::fromJson(QString &json) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonObject jsonObject = doc.object();
this->fromJsonObject(jsonObject);
return this;
}
void
SWGAudioCATSISOSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&rx_center_frequency, pJson["rxCenterFrequency"], "qint64", "");
::SWGSDRangel::setValue(&tx_center_frequency, pJson["txCenterFrequency"], "qint64", "");
::SWGSDRangel::setValue(&transverter_mode, pJson["transverterMode"], "qint32", "");
::SWGSDRangel::setValue(&transverter_delta_frequency, pJson["transverterDeltaFrequency"], "qint64", "");
::SWGSDRangel::setValue(&iq_order, pJson["iqOrder"], "qint32", "");
::SWGSDRangel::setValue(&stream_index, pJson["streamIndex"], "qint32", "");
::SWGSDRangel::setValue(&spectrum_stream_index, pJson["spectrumStreamIndex"], "qint32", "");
::SWGSDRangel::setValue(&tx_enable, pJson["txEnable"], "qint32", "");
::SWGSDRangel::setValue(&rx_device_name, pJson["rxDeviceName"], "QString", "QString");
::SWGSDRangel::setValue(&rx_iq_mapping, pJson["rxIQMapping"], "qint32", "");
::SWGSDRangel::setValue(&log2_decim, pJson["log2Decim"], "qint32", "");
::SWGSDRangel::setValue(&fc_pos_rx, pJson["fcPosRx"], "qint32", "");
::SWGSDRangel::setValue(&dc_block, pJson["dcBlock"], "qint32", "");
::SWGSDRangel::setValue(&iq_correction, pJson["iqCorrection"], "qint32", "");
::SWGSDRangel::setValue(&rx_volume, pJson["rxVolume"], "float", "");
::SWGSDRangel::setValue(&tx_device_name, pJson["txDeviceName"], "QString", "QString");
::SWGSDRangel::setValue(&tx_iq_mapping, pJson["txIQMapping"], "qint32", "");
::SWGSDRangel::setValue(&log2_interp, pJson["log2Interp"], "qint32", "");
::SWGSDRangel::setValue(&fc_pos_tx, pJson["fcPosTx"], "qint32", "");
::SWGSDRangel::setValue(&tx_volume, pJson["txVolume"], "float", "");
::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_device_index, pJson["reverseAPIDeviceIndex"], "qint32", "");
}
QString
SWGAudioCATSISOSettings::asJson ()
{
QJsonObject* obj = this->asJsonObject();
QJsonDocument doc(*obj);
QByteArray bytes = doc.toJson();
delete obj;
return QString(bytes);
}
QJsonObject*
SWGAudioCATSISOSettings::asJsonObject() {
QJsonObject* obj = new QJsonObject();
if(m_rx_center_frequency_isSet){
obj->insert("rxCenterFrequency", QJsonValue(rx_center_frequency));
}
if(m_tx_center_frequency_isSet){
obj->insert("txCenterFrequency", QJsonValue(tx_center_frequency));
}
if(m_transverter_mode_isSet){
obj->insert("transverterMode", QJsonValue(transverter_mode));
}
if(m_transverter_delta_frequency_isSet){
obj->insert("transverterDeltaFrequency", QJsonValue(transverter_delta_frequency));
}
if(m_iq_order_isSet){
obj->insert("iqOrder", QJsonValue(iq_order));
}
if(m_stream_index_isSet){
obj->insert("streamIndex", QJsonValue(stream_index));
}
if(m_spectrum_stream_index_isSet){
obj->insert("spectrumStreamIndex", QJsonValue(spectrum_stream_index));
}
if(m_tx_enable_isSet){
obj->insert("txEnable", QJsonValue(tx_enable));
}
if(rx_device_name != nullptr && *rx_device_name != QString("")){
toJsonValue(QString("rxDeviceName"), rx_device_name, obj, QString("QString"));
}
if(m_rx_iq_mapping_isSet){
obj->insert("rxIQMapping", QJsonValue(rx_iq_mapping));
}
if(m_log2_decim_isSet){
obj->insert("log2Decim", QJsonValue(log2_decim));
}
if(m_fc_pos_rx_isSet){
obj->insert("fcPosRx", QJsonValue(fc_pos_rx));
}
if(m_dc_block_isSet){
obj->insert("dcBlock", QJsonValue(dc_block));
}
if(m_iq_correction_isSet){
obj->insert("iqCorrection", QJsonValue(iq_correction));
}
if(m_rx_volume_isSet){
obj->insert("rxVolume", QJsonValue(rx_volume));
}
if(tx_device_name != nullptr && *tx_device_name != QString("")){
toJsonValue(QString("txDeviceName"), tx_device_name, obj, QString("QString"));
}
if(m_tx_iq_mapping_isSet){
obj->insert("txIQMapping", QJsonValue(tx_iq_mapping));
}
if(m_log2_interp_isSet){
obj->insert("log2Interp", QJsonValue(log2_interp));
}
if(m_fc_pos_tx_isSet){
obj->insert("fcPosTx", QJsonValue(fc_pos_tx));
}
if(m_tx_volume_isSet){
obj->insert("txVolume", QJsonValue(tx_volume));
}
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_device_index_isSet){
obj->insert("reverseAPIDeviceIndex", QJsonValue(reverse_api_device_index));
}
return obj;
}
qint64
SWGAudioCATSISOSettings::getRxCenterFrequency() {
return rx_center_frequency;
}
void
SWGAudioCATSISOSettings::setRxCenterFrequency(qint64 rx_center_frequency) {
this->rx_center_frequency = rx_center_frequency;
this->m_rx_center_frequency_isSet = true;
}
qint64
SWGAudioCATSISOSettings::getTxCenterFrequency() {
return tx_center_frequency;
}
void
SWGAudioCATSISOSettings::setTxCenterFrequency(qint64 tx_center_frequency) {
this->tx_center_frequency = tx_center_frequency;
this->m_tx_center_frequency_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getTransverterMode() {
return transverter_mode;
}
void
SWGAudioCATSISOSettings::setTransverterMode(qint32 transverter_mode) {
this->transverter_mode = transverter_mode;
this->m_transverter_mode_isSet = true;
}
qint64
SWGAudioCATSISOSettings::getTransverterDeltaFrequency() {
return transverter_delta_frequency;
}
void
SWGAudioCATSISOSettings::setTransverterDeltaFrequency(qint64 transverter_delta_frequency) {
this->transverter_delta_frequency = transverter_delta_frequency;
this->m_transverter_delta_frequency_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getIqOrder() {
return iq_order;
}
void
SWGAudioCATSISOSettings::setIqOrder(qint32 iq_order) {
this->iq_order = iq_order;
this->m_iq_order_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getStreamIndex() {
return stream_index;
}
void
SWGAudioCATSISOSettings::setStreamIndex(qint32 stream_index) {
this->stream_index = stream_index;
this->m_stream_index_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getSpectrumStreamIndex() {
return spectrum_stream_index;
}
void
SWGAudioCATSISOSettings::setSpectrumStreamIndex(qint32 spectrum_stream_index) {
this->spectrum_stream_index = spectrum_stream_index;
this->m_spectrum_stream_index_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getTxEnable() {
return tx_enable;
}
void
SWGAudioCATSISOSettings::setTxEnable(qint32 tx_enable) {
this->tx_enable = tx_enable;
this->m_tx_enable_isSet = true;
}
QString*
SWGAudioCATSISOSettings::getRxDeviceName() {
return rx_device_name;
}
void
SWGAudioCATSISOSettings::setRxDeviceName(QString* rx_device_name) {
this->rx_device_name = rx_device_name;
this->m_rx_device_name_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getRxIqMapping() {
return rx_iq_mapping;
}
void
SWGAudioCATSISOSettings::setRxIqMapping(qint32 rx_iq_mapping) {
this->rx_iq_mapping = rx_iq_mapping;
this->m_rx_iq_mapping_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getLog2Decim() {
return log2_decim;
}
void
SWGAudioCATSISOSettings::setLog2Decim(qint32 log2_decim) {
this->log2_decim = log2_decim;
this->m_log2_decim_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getFcPosRx() {
return fc_pos_rx;
}
void
SWGAudioCATSISOSettings::setFcPosRx(qint32 fc_pos_rx) {
this->fc_pos_rx = fc_pos_rx;
this->m_fc_pos_rx_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getDcBlock() {
return dc_block;
}
void
SWGAudioCATSISOSettings::setDcBlock(qint32 dc_block) {
this->dc_block = dc_block;
this->m_dc_block_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getIqCorrection() {
return iq_correction;
}
void
SWGAudioCATSISOSettings::setIqCorrection(qint32 iq_correction) {
this->iq_correction = iq_correction;
this->m_iq_correction_isSet = true;
}
float
SWGAudioCATSISOSettings::getRxVolume() {
return rx_volume;
}
void
SWGAudioCATSISOSettings::setRxVolume(float rx_volume) {
this->rx_volume = rx_volume;
this->m_rx_volume_isSet = true;
}
QString*
SWGAudioCATSISOSettings::getTxDeviceName() {
return tx_device_name;
}
void
SWGAudioCATSISOSettings::setTxDeviceName(QString* tx_device_name) {
this->tx_device_name = tx_device_name;
this->m_tx_device_name_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getTxIqMapping() {
return tx_iq_mapping;
}
void
SWGAudioCATSISOSettings::setTxIqMapping(qint32 tx_iq_mapping) {
this->tx_iq_mapping = tx_iq_mapping;
this->m_tx_iq_mapping_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getLog2Interp() {
return log2_interp;
}
void
SWGAudioCATSISOSettings::setLog2Interp(qint32 log2_interp) {
this->log2_interp = log2_interp;
this->m_log2_interp_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getFcPosTx() {
return fc_pos_tx;
}
void
SWGAudioCATSISOSettings::setFcPosTx(qint32 fc_pos_tx) {
this->fc_pos_tx = fc_pos_tx;
this->m_fc_pos_tx_isSet = true;
}
float
SWGAudioCATSISOSettings::getTxVolume() {
return tx_volume;
}
void
SWGAudioCATSISOSettings::setTxVolume(float tx_volume) {
this->tx_volume = tx_volume;
this->m_tx_volume_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getUseReverseApi() {
return use_reverse_api;
}
void
SWGAudioCATSISOSettings::setUseReverseApi(qint32 use_reverse_api) {
this->use_reverse_api = use_reverse_api;
this->m_use_reverse_api_isSet = true;
}
QString*
SWGAudioCATSISOSettings::getReverseApiAddress() {
return reverse_api_address;
}
void
SWGAudioCATSISOSettings::setReverseApiAddress(QString* reverse_api_address) {
this->reverse_api_address = reverse_api_address;
this->m_reverse_api_address_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getReverseApiPort() {
return reverse_api_port;
}
void
SWGAudioCATSISOSettings::setReverseApiPort(qint32 reverse_api_port) {
this->reverse_api_port = reverse_api_port;
this->m_reverse_api_port_isSet = true;
}
qint32
SWGAudioCATSISOSettings::getReverseApiDeviceIndex() {
return reverse_api_device_index;
}
void
SWGAudioCATSISOSettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) {
this->reverse_api_device_index = reverse_api_device_index;
this->m_reverse_api_device_index_isSet = true;
}
bool
SWGAudioCATSISOSettings::isSet(){
bool isObjectUpdated = false;
do{
if(m_rx_center_frequency_isSet){
isObjectUpdated = true; break;
}
if(m_tx_center_frequency_isSet){
isObjectUpdated = true; break;
}
if(m_transverter_mode_isSet){
isObjectUpdated = true; break;
}
if(m_transverter_delta_frequency_isSet){
isObjectUpdated = true; break;
}
if(m_iq_order_isSet){
isObjectUpdated = true; break;
}
if(m_stream_index_isSet){
isObjectUpdated = true; break;
}
if(m_spectrum_stream_index_isSet){
isObjectUpdated = true; break;
}
if(m_tx_enable_isSet){
isObjectUpdated = true; break;
}
if(rx_device_name && *rx_device_name != QString("")){
isObjectUpdated = true; break;
}
if(m_rx_iq_mapping_isSet){
isObjectUpdated = true; break;
}
if(m_log2_decim_isSet){
isObjectUpdated = true; break;
}
if(m_fc_pos_rx_isSet){
isObjectUpdated = true; break;
}
if(m_dc_block_isSet){
isObjectUpdated = true; break;
}
if(m_iq_correction_isSet){
isObjectUpdated = true; break;
}
if(m_rx_volume_isSet){
isObjectUpdated = true; break;
}
if(tx_device_name && *tx_device_name != QString("")){
isObjectUpdated = true; break;
}
if(m_tx_iq_mapping_isSet){
isObjectUpdated = true; break;
}
if(m_log2_interp_isSet){
isObjectUpdated = true; break;
}
if(m_fc_pos_tx_isSet){
isObjectUpdated = true; break;
}
if(m_tx_volume_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_device_index_isSet){
isObjectUpdated = true; break;
}
}while(false);
return isObjectUpdated;
}
}

Wyświetl plik

@ -0,0 +1,197 @@
/**
* 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.
*/
/*
* SWGAudioCATSISOSettings.h
*
* AudioCATSISO
*/
#ifndef SWGAudioCATSISOSettings_H_
#define SWGAudioCATSISOSettings_H_
#include <QJsonObject>
#include <QString>
#include "SWGObject.h"
#include "export.h"
namespace SWGSDRangel {
class SWG_API SWGAudioCATSISOSettings: public SWGObject {
public:
SWGAudioCATSISOSettings();
SWGAudioCATSISOSettings(QString* json);
virtual ~SWGAudioCATSISOSettings();
void init();
void cleanup();
virtual QString asJson () override;
virtual QJsonObject* asJsonObject() override;
virtual void fromJsonObject(QJsonObject &json) override;
virtual SWGAudioCATSISOSettings* fromJson(QString &jsonString) override;
qint64 getRxCenterFrequency();
void setRxCenterFrequency(qint64 rx_center_frequency);
qint64 getTxCenterFrequency();
void setTxCenterFrequency(qint64 tx_center_frequency);
qint32 getTransverterMode();
void setTransverterMode(qint32 transverter_mode);
qint64 getTransverterDeltaFrequency();
void setTransverterDeltaFrequency(qint64 transverter_delta_frequency);
qint32 getIqOrder();
void setIqOrder(qint32 iq_order);
qint32 getStreamIndex();
void setStreamIndex(qint32 stream_index);
qint32 getSpectrumStreamIndex();
void setSpectrumStreamIndex(qint32 spectrum_stream_index);
qint32 getTxEnable();
void setTxEnable(qint32 tx_enable);
QString* getRxDeviceName();
void setRxDeviceName(QString* rx_device_name);
qint32 getRxIqMapping();
void setRxIqMapping(qint32 rx_iq_mapping);
qint32 getLog2Decim();
void setLog2Decim(qint32 log2_decim);
qint32 getFcPosRx();
void setFcPosRx(qint32 fc_pos_rx);
qint32 getDcBlock();
void setDcBlock(qint32 dc_block);
qint32 getIqCorrection();
void setIqCorrection(qint32 iq_correction);
float getRxVolume();
void setRxVolume(float rx_volume);
QString* getTxDeviceName();
void setTxDeviceName(QString* tx_device_name);
qint32 getTxIqMapping();
void setTxIqMapping(qint32 tx_iq_mapping);
qint32 getLog2Interp();
void setLog2Interp(qint32 log2_interp);
qint32 getFcPosTx();
void setFcPosTx(qint32 fc_pos_tx);
float getTxVolume();
void setTxVolume(float tx_volume);
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 getReverseApiDeviceIndex();
void setReverseApiDeviceIndex(qint32 reverse_api_device_index);
virtual bool isSet() override;
private:
qint64 rx_center_frequency;
bool m_rx_center_frequency_isSet;
qint64 tx_center_frequency;
bool m_tx_center_frequency_isSet;
qint32 transverter_mode;
bool m_transverter_mode_isSet;
qint64 transverter_delta_frequency;
bool m_transverter_delta_frequency_isSet;
qint32 iq_order;
bool m_iq_order_isSet;
qint32 stream_index;
bool m_stream_index_isSet;
qint32 spectrum_stream_index;
bool m_spectrum_stream_index_isSet;
qint32 tx_enable;
bool m_tx_enable_isSet;
QString* rx_device_name;
bool m_rx_device_name_isSet;
qint32 rx_iq_mapping;
bool m_rx_iq_mapping_isSet;
qint32 log2_decim;
bool m_log2_decim_isSet;
qint32 fc_pos_rx;
bool m_fc_pos_rx_isSet;
qint32 dc_block;
bool m_dc_block_isSet;
qint32 iq_correction;
bool m_iq_correction_isSet;
float rx_volume;
bool m_rx_volume_isSet;
QString* tx_device_name;
bool m_tx_device_name_isSet;
qint32 tx_iq_mapping;
bool m_tx_iq_mapping_isSet;
qint32 log2_interp;
bool m_log2_interp_isSet;
qint32 fc_pos_tx;
bool m_fc_pos_tx_isSet;
float tx_volume;
bool m_tx_volume_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_device_index;
bool m_reverse_api_device_index_isSet;
};
}
#endif /* SWGAudioCATSISOSettings_H_ */

Wyświetl plik

@ -38,6 +38,8 @@ SWGDeviceSettings::SWGDeviceSettings() {
m_airspy_settings_isSet = false;
airspy_hf_settings = nullptr;
m_airspy_hf_settings_isSet = false;
audio_catsiso_settings = nullptr;
m_audio_catsiso_settings_isSet = false;
audio_input_settings = nullptr;
m_audio_input_settings_isSet = false;
audio_output_settings = nullptr;
@ -142,6 +144,8 @@ SWGDeviceSettings::init() {
m_airspy_settings_isSet = false;
airspy_hf_settings = new SWGAirspyHFSettings();
m_airspy_hf_settings_isSet = false;
audio_catsiso_settings = new SWGAudioCATSISOSettings();
m_audio_catsiso_settings_isSet = false;
audio_input_settings = new SWGAudioInputSettings();
m_audio_input_settings_isSet = false;
audio_output_settings = new SWGAudioOutputSettings();
@ -243,6 +247,9 @@ SWGDeviceSettings::cleanup() {
if(airspy_hf_settings != nullptr) {
delete airspy_hf_settings;
}
if(audio_catsiso_settings != nullptr) {
delete audio_catsiso_settings;
}
if(audio_input_settings != nullptr) {
delete audio_input_settings;
}
@ -395,6 +402,8 @@ SWGDeviceSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&airspy_hf_settings, pJson["airspyHFSettings"], "SWGAirspyHFSettings", "SWGAirspyHFSettings");
::SWGSDRangel::setValue(&audio_catsiso_settings, pJson["audioCATSISOSettings"], "SWGAudioCATSISOSettings", "SWGAudioCATSISOSettings");
::SWGSDRangel::setValue(&audio_input_settings, pJson["audioInputSettings"], "SWGAudioInputSettings", "SWGAudioInputSettings");
::SWGSDRangel::setValue(&audio_output_settings, pJson["audioOutputSettings"], "SWGAudioOutputSettings", "SWGAudioOutputSettings");
@ -512,6 +521,9 @@ SWGDeviceSettings::asJsonObject() {
if((airspy_hf_settings != nullptr) && (airspy_hf_settings->isSet())){
toJsonValue(QString("airspyHFSettings"), airspy_hf_settings, obj, QString("SWGAirspyHFSettings"));
}
if((audio_catsiso_settings != nullptr) && (audio_catsiso_settings->isSet())){
toJsonValue(QString("audioCATSISOSettings"), audio_catsiso_settings, obj, QString("SWGAudioCATSISOSettings"));
}
if((audio_input_settings != nullptr) && (audio_input_settings->isSet())){
toJsonValue(QString("audioInputSettings"), audio_input_settings, obj, QString("SWGAudioInputSettings"));
}
@ -695,6 +707,16 @@ SWGDeviceSettings::setAirspyHfSettings(SWGAirspyHFSettings* airspy_hf_settings)
this->m_airspy_hf_settings_isSet = true;
}
SWGAudioCATSISOSettings*
SWGDeviceSettings::getAudioCatsisoSettings() {
return audio_catsiso_settings;
}
void
SWGDeviceSettings::setAudioCatsisoSettings(SWGAudioCATSISOSettings* audio_catsiso_settings) {
this->audio_catsiso_settings = audio_catsiso_settings;
this->m_audio_catsiso_settings_isSet = true;
}
SWGAudioInputSettings*
SWGDeviceSettings::getAudioInputSettings() {
return audio_input_settings;
@ -1145,6 +1167,9 @@ SWGDeviceSettings::isSet(){
if(airspy_hf_settings && airspy_hf_settings->isSet()){
isObjectUpdated = true; break;
}
if(audio_catsiso_settings && audio_catsiso_settings->isSet()){
isObjectUpdated = true; break;
}
if(audio_input_settings && audio_input_settings->isSet()){
isObjectUpdated = true; break;
}

Wyświetl plik

@ -26,6 +26,7 @@
#include "SWGAaroniaRTSASettings.h"
#include "SWGAirspyHFSettings.h"
#include "SWGAirspySettings.h"
#include "SWGAudioCATSISOSettings.h"
#include "SWGAudioInputSettings.h"
#include "SWGAudioOutputSettings.h"
#include "SWGBladeRF1InputSettings.h"
@ -102,6 +103,9 @@ public:
SWGAirspyHFSettings* getAirspyHfSettings();
void setAirspyHfSettings(SWGAirspyHFSettings* airspy_hf_settings);
SWGAudioCATSISOSettings* getAudioCatsisoSettings();
void setAudioCatsisoSettings(SWGAudioCATSISOSettings* audio_catsiso_settings);
SWGAudioInputSettings* getAudioInputSettings();
void setAudioInputSettings(SWGAudioInputSettings* audio_input_settings);
@ -250,6 +254,9 @@ private:
SWGAirspyHFSettings* airspy_hf_settings;
bool m_airspy_hf_settings_isSet;
SWGAudioCATSISOSettings* audio_catsiso_settings;
bool m_audio_catsiso_settings_isSet;
SWGAudioInputSettings* audio_input_settings;
bool m_audio_input_settings_isSet;

Wyświetl plik

@ -54,6 +54,7 @@
#include "SWGAntennaToolsSettings.h"
#include "SWGArgInfo.h"
#include "SWGArgValue.h"
#include "SWGAudioCATSISOSettings.h"
#include "SWGAudioDevices.h"
#include "SWGAudioInputDevice.h"
#include "SWGAudioInputSettings.h"
@ -559,6 +560,11 @@ namespace SWGSDRangel {
obj->init();
return obj;
}
if(QString("SWGAudioCATSISOSettings").compare(type) == 0) {
SWGAudioCATSISOSettings *obj = new SWGAudioCATSISOSettings();
obj->init();
return obj;
}
if(QString("SWGAudioDevices").compare(type) == 0) {
SWGAudioDevices *obj = new SWGAudioDevices();
obj->init();