mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-02-03 09:44:01 -05:00
Perseus support (4)
This commit is contained in:
parent
becbe0f96e
commit
65174d7044
78
plugins/samplesource/perseus/CMakeLists.txt
Normal file
78
plugins/samplesource/perseus/CMakeLists.txt
Normal file
@ -0,0 +1,78 @@
|
||||
project(perseus)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
set(perseus_SOURCES
|
||||
# perseusgui.cpp
|
||||
# perseusinput.cpp
|
||||
# perseusplugin.cpp
|
||||
perseussettings.cpp
|
||||
# perseusthread.cpp
|
||||
)
|
||||
|
||||
set(perseus_HEADERS
|
||||
# perseusgui.h
|
||||
# perseusinput.h
|
||||
# perseusplugin.h
|
||||
perseussettings.h
|
||||
# perseusthread.h
|
||||
)
|
||||
|
||||
set(perseus_FORMS
|
||||
perseusgui.ui
|
||||
)
|
||||
|
||||
if (BUILD_DEBIAN)
|
||||
include_directories(
|
||||
.
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||
${LIBAIRSPYHFSRC}
|
||||
${LIBAIRSPYHFSRC}/libperseus/src
|
||||
)
|
||||
else (BUILD_DEBIAN)
|
||||
include_directories(
|
||||
.
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||
${LIBAIRSPYHF_INCLUDE_DIR}
|
||||
)
|
||||
endif (BUILD_DEBIAN)
|
||||
|
||||
#include(${QT_USE_FILE})
|
||||
#add_definitions(${QT_DEFINITIONS})
|
||||
add_definitions("${QT_DEFINITIONS} -DLIBAIRSPY_DYN_RATES")
|
||||
add_definitions(-DQT_PLUGIN)
|
||||
add_definitions(-DQT_SHARED)
|
||||
|
||||
#qt4_wrap_cpp(perseus_HEADERS_MOC ${perseus_HEADERS})
|
||||
qt5_wrap_ui(perseus_FORMS_HEADERS ${perseus_FORMS})
|
||||
|
||||
add_library(inputperseus SHARED
|
||||
${perseus_SOURCES}
|
||||
${perseus_HEADERS_MOC}
|
||||
${perseus_FORMS_HEADERS}
|
||||
)
|
||||
|
||||
if (BUILD_DEBIAN)
|
||||
target_link_libraries(inputperseus
|
||||
${QT_LIBRARIES}
|
||||
perseus
|
||||
sdrbase
|
||||
sdrgui
|
||||
swagger
|
||||
)
|
||||
else (BUILD_DEBIAN)
|
||||
target_link_libraries(inputperseus
|
||||
${QT_LIBRARIES}
|
||||
${LIBAIRSPYHF_LIBRARIES}
|
||||
sdrbase
|
||||
sdrgui
|
||||
swagger
|
||||
)
|
||||
endif (BUILD_DEBIAN)
|
||||
|
||||
|
||||
qt5_use_modules(inputperseus Core Widgets)
|
||||
|
||||
install(TARGETS inputperseus DESTINATION lib/plugins/samplesource)
|
199
plugins/samplesource/perseus/perseusinput.cpp
Normal file
199
plugins/samplesource/perseus/perseusinput.cpp
Normal file
@ -0,0 +1,199 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 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 //
|
||||
// //
|
||||
// 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 "SWGDeviceState.h"
|
||||
|
||||
#include "dsp/filerecord.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "device/devicesourceapi.h"
|
||||
|
||||
#include "perseusinput.h"
|
||||
#include "perseusthread.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(PerseusInput::MsgConfigurePerseus, Message)
|
||||
MESSAGE_CLASS_DEFINITION(PerseusInput::MsgFileRecord, Message)
|
||||
MESSAGE_CLASS_DEFINITION(PerseusInput::MsgStartStop, Message)
|
||||
|
||||
PerseusInput::PerseusInput(DeviceSourceAPI *deviceAPI) :
|
||||
m_deviceAPI(deviceAPI),
|
||||
m_fileSink(0),
|
||||
m_deviceDescription("PerseusInput"),
|
||||
m_running(false),
|
||||
m_perseusThread(0),
|
||||
m_perseusDescriptor(0)
|
||||
{
|
||||
openDevice();
|
||||
char recFileNameCStr[30];
|
||||
sprintf(recFileNameCStr, "test_%d.sdriq", m_deviceAPI->getDeviceUID());
|
||||
m_fileSink = new FileRecord(std::string(recFileNameCStr));
|
||||
m_deviceAPI->addSink(m_fileSink);
|
||||
}
|
||||
|
||||
PerseusInput::~PerseusInput()
|
||||
{
|
||||
m_deviceAPI->removeSink(m_fileSink);
|
||||
delete m_fileSink;
|
||||
closeDevice();
|
||||
}
|
||||
|
||||
void PerseusInput::destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void PerseusInput::init()
|
||||
{
|
||||
applySettings(m_settings, true);
|
||||
}
|
||||
|
||||
bool PerseusInput::start()
|
||||
{
|
||||
if (m_running) stop();
|
||||
|
||||
applySettings(m_settings, true);
|
||||
|
||||
// start / stop streaming is done in the thread.
|
||||
|
||||
if ((m_plutoSDRInputThread = new PlutoSDRInputThread(PLUTOSDR_BLOCKSIZE_SAMPLES, m_deviceShared.m_deviceParams->getBox(), &m_sampleFifo)) == 0)
|
||||
{
|
||||
qFatal("PlutoSDRInput::start: cannot create thread");
|
||||
stop();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("PlutoSDRInput::start: thread created");
|
||||
}
|
||||
|
||||
m_perseusThread->setLog2Decimation(m_settings.m_log2Decim);
|
||||
m_perseusThread->startWork();
|
||||
|
||||
m_running = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PerseusInput::stop()
|
||||
{
|
||||
if (m_perseusThread != 0)
|
||||
{
|
||||
m_perseusThread->stopWork();
|
||||
delete m_perseusThread;
|
||||
m_perseusThread = 0;
|
||||
}
|
||||
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
QByteArray PerseusInput::serialize() const
|
||||
{
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool PerseusInput::deserialize(const QByteArray& data)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (!m_settings.deserialize(data))
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
success = false;
|
||||
}
|
||||
|
||||
MsgConfigurePerseus* message = MsgConfigurePerseus::create(m_settings, true);
|
||||
m_inputMessageQueue.push(message);
|
||||
|
||||
if (m_guiMessageQueue)
|
||||
{
|
||||
MsgConfigurePerseus* messageToGUI = MsgConfigurePerseus::create(m_settings, true);
|
||||
m_guiMessageQueue->push(messageToGUI);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
const QString& PerseusInput::getDeviceDescription() const
|
||||
{
|
||||
return m_deviceDescription;
|
||||
}
|
||||
int PerseusInput::getSampleRate() const
|
||||
{
|
||||
return (m_settings.m_devSampleRate / (1<<m_settings.m_log2Decim));
|
||||
}
|
||||
|
||||
quint64 PerseusInput::getCenterFrequency() const
|
||||
{
|
||||
return m_settings.m_centerFrequency;
|
||||
}
|
||||
|
||||
void PerseusInput::setCenterFrequency(qint64 centerFrequency)
|
||||
{
|
||||
PerseusSettings settings = m_settings;
|
||||
settings.m_centerFrequency = centerFrequency;
|
||||
|
||||
MsgConfigurePerseus* message = MsgConfigurePerseus::create(settings, false);
|
||||
m_inputMessageQueue.push(message);
|
||||
|
||||
if (m_guiMessageQueue)
|
||||
{
|
||||
MsgConfigurePerseus* messageToGUI = MsgConfigurePerseus::create(settings, false);
|
||||
m_guiMessageQueue->push(messageToGUI);
|
||||
}
|
||||
}
|
||||
|
||||
bool PerseusInput::openDevice()
|
||||
{
|
||||
m_deviceAPI->getSampleSourceSerial();
|
||||
int deviceSequence = DevicePerseus::instance().getSequenceFromSerial(m_deviceAPI->getSampleSourceSerial().toStdString());
|
||||
|
||||
if ((m_perseusDescriptor = perseus_open(deviceSequence)) == 0)
|
||||
{
|
||||
qCritical("PerseusInput::openDevice: cannot open device: %s", perseus_errorstr());
|
||||
return false;
|
||||
}
|
||||
|
||||
int buf[32];
|
||||
m_sampleRates.clear();
|
||||
|
||||
if (perseus_get_sampling_rates(m_perseusDescriptor, buf, sizeof(buf)/sizeof(buf[0])) < 0)
|
||||
{
|
||||
qCritical("PerseusInput::openDevice: cannot get sampling rates: %s", perseus_errorstr());
|
||||
perseus_close(m_perseusDescriptor);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; (i < 32) && (buf[i] != 0); i++)
|
||||
{
|
||||
qDebug("PerseusInput::openDevice: sample rate: %d", buf[i]);
|
||||
m_sampleRates.push_back(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PerseusInput::closeDevice()
|
||||
{
|
||||
if (m_perseusDescriptor)
|
||||
{
|
||||
perseus_stop_async_input(m_perseusDescriptor);
|
||||
perseus_close(m_perseusDescriptor);
|
||||
}
|
||||
}
|
||||
|
137
plugins/samplesource/perseus/perseusinput.h
Normal file
137
plugins/samplesource/perseus/perseusinput.h
Normal file
@ -0,0 +1,137 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 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 //
|
||||
// //
|
||||
// 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 PLUGINS_SAMPLESOURCE_PERSEUS_PERSEUSINPUT_H_
|
||||
#define PLUGINS_SAMPLESOURCE_PERSEUS_PERSEUSINPUT_H_
|
||||
|
||||
#include <vector>
|
||||
#include "dsp/devicesamplesource.h"
|
||||
#include "util/message.h"
|
||||
#include "perseussettings.h"
|
||||
|
||||
class DeviceSourceAPI;
|
||||
class FileRecord;
|
||||
class PerseusThread;
|
||||
struct perseus_descr;
|
||||
|
||||
class PerseusInput : public DeviceSampleSource {
|
||||
public:
|
||||
class MsgConfigurePerseus : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const PerseusSettings& getSettings() const { return m_settings; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigurePerseus* create(const PerseusSettings& settings, bool force)
|
||||
{
|
||||
return new MsgConfigurePerseus(settings, force);
|
||||
}
|
||||
|
||||
private:
|
||||
PerseusSettings m_settings;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigurePerseus(const PerseusSettings& settings, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgFileRecord : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
bool getStartStop() const { return m_startStop; }
|
||||
|
||||
static MsgFileRecord* create(bool startStop) {
|
||||
return new MsgFileRecord(startStop);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool m_startStop;
|
||||
|
||||
MsgFileRecord(bool startStop) :
|
||||
Message(),
|
||||
m_startStop(startStop)
|
||||
{ }
|
||||
};
|
||||
|
||||
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)
|
||||
{ }
|
||||
};
|
||||
|
||||
PerseusInput(DeviceSourceAPI *deviceAPI);
|
||||
~PerseusInput();
|
||||
virtual void destroy();
|
||||
|
||||
virtual void init();
|
||||
virtual bool start();
|
||||
virtual void stop();
|
||||
|
||||
virtual QByteArray serialize() const;
|
||||
virtual bool deserialize(const QByteArray& data);
|
||||
|
||||
virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
|
||||
virtual const QString& getDeviceDescription() const;
|
||||
virtual int getSampleRate() const;
|
||||
virtual quint64 getCenterFrequency() const;
|
||||
virtual void setCenterFrequency(qint64 centerFrequency);
|
||||
|
||||
virtual bool handleMessage(const Message& message);
|
||||
|
||||
virtual int webapiRunGet(
|
||||
SWGSDRangel::SWGDeviceState& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiRun(
|
||||
bool run,
|
||||
SWGSDRangel::SWGDeviceState& response,
|
||||
QString& errorMessage);
|
||||
|
||||
private:
|
||||
DeviceSourceAPI *m_deviceAPI;
|
||||
FileRecord *m_fileSink;
|
||||
QString m_deviceDescription;
|
||||
PerseusSettings m_settings;
|
||||
bool m_running;
|
||||
PerseusThread *m_perseusThread;
|
||||
perseus_descr *m_perseusDescriptor;
|
||||
std::vector<uint32_t> m_sampleRates;
|
||||
QMutex m_mutex;
|
||||
|
||||
bool openDevice();
|
||||
void closeDevice();
|
||||
bool applySettings(const PerseusSettings& settings, bool force = false);
|
||||
};
|
||||
|
||||
#endif /* PLUGINS_SAMPLESOURCE_PERSEUS_PERSEUSINPUT_H_ */
|
95
plugins/samplesource/perseus/perseussettings.cpp
Normal file
95
plugins/samplesource/perseus/perseussettings.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 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 //
|
||||
// //
|
||||
// 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 "perseussettings.h"
|
||||
#include "util/simpleserializer.h"
|
||||
|
||||
|
||||
PerseusSettings::PerseusSettings()
|
||||
{
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
void PerseusSettings::resetToDefaults()
|
||||
{
|
||||
m_centerFrequency = 7150*1000;
|
||||
m_LOppmTenths = 0;
|
||||
m_devSampleRateIndex = 0;
|
||||
m_log2Decim = 0;
|
||||
m_transverterMode = false;
|
||||
m_transverterDeltaFrequency = 0;
|
||||
m_adcDither = false;
|
||||
m_adcPreamp = false;
|
||||
m_wideBand = false;
|
||||
m_attenuator = Attenuator_None;
|
||||
}
|
||||
|
||||
QByteArray PerseusSettings::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
|
||||
s.writeU32(1, m_devSampleRateIndex);
|
||||
s.writeS32(2, m_LOppmTenths);
|
||||
s.writeU32(3, m_log2Decim);
|
||||
s.writeBool(4, m_transverterMode);
|
||||
s.writeS64(5, m_transverterDeltaFrequency);
|
||||
s.writeBool(6, m_adcDither);
|
||||
s.writeBool(7, m_adcPreamp);
|
||||
s.writeBool(8, m_wideBand);
|
||||
s.writeS32(9, (int) m_attenuator);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
|
||||
bool PerseusSettings::deserialize(const QByteArray& data)
|
||||
{
|
||||
SimpleDeserializer d(data);
|
||||
|
||||
if (!d.isValid())
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d.getVersion() == 1)
|
||||
{
|
||||
int intval;
|
||||
|
||||
d.readU32(1, &m_devSampleRateIndex, 0);
|
||||
d.readS32(2, &m_LOppmTenths, 0);
|
||||
d.readU32(3, &m_log2Decim, 0);
|
||||
d.readBool(4, &m_transverterMode, false);
|
||||
d.readS64(5, &m_transverterDeltaFrequency, 0);
|
||||
d.readBool(6, &m_adcDither, false);
|
||||
d.readBool(7, &m_adcPreamp, false);
|
||||
d.readBool(8, &m_wideBand, false);
|
||||
d.readS32(9, &intval, 0);
|
||||
|
||||
if ((intval >= 0) && (intval < (int) Attenuator_last)) {
|
||||
m_attenuator = (Attenuator) intval;
|
||||
} else {
|
||||
m_attenuator = Attenuator_None;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
52
plugins/samplesource/perseus/perseussettings.h
Normal file
52
plugins/samplesource/perseus/perseussettings.h
Normal file
@ -0,0 +1,52 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 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 //
|
||||
// //
|
||||
// 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 PLUGINS_SAMPLESOURCE_PERSEUS_PERSEUSSETTINGS_H_
|
||||
#define PLUGINS_SAMPLESOURCE_PERSEUS_PERSEUSSETTINGS_H_
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
struct PerseusSettings
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
Attenuator_None,
|
||||
Attenuator_10dB,
|
||||
Attenuator_20dB,
|
||||
Attenuator_30dB,
|
||||
Attenuator_last
|
||||
} Attenuator;
|
||||
|
||||
quint64 m_centerFrequency;
|
||||
qint32 m_LOppmTenths;
|
||||
quint32 m_devSampleRateIndex;
|
||||
quint32 m_log2Decim;
|
||||
bool m_transverterMode;
|
||||
qint64 m_transverterDeltaFrequency;
|
||||
bool m_adcDither;
|
||||
bool m_adcPreamp;
|
||||
bool m_wideBand;
|
||||
Attenuator m_attenuator;
|
||||
|
||||
PerseusSettings();
|
||||
void resetToDefaults();
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* PLUGINS_SAMPLESOURCE_PERSEUS_PERSEUSSETTINGS_H_ */
|
Loading…
Reference in New Issue
Block a user