1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-08-14 23:43:43 -04:00

Merge branch 'f4exb:master' into fixes

This commit is contained in:
srcejon
2026-08-03 13:42:07 +01:00
committed by GitHub
7 changed files with 105 additions and 61 deletions
+54 -35
View File
@@ -23,6 +23,8 @@ Copyright 2018 Ahmet Inan <xdsopl@gmail.com>
#ifndef GENERIC_HH
#define GENERIC_HH
#include <vector>
#include "exclusive_reduce.h"
namespace ldpctool {
@@ -66,13 +68,15 @@ struct MinSumAlgorithm
}
static void finalp(TYPE *links, int cnt)
{
TYPE mags[cnt], mins[cnt];
std::vector<TYPE> mags(cnt);
std::vector<TYPE> mins(cnt);
std::vector<TYPE> signs(cnt);
for (int i = 0; i < cnt; ++i)
mags[i] = std::abs(links[i]);
CODE::exclusive_reduce(mags, mins, cnt, min);
TYPE signs[cnt];
CODE::exclusive_reduce(links, signs, cnt, sign);
CODE::exclusive_reduce(mags.data(), mins.data(), cnt, min);
CODE::exclusive_reduce(links, signs.data(), cnt, sign);
for (int i = 0; i < cnt; ++i)
links[i] = sign(mins[i], signs[i]);
@@ -117,18 +121,20 @@ struct MinSumAlgorithm<float, UPDATE>
static void finalp(float *links, int cnt)
{
int mask = 0x80000000;
float mags[cnt], mins[cnt];
std::vector<float> mags(cnt), mins(cnt);
std::vector<int> signs(cnt);
for (int i = 0; i < cnt; ++i)
mags[i] = std::abs(links[i]);
CODE::exclusive_reduce(mags, mins, cnt, min);
int signs[cnt];
CODE::exclusive_reduce(reinterpret_cast<int *>(links), signs, cnt, xor_);
CODE::exclusive_reduce(mags.data(), mins.data(), cnt, min);
CODE::exclusive_reduce(reinterpret_cast<int *>(links), signs.data(), cnt, xor_);
for (int i = 0; i < cnt; ++i)
signs[i] &= mask;
for (int i = 0; i < cnt; ++i)
reinterpret_cast<int *>(links)[i] = signs[i] | reinterpret_cast<int *>(mins)[i];
reinterpret_cast<int *>(links)[i] = signs[i] | reinterpret_cast<int *>(mins.data())[i];
}
static float sign(float a, float b)
{
@@ -193,13 +199,17 @@ struct MinSumAlgorithm<int8_t, UPDATE>
}
static void finalp(int8_t *links, int cnt)
{
int8_t mags[cnt], mins[cnt];
std::vector<int8_t> scratch(3 * cnt);
int8_t *mags = scratch.data();
int8_t *mins = mags + cnt;
int8_t *signs = mins + cnt;
for (int i = 0; i < cnt; ++i)
mags[i] = sqabs(links[i]);
CODE::exclusive_reduce(mags, mins, cnt, min);
int8_t signs[cnt];
CODE::exclusive_reduce(mags, mins, cnt, min);
CODE::exclusive_reduce(links, signs, cnt, xor_);
for (int i = 0; i < cnt; ++i)
signs[i] |= 127;
@@ -238,13 +248,15 @@ struct OffsetMinSumAlgorithm
static void finalp(TYPE *links, int cnt)
{
TYPE beta = 0.5 * FACTOR;
TYPE mags[cnt], mins[cnt];
std::vector<TYPE> mags(cnt);
std::vector<TYPE> mins(cnt);
std::vector<TYPE> signs(cnt);
for (int i = 0; i < cnt; ++i)
mags[i] = std::max(std::abs(links[i]) - beta, TYPE(0));
CODE::exclusive_reduce(mags, mins, cnt, min);
TYPE signs[cnt];
CODE::exclusive_reduce(links, signs, cnt, sign);
CODE::exclusive_reduce(mags.data(), mins.data(), cnt, min);
CODE::exclusive_reduce(links, signs.data(), cnt, sign);
for (int i = 0; i < cnt; ++i)
links[i] = sign(mins[i], signs[i]);
@@ -315,12 +327,15 @@ struct OffsetMinSumAlgorithm<int8_t, UPDATE, FACTOR>
static void finalp(int8_t *links, int cnt)
{
int8_t beta = std::nearbyint(0.5 * FACTOR);
int8_t mags[cnt], mins[cnt];
std::vector<int8_t> scratch(3 * cnt);
int8_t *mags = scratch.data();
int8_t *mins = mags + cnt;
int8_t *signs = mins + cnt;
for (int i = 0; i < cnt; ++i)
mags[i] = subu(sqabs(links[i]), beta);
CODE::exclusive_reduce(mags, mins, cnt, min);
int8_t signs[cnt];
CODE::exclusive_reduce(links, signs, cnt, xor_);
for (int i = 0; i < cnt; ++i)
signs[i] |= 127;
@@ -376,8 +391,8 @@ struct MinSumCAlgorithm
}
static void finalp(TYPE *links, int cnt)
{
TYPE tmp[cnt];
CODE::exclusive_reduce(links, tmp, cnt, min);
std::vector<TYPE> tmp(cnt);
CODE::exclusive_reduce(links, tmp.data(), cnt, min);
for (int i = 0; i < cnt; ++i)
links[i] = tmp[i];
}
@@ -432,8 +447,8 @@ struct MinSumCAlgorithm<float, UPDATE, FACTOR>
}
static void finalp(float *links, int cnt)
{
float tmp[cnt];
CODE::exclusive_reduce(links, tmp, cnt, min);
std::vector<float> tmp(cnt);
CODE::exclusive_reduce(links, tmp.data(), cnt, min);
for (int i = 0; i < cnt; ++i)
links[i] = tmp[i];
}
@@ -529,8 +544,8 @@ struct MinSumCAlgorithm<int8_t, UPDATE, FACTOR>
}
static void finalp(int8_t *links, int cnt)
{
int8_t tmp[cnt];
CODE::exclusive_reduce(links, tmp, cnt, min);
std::vector<int8_t> tmp(cnt);
CODE::exclusive_reduce(links, tmp.data(), cnt, min);
for (int i = 0; i < cnt; ++i)
links[i] = tmp[i];
}
@@ -574,13 +589,15 @@ struct LogDomainSPA
}
static void finalp(TYPE *links, int cnt)
{
TYPE mags[cnt], sums[cnt];
std::vector<TYPE> mags(cnt);
std::vector<TYPE> sums(cnt);
std::vector<TYPE> signs(cnt);
for (int i = 0; i < cnt; ++i)
mags[i] = phi(std::abs(links[i]));
CODE::exclusive_reduce(mags, sums, cnt, add);
TYPE signs[cnt];
CODE::exclusive_reduce(links, signs, cnt, sign);
CODE::exclusive_reduce(mags.data(), sums.data(), cnt, add);
CODE::exclusive_reduce(links, signs.data(), cnt, sign);
for (int i = 0; i < cnt; ++i)
links[i] = sign(phi(sums[i]), signs[i]);
@@ -626,12 +643,12 @@ struct LambdaMinAlgorithm
static void finalp(TYPE *links, int cnt)
{
typedef std::pair<TYPE, int> Pair;
Pair mags[cnt];
std::vector<Pair> mags(cnt);
for (int i = 0; i < cnt; ++i)
mags[i] = Pair(std::abs(links[i]), i);
std::nth_element(mags, mags+LAMBDA, mags+cnt, [](Pair a, Pair b){ return a.first < b.first; });
std::nth_element(mags.begin(), mags.begin()+LAMBDA, mags.end(), [](Pair a, Pair b){ return a.first < b.first; });
TYPE sums[cnt];
std::vector<TYPE> sums(cnt);
for (int i = 0; i < cnt; ++i) {
int j = 0;
if (i == mags[0].second)
@@ -645,8 +662,8 @@ struct LambdaMinAlgorithm
}
}
TYPE signs[cnt];
CODE::exclusive_reduce(links, signs, cnt, sign);
std::vector<TYPE> signs(cnt);
CODE::exclusive_reduce(links, signs.data(), cnt, sign);
for (int i = 0; i < cnt; ++i)
links[i] = sign(phi(sums[i]), signs[i]);
@@ -690,10 +707,12 @@ struct SumProductAlgorithm
}
static void finalp(TYPE *links, int cnt)
{
TYPE in[cnt], out[cnt];
std::vector<TYPE> in(cnt);
std::vector<TYPE> out(cnt);
for (int i = 0; i < cnt; ++i)
in[i] = prep(links[i]);
CODE::exclusive_reduce(in, out, cnt, mul);
CODE::exclusive_reduce(in.data(), out.data(), cnt, mul);
for (int i = 0; i < cnt; ++i)
links[i] = postp(out[i]);
}
@@ -24,6 +24,7 @@
#pragma GCC diagnostic ignored "-Wshift-negative-value"
#include <cstddef>
#include <type_traits>
namespace leansdr
{
@@ -223,6 +224,11 @@ bitvect<T, N> operator*(bitvect<T, N> a, const bitvect<T, NB> &b)
template <typename Te, int N, Te ALPHA, Te TRUNCP>
struct gf2n
{
// Field elements are represented as packed polynomial coefficients:
// bit i corresponds to the coefficient of X^i. Unsigned storage is
// required so bit operations have well-defined behavior.
static_assert(std::is_unsigned_v<Te>, "Te must be unsigned");
typedef Te element;
static const Te alpha = ALPHA;
gf2n()
@@ -236,9 +242,14 @@ struct gf2n
lut_exp[i] = alpha_i; // ALPHA^i
lut_exp[((1 << N) - 1) + i] = alpha_i; // Wrap to avoid modulo 2^N-1
lut_log[alpha_i] = i;
bool overflow = alpha_i & (1 << (N - 1));
// Multiplication by ALPHA=[X] shifts the polynomial left by one.
// If the X^(N-1) coefficient was set, the shift will overflow and
// the generator polynomial must be applied modulo P(X).
bool overflow = alpha_i & (static_cast<Te>(1) << (N - 1));
alpha_i *= 2; // Multiply by alpha=[X] i.e. increase degrees
alpha_i &= ~((~(Te)0) << N); // In case Te is wider than N bits
// Keep only the lowest N bits. This removes the X^N term and
// higher bits before applying the generator polynomial reduction.
alpha_i &= static_cast<Te>((static_cast<Te>(1) << N) - 1);
if (overflow)
alpha_i ^= TRUNCP; // Modulo P iteratively
}
+1 -1
View File
@@ -1472,6 +1472,7 @@ struct fast_qpsk_receiver : runnable
meas_decimation(1048576),
pll_adjustment(1.0),
allow_drift(false),
hist{},
in(_in),
out(_out, chunk_size),
mu(0),
@@ -1482,7 +1483,6 @@ struct fast_qpsk_receiver : runnable
set_freq(0);
freq_out = _freq_out ? new pipewriter<float>(*_freq_out) : nullptr;
cstln_out = _cstln_out ? new pipewriter<std::complex<T>>(*_cstln_out) : nullptr;
memset(hist, 0, sizeof(hist));
init_lookup_tables();
}
@@ -652,7 +652,7 @@ void VorLocalizerWorker::getChannelsByDevice(
bool operator()(const RRTurnPlan& a, const RRTurnPlan& b)
{
unsigned int nbChannelsA = a.m_channels.size();
unsigned int nbChannelsB = a.m_channels.size();
unsigned int nbChannelsB = b.m_channels.size();
if (nbChannelsA == nbChannelsB) {
return a.m_bandwidth > b.m_bandwidth;
+26 -11
View File
@@ -774,13 +774,25 @@ void DeviceAPI::removeBuddy(DeviceAPI* buddy)
{
switch(buddy->m_streamType) {
case StreamSingleRx:
m_sourceBuddies.erase(std::find(m_sourceBuddies.begin(), m_sourceBuddies.end(), buddy));
{
auto it = std::find(m_sourceBuddies.begin(), m_sourceBuddies.end(), buddy);
if (it != m_sourceBuddies.end())
{
m_sourceBuddies.erase(it);
}
break;
}
case StreamSingleTx:
m_sinkBuddies.erase(std::find(m_sinkBuddies.begin(), m_sinkBuddies.end(), buddy));
{
auto it = std::find(m_sinkBuddies.begin(), m_sinkBuddies.end(), buddy);
if (it != m_sinkBuddies.end())
{
m_sinkBuddies.erase(it);
}
break;
}
default:
qDebug("DeviceAPI::removeSourceBuddy: buddy %s(%s) is not of single Rx or Tx type",
qDebug("DeviceAPI::removeBuddy: buddy %s(%s) is not of single Rx or Tx type",
qPrintable(buddy->getHardwareId()),
qPrintable(buddy->getSamplingDeviceSerial()));
return;
@@ -789,32 +801,35 @@ void DeviceAPI::removeBuddy(DeviceAPI* buddy)
void DeviceAPI::clearBuddiesLists()
{
auto itSource = m_sourceBuddies.begin();
auto itSink = m_sinkBuddies.begin();
// Make copies before iterating because removeBuddy() modifies the buddy
// relationship lists. Iterating directly over m_sourceBuddies/m_sinkBuddies
// could invalidate iterators while the relationships are being removed.
auto sourceCopy = m_sourceBuddies;
auto sinkCopy = m_sinkBuddies;
bool leaderElected = false;
for (;itSource != m_sourceBuddies.end(); ++itSource)
for (auto* buddy : sourceCopy)
{
if (isBuddyLeader() && !leaderElected)
{
(*itSource)->setBuddyLeader(true);
buddy->setBuddyLeader(true);
leaderElected = true;
}
(*itSource)->removeBuddy(this);
buddy->removeBuddy(this);
}
m_sourceBuddies.clear();
for (;itSink != m_sinkBuddies.end(); ++itSink)
for (auto* buddy : sinkCopy)
{
if (isBuddyLeader() && !leaderElected)
{
(*itSink)->setBuddyLeader(true);
buddy->setBuddyLeader(true);
leaderElected = true;
}
(*itSink)->removeBuddy(this);
buddy->removeBuddy(this);
}
m_sinkBuddies.clear();
+6 -6
View File
@@ -340,7 +340,7 @@ setInvalid:
bool SimpleDeserializer::readS32(quint32 id, qint32* result, qint32 def) const
{
uint readOfs;
qint32 tmp;
quint32 tmp;
Elements::const_iterator it = m_elements.constFind(id);
if(it == m_elements.constEnd())
goto returnDefault;
@@ -354,10 +354,10 @@ bool SimpleDeserializer::readS32(quint32 id, qint32* result, qint32 def) const
for(uint i = 0; i < it->length; i++) {
quint8 byte = readByte(&readOfs);
if((i == 0) && (byte & 0x80))
tmp = -1;
tmp = 0xFFFFFFFF;
tmp = (tmp << 8) | byte;
}
*result = tmp;
*result = static_cast<qint32>(tmp);
return true;
returnDefault:
@@ -392,7 +392,7 @@ returnDefault:
bool SimpleDeserializer::readS64(quint32 id, qint64* result, qint64 def) const
{
uint readOfs;
qint64 tmp;
quint64 tmp;
Elements::const_iterator it = m_elements.constFind(id);
if(it == m_elements.constEnd())
goto returnDefault;
@@ -406,10 +406,10 @@ bool SimpleDeserializer::readS64(quint32 id, qint64* result, qint64 def) const
for(uint i = 0; i < it->length; i++) {
quint8 byte = readByte(&readOfs);
if((i == 0) && (byte & 0x80))
tmp = -1;
tmp = 0xFFFFFFFFFFFFFFFFULL;
tmp = (tmp << 8) | byte;
}
*result = tmp;
*result = static_cast<qint64>(tmp);
return true;
returnDefault:
+4 -5
View File
@@ -647,14 +647,13 @@ void ValueDialZ::keyPressEvent(QKeyEvent* value)
}
int d = c.toLatin1() - '0';
quint64 e = findExponent(m_cursor);
quint64 value = abs(m_value);
int sign = m_value < 0 ? -1 : 1;
quint64 v = (value / e) % 10;
qint64 e = static_cast<qint64>(findExponent(m_cursor));
qint64 value = qAbs(m_value);
qint64 v = (value / e) % 10;
v = value - v * e;
v += d * e;
setValue(sign*v);
setValue(m_value < 0 ? -v : v);
m_cursor++;
if ((m_text[m_cursor] == m_groupSeparator) || (m_text[m_cursor] == m_decSeparator)) {