Merge pull request #1906 from srcejon/freq_scanner

Variety of small fixes
This commit is contained in:
Edouard Griffiths 2023-12-02 11:11:28 +01:00 committed by GitHub
commit e3d862c8a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 100 additions and 30 deletions

View File

@ -108,8 +108,6 @@ jobs:
fetch-depth: 0
- name: Update brew
run: brew update
- name: Install brew packages
run: brew install nasm boost hidapi libusb fftw ffmpeg faad2 zlib airspy airspyhf hackrf rtl-sdr libbladerf soapysdr qt
- name: Install brew uhd package
run: |
rm -f /usr/local/bin/2to3*
@ -122,6 +120,8 @@ jobs:
run: |
rm -f /usr/local/bin/2to3
brew install opencv
- name: Install brew packages
run: brew install nasm boost hidapi libusb fftw ffmpeg faad2 zlib airspy airspyhf hackrf rtl-sdr libbladerf soapysdr qt
- name: Configure SDRangel
run: |
mkdir build && cd build

View File

@ -31,6 +31,15 @@ set(SOAPYSDR_REMOTE_TAG "soapy-remote-0.5.1")
set(AIRSPY_TAG "37c768ce9997b32e7328eb48972a7fda0a1f8554")
set(HACKRF_TAG "v2022.09.1")
set(LIBXML2_TAG "v2.10.4")
set(UHD_TAG "v4.5.0.0")
if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64))
# UHD fails to load with 1.80+
set(BOOST_TAG "1.78.0")
set(BOOST_TAG2 "1_78_0")
else()
set(BOOST_TAG "1.83.0")
set(BOOST_TAG2 "1_83_0")
endif()
# For some external project macros
include(ExternalProject)
@ -340,7 +349,7 @@ endif (NOT FFTW3F_FOUND AND NOT USE_PRECOMPILED_LIBS)
# So instead, we use FetchContent and build Boost at CMake configure time
include(FetchContent)
FetchContent_Declare(boost
URL https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.gz
URL "https://sourceforge.net/projects/boost/files/boost/${BOOST_TAG}/boost_${BOOST_TAG2}.tar.gz/download"
)
find_package(Boost QUIET)
@ -483,7 +492,11 @@ if (NOT FFMPEG_FOUND AND NOT USE_PRECOMPILED_LIBS)
# ffmpeg doesn't try to use pkg-config for lame, as it doesn't include a .pc file
#set(LAME_PKG_CONFIG_DIR "${install_dir}/lib/pkgconfig")
set(LAME_EXTRA_CFLAGS "-I${install_dir}/include")
set(LAME_EXTRA_LDFLAGS "-L${install_dir}/lib")
if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL arm64))
set(LAME_EXTRA_LDFLAGS "-L${install_dir}/lib -Wl,-ld_classic")
else()
set(LAME_EXTRA_LDFLAGS "-L${install_dir}/lib")
endif()
set_global_cache(LAME_FOUND ON)
set(LAME_EXTERNAL ON CACHE INTERNAL "")
if (APPLE)
@ -1491,7 +1504,7 @@ if (WIN32 OR APPLE)
endif ()
ExternalProject_Add(uhd
GIT_REPOSITORY https://github.com/EttusResearch/uhd.git
GIT_TAG v4.5.0.0
GIT_TAG ${UHD_TAG}
DEPENDS ${LIBUSB_DEPENDS} ${Boost_DEPENDS}
PREFIX "${EXTERNAL_BUILD_LIBRARIES}/uhd"
SOURCE_SUBDIR "host"

View File

@ -249,7 +249,7 @@ bool FreqScanner::handleMessage(const Message& cmd)
}
else if (MsgStartScan::match(cmd))
{
muteAll();
muteAll(m_settings);
startScan();
return true;
@ -657,14 +657,14 @@ void FreqScanner::setCenterFrequency(qint64 frequency)
}
// Mute all channels
void FreqScanner::muteAll()
void FreqScanner::muteAll(const FreqScannerSettings& settings)
{
QStringList channels;
channels.append(m_settings.m_channel);
for (int i = 0; i < m_settings.m_frequencySettings.size(); i++)
channels.append(settings.m_channel);
for (int i = 0; i < settings.m_frequencySettings.size(); i++)
{
QString channel = m_settings.m_frequencySettings[i].m_channel;
QString channel = settings.m_frequencySettings[i].m_channel;
if (!channel.isEmpty() && !channels.contains(channel)) {
channels.append(channel);
}

View File

@ -350,6 +350,7 @@ public:
uint32_t getNumberOfDeviceStreams() const;
void calcScannerSampleRate(int channelBW, int basebandSampleRate, int& scannerSampleRate, int& fftSize, int& binsPerChannel);
static void muteAll(const FreqScannerSettings& settings);
static const char * const m_channelIdURI;
static const char * const m_channelId;
@ -408,7 +409,6 @@ private:
void processScanResults(const QDateTime& fftStartTime, const QList<MsgScanResult::ScanResult>& results);
void setDeviceCenterFrequency(qint64 frequency);
void applyChannelSetting(const QString& channel);
void muteAll();
static QList<SWGSDRangel::SWGFreqScannerFrequency *> *createFrequencyList(const FreqScannerSettings& settings);

View File

@ -932,18 +932,29 @@ void FreqScannerGUI::table_customContextMenuRequested(QPoint pos)
// Tune to frequency
qint64 frequency = ui->table->item(row, COL_FREQUENCY)->text().toLongLong();
FreqScannerSettings::FrequencySettings *frequencySettings = m_settings.getFrequencySettings(frequency);
QString channel = m_settings.getChannel(frequencySettings);
const QRegExp re("R([0-9]+):([0-9]+)");
if (re.indexIn(m_settings.m_channel) >= 0)
if (re.indexIn(channel) >= 0)
{
int scanDeviceSetIndex = re.capturedTexts()[1].toInt();
int scanChannelIndex = re.capturedTexts()[2].toInt();
qDebug() << "scanDeviceSetIndex" << scanDeviceSetIndex << "scanChannelIndex" << scanChannelIndex;
qint64 frequency = ui->table->item(row, COL_FREQUENCY)->text().toLongLong();
ButtonSwitch *startStop = ui->startStop;
QAction* findChannelMapAction = new QAction(QString("Tune R%1:%2 to %3").arg(scanDeviceSetIndex).arg(scanChannelIndex).arg(frequency), tableContextMenu);
connect(findChannelMapAction, &QAction::triggered, this, [this, scanDeviceSetIndex, scanChannelIndex, frequency]()->void {
connect(findChannelMapAction, &QAction::triggered, this, [this, scanDeviceSetIndex, scanChannelIndex, frequency, startStop]()->void {
// Stop scanning
if (startStop->isChecked()) {
startStop->click();
}
// Mute all channels
m_freqScanner->muteAll(m_settings);
// Tune to frequency
if ((frequency - m_settings.m_channelBandwidth / 2 < m_deviceCenterFrequency - m_basebandSampleRate / 2)
|| (frequency + m_settings.m_channelBandwidth / 2 >= m_deviceCenterFrequency + m_basebandSampleRate / 2))
{
@ -958,7 +969,6 @@ void FreqScannerGUI::table_customContextMenuRequested(QPoint pos)
if (!ChannelWebAPIUtils::setCenterFrequency(getDeviceSetIndex(), centerFrequency)) {
qWarning() << "Scanner failed to set frequency" << centerFrequency;
}
ChannelWebAPIUtils::setFrequencyOffset(scanDeviceSetIndex, scanChannelIndex, offset);
}
else
@ -967,6 +977,9 @@ void FreqScannerGUI::table_customContextMenuRequested(QPoint pos)
ChannelWebAPIUtils::setFrequencyOffset(scanDeviceSetIndex, scanChannelIndex, offset);
}
// Unmute channel
ChannelWebAPIUtils::setAudioMute(scanDeviceSetIndex, scanChannelIndex, false);
});
tableContextMenu->addAction(findChannelMapAction);
}

View File

@ -420,6 +420,15 @@ QDataStream& operator>>(QDataStream& in, FreqScannerSettings::FrequencySettings&
return in;
}
QString FreqScannerSettings::getChannel(FreqScannerSettings::FrequencySettings *frequencySettings) const
{
QString channel = m_channel;
if (!frequencySettings->m_channel.isEmpty()) {
channel = frequencySettings->m_channel;
}
return channel;
}
Real FreqScannerSettings::getThreshold(FreqScannerSettings::FrequencySettings *frequencySettings) const
{
Real threshold = m_threshold;

View File

@ -103,6 +103,7 @@ struct FreqScannerSettings
bool deserialize(const QByteArray& data);
void applySettings(const QStringList& settingsKeys, const FreqScannerSettings& settings);
QString getDebugString(const QStringList& settingsKeys, bool force = false) const;
QString getChannel(FreqScannerSettings::FrequencySettings *frequencySettings) const;
Real getThreshold(FreqScannerSettings::FrequencySettings *frequencySettings) const;
int getChannelBandwidth(FreqScannerSettings::FrequencySettings *frequencySettings) const;
FreqScannerSettings::FrequencySettings *getFrequencySettings(qint64 frequency);

View File

@ -510,8 +510,10 @@ QJsonObject CZML::update(ObjectMapItem *mapItem, bool isTarget, bool isSelected)
QJsonObject labelDistanceDisplayCondition {
{"distanceDisplayCondition", labelDisplayDistance}
};
QString labelText = mapItem->m_label;
labelText.replace("<br>", "\n");
QJsonObject label {
{"text", mapItem->m_label},
{"text", labelText},
{"show", m_settings->m_displayNames && mapItem->m_itemSettings->m_enabled && mapItem->m_itemSettings->m_display3DLabel},
{"scale", mapItem->m_itemSettings->m_3DLabelScale},
{"pixelOffset", labelPixelOffset},

View File

@ -719,6 +719,7 @@ void SimplePTTGUI::audioSelect(const QPoint& p)
qDebug("SimplePTTGUI::audioSelect");
AudioSelectDialog audioSelect(DSPEngine::instance()->getAudioDeviceManager(), m_settings.m_audioDeviceName, true);
audioSelect.move(p);
new DialogPositioner(&audioSelect, false);
audioSelect.exec();
if (audioSelect.m_selected)

View File

@ -292,7 +292,8 @@ int AirspyHFInput::getSampleRate() const
uint32_t AirspyHFInput::getSampleRateFromIndex(quint32 devSampleRateIndex) const
{
int index;
int index = (int) devSampleRateIndex;
if (devSampleRateIndex >= m_sampleRates.size()) {
index = m_sampleRates.size() - 1;
}

View File

@ -56,6 +56,13 @@ target_link_libraries(${TARGET_NAME}
${SDRPLAY_LIBRARIES}
)
# Library name is wrong in 3.12 release
if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL arm64))
add_custom_command(TARGET ${TARGET_NAME}
POST_BUILD COMMAND
${CMAKE_INSTALL_NAME_TOOL} -change libsdrplay_api_arm64.so.3.12 /Library/SDRplayAPI/3.12.0/lib/libsdrplay_api.so.3.12.0 $<TARGET_FILE:${TARGET_NAME}>)
endif()
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
# Install debug symbols

View File

@ -43,25 +43,38 @@ static constexpr const char* const m_hardwareID = "SDRplayV3";
static constexpr const char* const m_deviceTypeID = SDRPLAYV3_DEVICE_TYPE_ID;
SDRPlayV3Plugin::SDRPlayV3Plugin(QObject* parent) :
QObject(parent)
QObject(parent),
m_opened(false)
{
sdrplay_api_ErrT err;
float ver = 0.0f;
qDebug() << "SDRPlayV3Plugin: calling sdrplay_api_Open()";
if ((err = sdrplay_api_Open()) != sdrplay_api_Success)
if ((err = sdrplay_api_Open()) == sdrplay_api_Success)
{
m_opened = true;
if ((err = sdrplay_api_ApiVersion(&ver)) == sdrplay_api_Success)
{
if (ver != SDRPLAY_API_VERSION) {
qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: SDRPlay API versions do not match " << ver << " " << SDRPLAY_API_VERSION;
}
}
else
{
qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: failed to get SDRPlay API version.";
}
}
else
{
qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: sdrplay_api_Open() was unsuccessful. " << sdrplay_api_GetErrorString(err);
if ((err = sdrplay_api_ApiVersion(&ver)) != sdrplay_api_Success)
qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: failed to get SDRPlay API version.";
if (ver != SDRPLAY_API_VERSION)
qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: SDRPlay API versions do not match " << ver << " " << SDRPLAY_API_VERSION;
}
}
SDRPlayV3Plugin::~SDRPlayV3Plugin()
{
sdrplay_api_Close();
if (m_opened) {
sdrplay_api_Close();
}
}
const PluginDescriptor& SDRPlayV3Plugin::getPluginDescriptor() const

View File

@ -52,6 +52,7 @@ public:
virtual DeviceWebAPIAdapter* createDeviceWebAPIAdapter() const;
private:
bool m_opened; // Whether sdrplay_api_Open was successful
static const PluginDescriptor m_pluginDescriptor;
};

View File

@ -116,14 +116,14 @@ unsigned int DataFifo::write(const quint8* data, unsigned int count, DataType da
{
m_suppressed = 0;
m_msgRateTimer.start();
qCritical("DataFifo::write: overflow - dropping %u samples", count - total);
qCritical("DataFifo::write: overflow - dropping %u samples (size=%u)", count - total, m_size);
}
else
{
if (m_msgRateTimer.elapsed() > 2500)
{
qCritical("DataFifo::write: %u messages dropped", m_suppressed);
qCritical("DataFifo::write: overflow - dropping %u samples", count - total);
qCritical("DataFifo::write: overflow - dropping %u samples (size=%u)", count - total, m_size);
m_suppressed = -1;
}
else

View File

@ -60,6 +60,9 @@ public:
}
// Print taps as a Matlab vector
// To view:
// h=fvtool(filter);
// h.Fs=...
void printTaps(const char *name)
{
printf("%s = [", name);

View File

@ -8,6 +8,12 @@ The `compose` folder contains files to build the Docker compose stack comprising
The SDRangel source tree is mounted in both containers as writable so the generated code can be written directly from the code generator or the Swagger files served by the http server.
<h2>Install Docker on Ubuntu</h2>
sudo apt install docker.io docker-buildx docker-compose
sudo usermod -aG docker $USER
* reboot *
<h2>Server</h2>
Use `build.sh` to build the image. It takes the following arguments: