diff --git a/plugins/channelrx/demoddatv/ldpctool/generic.h b/plugins/channelrx/demoddatv/ldpctool/generic.h index d2af4620c..78b19c4c5 100644 --- a/plugins/channelrx/demoddatv/ldpctool/generic.h +++ b/plugins/channelrx/demoddatv/ldpctool/generic.h @@ -23,6 +23,8 @@ Copyright 2018 Ahmet Inan #ifndef GENERIC_HH #define GENERIC_HH +#include + #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 mags(cnt); + std::vector mins(cnt); + std::vector 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 static void finalp(float *links, int cnt) { int mask = 0x80000000; - float mags[cnt], mins[cnt]; + std::vector mags(cnt), mins(cnt); + std::vector 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(links), signs, cnt, xor_); + CODE::exclusive_reduce(mags.data(), mins.data(), cnt, min); + CODE::exclusive_reduce(reinterpret_cast(links), signs.data(), cnt, xor_); + for (int i = 0; i < cnt; ++i) signs[i] &= mask; for (int i = 0; i < cnt; ++i) - reinterpret_cast(links)[i] = signs[i] | reinterpret_cast(mins)[i]; + reinterpret_cast(links)[i] = signs[i] | reinterpret_cast(mins.data())[i]; } static float sign(float a, float b) { @@ -193,13 +199,17 @@ struct MinSumAlgorithm } static void finalp(int8_t *links, int cnt) { - int8_t mags[cnt], mins[cnt]; + std::vector 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 mags(cnt); + std::vector mins(cnt); + std::vector 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 static void finalp(int8_t *links, int cnt) { int8_t beta = std::nearbyint(0.5 * FACTOR); - int8_t mags[cnt], mins[cnt]; + std::vector 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 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 } static void finalp(float *links, int cnt) { - float tmp[cnt]; - CODE::exclusive_reduce(links, tmp, cnt, min); + std::vector 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 } static void finalp(int8_t *links, int cnt) { - int8_t tmp[cnt]; - CODE::exclusive_reduce(links, tmp, cnt, min); + std::vector 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 mags(cnt); + std::vector sums(cnt); + std::vector 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 Pair; - Pair mags[cnt]; + std::vector 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 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 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 in(cnt); + std::vector 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]); } diff --git a/plugins/channelrx/demoddatv/leansdr/discrmath.h b/plugins/channelrx/demoddatv/leansdr/discrmath.h index de3835713..ff276c296 100644 --- a/plugins/channelrx/demoddatv/leansdr/discrmath.h +++ b/plugins/channelrx/demoddatv/leansdr/discrmath.h @@ -24,6 +24,7 @@ #pragma GCC diagnostic ignored "-Wshift-negative-value" #include +#include namespace leansdr { @@ -223,6 +224,11 @@ bitvect operator*(bitvect a, const bitvect &b) template 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 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(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((static_cast(1) << N) - 1); if (overflow) alpha_i ^= TRUNCP; // Modulo P iteratively } diff --git a/plugins/channelrx/demoddatv/leansdr/sdr.h b/plugins/channelrx/demoddatv/leansdr/sdr.h index 42f555ee3..d35dcbd70 100644 --- a/plugins/channelrx/demoddatv/leansdr/sdr.h +++ b/plugins/channelrx/demoddatv/leansdr/sdr.h @@ -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(*_freq_out) : nullptr; cstln_out = _cstln_out ? new pipewriter>(*_cstln_out) : nullptr; - memset(hist, 0, sizeof(hist)); init_lookup_tables(); } diff --git a/plugins/feature/vorlocalizer/vorlocalizerworker.cpp b/plugins/feature/vorlocalizer/vorlocalizerworker.cpp index f2deb09a3..e12cf071b 100644 --- a/plugins/feature/vorlocalizer/vorlocalizerworker.cpp +++ b/plugins/feature/vorlocalizer/vorlocalizerworker.cpp @@ -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; diff --git a/sdrbase/device/deviceapi.cpp b/sdrbase/device/deviceapi.cpp index 9e08b0723..9f6cd2921 100644 --- a/sdrbase/device/deviceapi.cpp +++ b/sdrbase/device/deviceapi.cpp @@ -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(); diff --git a/sdrbase/util/simpleserializer.cpp b/sdrbase/util/simpleserializer.cpp index 77857b021..0ced52faa 100644 --- a/sdrbase/util/simpleserializer.cpp +++ b/sdrbase/util/simpleserializer.cpp @@ -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(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(tmp); return true; returnDefault: diff --git a/sdrgui/gui/valuedialz.cpp b/sdrgui/gui/valuedialz.cpp index 2b81257f6..161307797 100644 --- a/sdrgui/gui/valuedialz.cpp +++ b/sdrgui/gui/valuedialz.cpp @@ -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(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)) {