mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-07-04 18:05:24 -04:00
VOR Localizer:
Add support for devices such as File Input for which the center frequency can't be changed. Use device b/w instead of channel b/w, as the latter may be decimated.
This commit is contained in:
parent
2f1fe7ecb3
commit
cfa50510e8
@ -24,7 +24,11 @@
|
|||||||
#include "SWGErrorResponse.h"
|
#include "SWGErrorResponse.h"
|
||||||
|
|
||||||
#include "device/deviceset.h"
|
#include "device/deviceset.h"
|
||||||
|
#include "device/deviceapi.h"
|
||||||
|
#include "dsp/devicesamplesource.h"
|
||||||
|
#include "dsp/devicesamplesink.h"
|
||||||
#include "channel/channelapi.h"
|
#include "channel/channelapi.h"
|
||||||
|
#include "channel/channelwebapiutils.h"
|
||||||
#include "webapi/webapiadapterinterface.h"
|
#include "webapi/webapiadapterinterface.h"
|
||||||
#include "webapi/webapiutils.h"
|
#include "webapi/webapiutils.h"
|
||||||
#include "maincore.h"
|
#include "maincore.h"
|
||||||
@ -78,6 +82,7 @@ void VorLocalizerWorker::started()
|
|||||||
m_rrTimer.start(m_settings.m_rrTime * 1000);
|
m_rrTimer.start(m_settings.m_rrTime * 1000);
|
||||||
disconnect(thread(), SIGNAL(started()), this, SLOT(started()));
|
disconnect(thread(), SIGNAL(started()), this, SLOT(started()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VorLocalizerWorker::stopWork()
|
void VorLocalizerWorker::stopWork()
|
||||||
{
|
{
|
||||||
QMutexLocker mutexLocker(&m_mutex);
|
QMutexLocker mutexLocker(&m_mutex);
|
||||||
@ -205,6 +210,53 @@ void VorLocalizerWorker::updateHardware()
|
|||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quint64 VorLocalizerWorker::getDeviceCenterFrequency(int deviceIndex)
|
||||||
|
{
|
||||||
|
std::vector<DeviceSet*> deviceSets = MainCore::instance()->getDeviceSets();
|
||||||
|
if (deviceIndex < deviceSets.size())
|
||||||
|
{
|
||||||
|
DeviceSet *deviceSet = deviceSets[deviceIndex];
|
||||||
|
if (deviceSet->m_deviceSourceEngine)
|
||||||
|
{
|
||||||
|
DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource();
|
||||||
|
return source->getCenterFrequency();
|
||||||
|
}
|
||||||
|
else if (deviceSet->m_deviceSinkEngine)
|
||||||
|
{
|
||||||
|
DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink();
|
||||||
|
return sink->getCenterFrequency();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VorLocalizerWorker::getDeviceSampleRate(int deviceIndex)
|
||||||
|
{
|
||||||
|
std::vector<DeviceSet*> deviceSets = MainCore::instance()->getDeviceSets();
|
||||||
|
if (deviceIndex < deviceSets.size())
|
||||||
|
{
|
||||||
|
DeviceSet *deviceSet = deviceSets[deviceIndex];
|
||||||
|
if (deviceSet->m_deviceSourceEngine)
|
||||||
|
{
|
||||||
|
DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource();
|
||||||
|
return source->getSampleRate();
|
||||||
|
}
|
||||||
|
else if (deviceSet->m_deviceSinkEngine)
|
||||||
|
{
|
||||||
|
DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink();
|
||||||
|
return sink->getSampleRate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does this device have a center frequency setting (FileInput doesn't)
|
||||||
|
bool VorLocalizerWorker::hasCenterFrequencySetting(int deviceIndex)
|
||||||
|
{
|
||||||
|
double deviceFrequency;
|
||||||
|
return !ChannelWebAPIUtils::getCenterFrequency(deviceIndex, deviceFrequency);
|
||||||
|
}
|
||||||
|
|
||||||
void VorLocalizerWorker::removeVORChannel(int navId)
|
void VorLocalizerWorker::removeVORChannel(int navId)
|
||||||
{
|
{
|
||||||
qDebug("VorLocalizerWorker::removeVORChannel: %d", navId);
|
qDebug("VorLocalizerWorker::removeVORChannel: %d", navId);
|
||||||
@ -294,7 +346,12 @@ void VorLocalizerWorker::updateChannels()
|
|||||||
RRTurnPlan turnPlan(deviceChannel);
|
RRTurnPlan turnPlan(deviceChannel);
|
||||||
int fMin = vorList.front().m_frequency;
|
int fMin = vorList.front().m_frequency;
|
||||||
int fMax = vorList.back().m_frequency;
|
int fMax = vorList.back().m_frequency;
|
||||||
int devFreq = (fMin + fMax) / 2;
|
int devFreq;
|
||||||
|
if (turnPlan.m_fixedCenterFrequency) {
|
||||||
|
devFreq = getDeviceCenterFrequency(turnPlan.m_device.m_deviceIndex);
|
||||||
|
} else {
|
||||||
|
devFreq = (fMin + fMax) / 2;
|
||||||
|
}
|
||||||
turnPlan.m_device.m_frequency = devFreq;
|
turnPlan.m_device.m_frequency = devFreq;
|
||||||
int iCh = 0;
|
int iCh = 0;
|
||||||
|
|
||||||
@ -321,7 +378,6 @@ void VorLocalizerWorker::updateChannels()
|
|||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iCh++;
|
iCh++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +415,12 @@ void VorLocalizerWorker::updateChannels()
|
|||||||
RRTurnPlan turnPlan(deviceChannel);
|
RRTurnPlan turnPlan(deviceChannel);
|
||||||
int fMin = vorList.front().m_frequency;
|
int fMin = vorList.front().m_frequency;
|
||||||
int fMax = vorList.back().m_frequency;
|
int fMax = vorList.back().m_frequency;
|
||||||
int devFreq = (fMin + fMax) / 2;
|
int devFreq;
|
||||||
|
if (turnPlan.m_fixedCenterFrequency) {
|
||||||
|
devFreq = getDeviceCenterFrequency(turnPlan.m_device.m_deviceIndex);
|
||||||
|
} else {
|
||||||
|
devFreq = (fMin + fMax) / 2;
|
||||||
|
}
|
||||||
turnPlan.m_device.m_frequency = devFreq;
|
turnPlan.m_device.m_frequency = devFreq;
|
||||||
int iCh = 0;
|
int iCh = 0;
|
||||||
|
|
||||||
@ -406,69 +467,6 @@ void VorLocalizerWorker::updateChannels()
|
|||||||
rrNextTurn();
|
rrNextTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VorLocalizerWorker::allocateChannel(ChannelAPI *channel, int vorFrequency, int vorNavId, int channelShift)
|
|
||||||
{
|
|
||||||
VORLocalizerSettings::AvailableChannel& availableChannel = m_availableChannels->operator[](channel);
|
|
||||||
qDebug() << "VorLocalizerWorker::allocateChannel:"
|
|
||||||
<< " vorNavId:" << vorNavId
|
|
||||||
<< " vorFrequency:" << vorFrequency
|
|
||||||
<< " channelShift:" << channelShift
|
|
||||||
<< " deviceIndex:" << availableChannel.m_deviceSetIndex
|
|
||||||
<< " channelIndex:" << availableChannel.m_channelIndex;
|
|
||||||
double deviceFrequency = vorFrequency - channelShift;
|
|
||||||
setDeviceFrequency(availableChannel.m_deviceSetIndex, deviceFrequency);
|
|
||||||
setChannelShift(availableChannel.m_deviceSetIndex, availableChannel.m_channelIndex, channelShift, vorNavId);
|
|
||||||
availableChannel.m_navId = vorNavId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VorLocalizerWorker::setDeviceFrequency(int deviceIndex, double targetFrequency)
|
|
||||||
{
|
|
||||||
SWGSDRangel::SWGDeviceSettings deviceSettingsResponse;
|
|
||||||
SWGSDRangel::SWGErrorResponse errorResponse;
|
|
||||||
int httpRC;
|
|
||||||
|
|
||||||
// Get current device center frequency
|
|
||||||
httpRC = m_webAPIAdapterInterface->devicesetDeviceSettingsGet(
|
|
||||||
deviceIndex,
|
|
||||||
deviceSettingsResponse,
|
|
||||||
errorResponse
|
|
||||||
);
|
|
||||||
|
|
||||||
if (httpRC/100 != 2)
|
|
||||||
{
|
|
||||||
qWarning("VorLocalizerWorker::setDeviceFrequency: get device frequency error %d: %s",
|
|
||||||
httpRC, qPrintable(*errorResponse.getMessage()));
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject *jsonObj = deviceSettingsResponse.asJsonObject();
|
|
||||||
|
|
||||||
// Update centerFrequency
|
|
||||||
WebAPIUtils::setSubObjectDouble(*jsonObj, "centerFrequency", targetFrequency);
|
|
||||||
QStringList deviceSettingsKeys;
|
|
||||||
deviceSettingsKeys.append("centerFrequency");
|
|
||||||
deviceSettingsResponse.init();
|
|
||||||
deviceSettingsResponse.fromJsonObject(*jsonObj);
|
|
||||||
SWGSDRangel::SWGErrorResponse errorResponse2;
|
|
||||||
|
|
||||||
httpRC = m_webAPIAdapterInterface->devicesetDeviceSettingsPutPatch(
|
|
||||||
deviceIndex,
|
|
||||||
false, // PATCH
|
|
||||||
deviceSettingsKeys,
|
|
||||||
deviceSettingsResponse,
|
|
||||||
errorResponse2
|
|
||||||
);
|
|
||||||
|
|
||||||
if (httpRC/100 == 2)
|
|
||||||
{
|
|
||||||
qDebug("VorLocalizerWorker::setDeviceFrequency: set device frequency %f OK", targetFrequency);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qWarning("VorLocalizerWorker::setDeviceFrequency: set device frequency error %d: %s",
|
|
||||||
httpRC, qPrintable(*errorResponse2.getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VorLocalizerWorker::setChannelShift(int deviceIndex, int channelIndex, double targetOffset, int vorNavId)
|
void VorLocalizerWorker::setChannelShift(int deviceIndex, int channelIndex, double targetOffset, int vorNavId)
|
||||||
{
|
{
|
||||||
SWGSDRangel::SWGChannelSettings channelSettingsResponse;
|
SWGSDRangel::SWGChannelSettings channelSettingsResponse;
|
||||||
@ -674,14 +672,16 @@ void VorLocalizerWorker::getChannelsByDevice(
|
|||||||
for (; itr != availableChannels->end(); ++itr)
|
for (; itr != availableChannels->end(); ++itr)
|
||||||
{
|
{
|
||||||
devicesChannelsMap[itr->m_deviceSetIndex].m_device.m_deviceIndex = itr->m_deviceSetIndex;
|
devicesChannelsMap[itr->m_deviceSetIndex].m_device.m_deviceIndex = itr->m_deviceSetIndex;
|
||||||
devicesChannelsMap[itr->m_deviceSetIndex].m_bandwidth = itr->m_basebandSampleRate;
|
devicesChannelsMap[itr->m_deviceSetIndex].m_bandwidth = getDeviceSampleRate(itr->m_deviceSetIndex); // Get b/w of device, not channel, as the latter may be decimated
|
||||||
devicesChannelsMap[itr->m_deviceSetIndex].m_channels.push_back(RRChannel{itr->m_channelAPI, itr->m_channelIndex, 0, -1});
|
devicesChannelsMap[itr->m_deviceSetIndex].m_channels.push_back(RRChannel{itr->m_channelAPI, itr->m_channelIndex, 0, -1});
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<int, RRTurnPlan>::const_iterator itm = devicesChannelsMap.begin();
|
QMap<int, RRTurnPlan>::iterator itm = devicesChannelsMap.begin();
|
||||||
devicesChannels.clear();
|
devicesChannels.clear();
|
||||||
|
|
||||||
for (; itm != devicesChannelsMap.end(); ++itm) {
|
for (; itm != devicesChannelsMap.end(); ++itm)
|
||||||
|
{
|
||||||
|
itm->m_fixedCenterFrequency = hasCenterFrequencySetting(itm->m_device.m_deviceIndex);
|
||||||
devicesChannels.push_back(*itm);
|
devicesChannels.push_back(*itm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,23 +700,32 @@ void VorLocalizerWorker::rrNextTurn()
|
|||||||
unsigned int turnCount = m_rrTurnCounters[iDevPlan];
|
unsigned int turnCount = m_rrTurnCounters[iDevPlan];
|
||||||
int deviceIndex = rrPlan[turnCount].m_device.m_deviceIndex;
|
int deviceIndex = rrPlan[turnCount].m_device.m_deviceIndex;
|
||||||
int deviceFrequency = rrPlan[turnCount].m_device.m_frequency - m_settings.m_centerShift;
|
int deviceFrequency = rrPlan[turnCount].m_device.m_frequency - m_settings.m_centerShift;
|
||||||
|
|
||||||
qDebug() << "VorLocalizerWorker::rrNextTurn: "
|
qDebug() << "VorLocalizerWorker::rrNextTurn: "
|
||||||
<< "turn:" << turnCount
|
<< "turn:" << turnCount
|
||||||
<< "device:" << deviceIndex
|
<< "device:" << deviceIndex
|
||||||
<< "frequency:" << deviceFrequency - m_settings.m_centerShift;
|
<< "frequency:" << deviceFrequency - m_settings.m_centerShift;
|
||||||
setDeviceFrequency(deviceIndex, deviceFrequency);
|
|
||||||
|
if (!rrPlan[turnCount].m_fixedCenterFrequency) {
|
||||||
|
ChannelWebAPIUtils::setCenterFrequency(deviceIndex, deviceFrequency);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto channel : rrPlan[turnCount].m_channels)
|
for (auto channel : rrPlan[turnCount].m_channels)
|
||||||
{
|
{
|
||||||
|
int shift = channel.m_frequencyShift;
|
||||||
|
if (!rrPlan[turnCount].m_fixedCenterFrequency) {
|
||||||
|
shift += m_settings.m_centerShift;
|
||||||
|
}
|
||||||
|
|
||||||
qDebug() << "VorLocalizerWorker::rrNextTurn: "
|
qDebug() << "VorLocalizerWorker::rrNextTurn: "
|
||||||
<< "device:" << deviceIndex
|
<< "device:" << deviceIndex
|
||||||
<< "channel:" << channel.m_channelIndex
|
<< "channel:" << channel.m_channelIndex
|
||||||
<< "shift:" << channel.m_frequencyShift + m_settings.m_centerShift
|
<< "shift:" << shift
|
||||||
<< "navId:" << channel.m_navId;
|
<< "navId:" << channel.m_navId;
|
||||||
setChannelShift(
|
setChannelShift(
|
||||||
deviceIndex,
|
deviceIndex,
|
||||||
channel.m_channelIndex,
|
channel.m_channelIndex,
|
||||||
channel.m_frequencyShift + m_settings.m_centerShift,
|
shift,
|
||||||
channel.m_navId
|
channel.m_navId
|
||||||
);
|
);
|
||||||
m_channelAllocations[channel.m_navId] = ChannelAllocation{
|
m_channelAllocations[channel.m_navId] = ChannelAllocation{
|
||||||
|
@ -121,6 +121,7 @@ private:
|
|||||||
RRDevice m_device;
|
RRDevice m_device;
|
||||||
int m_bandwidth;
|
int m_bandwidth;
|
||||||
std::vector<RRChannel> m_channels;
|
std::vector<RRChannel> m_channels;
|
||||||
|
bool m_fixedCenterFrequency; // Devices such as FileInput that can't have center freq changed
|
||||||
|
|
||||||
RRTurnPlan() = default;
|
RRTurnPlan() = default;
|
||||||
RRTurnPlan(const RRTurnPlan&) = default;
|
RRTurnPlan(const RRTurnPlan&) = default;
|
||||||
@ -157,10 +158,11 @@ private:
|
|||||||
void removeVORChannel(int navId);
|
void removeVORChannel(int navId);
|
||||||
void addVORChannel(const VORLocalizerSubChannelSettings& subChannelSettings);
|
void addVORChannel(const VORLocalizerSubChannelSettings& subChannelSettings);
|
||||||
void updateChannels(); //!< (re)allocate channels to service VORs
|
void updateChannels(); //!< (re)allocate channels to service VORs
|
||||||
void allocateChannel(ChannelAPI *channel, int vorFrequency, int vorNavId, int channelShift);
|
|
||||||
void setDeviceFrequency(int deviceIndex, double targetFrequency);
|
|
||||||
void setChannelShift(int deviceIndex, int channelIndex, double targetOffset, int vorNavId);
|
void setChannelShift(int deviceIndex, int channelIndex, double targetOffset, int vorNavId);
|
||||||
void setAudioMute(int vorNavId, bool audioMute);
|
void setAudioMute(int vorNavId, bool audioMute);
|
||||||
|
static quint64 getDeviceCenterFrequency(int deviceIndex);
|
||||||
|
static int getDeviceSampleRate(int deviceIndex);
|
||||||
|
static bool hasCenterFrequencySetting(int deviceIndex);
|
||||||
static void generateIndexCombinations(int length, int subLength, std::vector<std::vector<int>>& indexCombinations);
|
static void generateIndexCombinations(int length, int subLength, std::vector<std::vector<int>>& indexCombinations);
|
||||||
static void getVORRanges(const QList<VORLocalizerSettings::VORChannel>& vors, int subLength, std::vector<VORRange>& vorRanges);
|
static void getVORRanges(const QList<VORLocalizerSettings::VORChannel>& vors, int subLength, std::vector<VORRange>& vorRanges);
|
||||||
static void filterVORRanges(std::vector<VORRange>& vorRanges, int thresholdBW);
|
static void filterVORRanges(std::vector<VORRange>& vorRanges, int thresholdBW);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user