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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user