[webftr-js8-lab] command=source-bitpath-extract [webftr-js8-lab] root=/decoders/js8_decoder [webftr-js8-lab] log=/decoders/js8_decoder/logs/20260527T124745Z_source-bitpath-extract.log [webftr-js8-lab] manifest=/decoders/js8_decoder/logs/20260527T124745Z_source-bitpath-extract_manifest.json [webftr-js8-lab] utc=20260527T124745Z [webftr-js8-lab] rx-only guard: no TX / no PTT / no Tune / no Send [webftr-js8-lab] source bitpath extract source: /decoders/js8_decoder/runtime/src/JS8Call-improved [webftr-js8-lab] JSON output: /decoders/js8_decoder/logs/20260527T124745Z_source_bitpath_extract_output.json [webftr-js8-lab] JSON timeout guard: 180s { "ok": true, "tool": "webftr-js8-source-bitpath-extract-pack", "tool_version": "step54-source-bitpath-extract-pack", "source_dir": "/decoders/js8_decoder/runtime/src/JS8Call-improved", "rx_only_guard": { "tx": false, "ptt": false, "tune": false, "send": false, "js8call_runtime_control": false }, "no_gui_runtime_started": true, "purpose": "Extract focused JS8Call-Improved RX-core snippets for source-derived bitpath implementation in JS8Lab.", "scanned_target_files": 12, "existing_target_files": 12, "missing_target_files": [], "phase_top_files": { "timing_submode": [ { "path": "JS8_Mode/JS8Submode.cpp", "score": 26, "sha256": "10d60fcdd5c908d8" }, { "path": "JS8_Mode/JS8.cpp", "score": 5, "sha256": "b72787f6e6473919" }, { "path": "JS8_Include/commons.h", "score": 3, "sha256": "d7abc3090fcf5516" } ], "symbol_to_soft_bits": [ { "path": "JS8_JSC/JSC_map.cpp", "score": 590, "sha256": "ab2bd62ef594f462" }, { "path": "JS8_JSC/JSC_list.cpp", "score": 590, "sha256": "993811813f1cd6e0" }, { "path": "JS8_Mode/JS8.cpp", "score": 184, "sha256": "b72787f6e6473919" }, { "path": "JS8_Mode/whitening_processor.h", "score": 112, "sha256": "bcd61a557030caba" }, { "path": "JS8_Mode/soft_combiner.h", "score": 109, "sha256": "59a2c7dafab922a1" }, { "path": "JS8_Mode/ldpc_feedback.h", "score": 50, "sha256": "c9bb4ccc8f3def26" }, { "path": "JS8_Mode/JS8Submode.cpp", "score": 41, "sha256": "10d60fcdd5c908d8" }, { "path": "JS8_Include/commons.h", "score": 6, "sha256": "d7abc3090fcf5516" } ], "bit_order_interleaver": [ { "path": "JS8_JSC/JSC_map.cpp", "score": 398, "sha256": "ab2bd62ef594f462" }, { "path": "JS8_JSC/JSC_list.cpp", "score": 398, "sha256": "993811813f1cd6e0" }, { "path": "JS8_Main/Varicode.cpp", "score": 231, "sha256": "2b4a877e7dae1a3f" }, { "path": "JS8_Mode/JS8.cpp", "score": 110, "sha256": "b72787f6e6473919" }, { "path": "JS8_Main/Varicode.h", "score": 32, "sha256": "dd7b8bf50466d0d2" }, { "path": "JS8_Mode/DecodedText.cpp", "score": 24, "sha256": "1f3d3a687a0bae5a" }, { "path": "JS8_Mode/soft_combiner.h", "score": 5, "sha256": "59a2c7dafab922a1" }, { "path": "JS8_Mode/ldpc_feedback.h", "score": 4, "sha256": "c9bb4ccc8f3def26" } ], "whitening_erasure": [ { "path": "JS8_JSC/JSC_map.cpp", "score": 119, "sha256": "ab2bd62ef594f462" }, { "path": "JS8_JSC/JSC_list.cpp", "score": 119, "sha256": "993811813f1cd6e0" }, { "path": "JS8_Mode/whitening_processor.h", "score": 57, "sha256": "bcd61a557030caba" }, { "path": "JS8_Mode/JS8.cpp", "score": 27, "sha256": "b72787f6e6473919" }, { "path": "JS8_Main/Varicode.cpp", "score": 11, "sha256": "2b4a877e7dae1a3f" }, { "path": "JS8_Mode/soft_combiner.h", "score": 4, "sha256": "59a2c7dafab922a1" } ], "ldpc_decode": [ { "path": "JS8_Mode/JS8.cpp", "score": 54, "sha256": "b72787f6e6473919" }, { "path": "JS8_Mode/ldpc_feedback.h", "score": 24, "sha256": "c9bb4ccc8f3def26" }, { "path": "JS8_JSC/JSC_map.cpp", "score": 6, "sha256": "ab2bd62ef594f462" }, { "path": "JS8_JSC/JSC_list.cpp", "score": 6, "sha256": "993811813f1cd6e0" } ], "message91_crc_text": [ { "path": "JS8_Main/Varicode.cpp", "score": 734, "sha256": "2b4a877e7dae1a3f" }, { "path": "JS8_JSC/JSC_list.cpp", "score": 153, "sha256": "993811813f1cd6e0" }, { "path": "JS8_JSC/JSC_map.cpp", "score": 152, "sha256": "ab2bd62ef594f462" }, { "path": "JS8_Mode/DecodedText.cpp", "score": 108, "sha256": "1f3d3a687a0bae5a" }, { "path": "JS8_Mode/JS8.cpp", "score": 88, "sha256": "b72787f6e6473919" }, { "path": "JS8_Main/Varicode.h", "score": 85, "sha256": "dd7b8bf50466d0d2" }, { "path": "JS8_Mode/JS8Submode.cpp", "score": 7, "sha256": "10d60fcdd5c908d8" } ] }, "files": [ { "path": "JS8_Mode/JS8.cpp", "exists": true, "bytes": 113531, "sha256": "b72787f6e6473919872103997ef5dc9847810ff3e7783124a3961a2da2a86bf1", "line_count": 2913, "phase_hits": { "timing_submode": 5, "symbol_to_soft_bits": 184, "bit_order_interleaver": 110, "whitening_erasure": 27, "ldpc_decode": 54, "message91_crc_text": 88 }, "function_blocks": [ { "function": "cos_approx", "line": 101, "signature": "constexpr double cos_approx(double x) {", "snippet": { "start_line": 87, "end_line": 115, "lines": [ { "line": 87, "text": "// expected, look at the Fortran code and compare the array indexing;" }, { "line": 88, "text": "// would not be surprised in the least to have off-by-one errors here." }, { "line": 89, "text": "" }, { "line": 90, "text": "/******************************************************************************/" }, { "line": 91, "text": "// Compilation Utilities" }, { "line": 92, "text": "/******************************************************************************/" }, { "line": 93, "text": "" }, { "line": 94, "text": "namespace {" }, { "line": 95, "text": "// Full-range cosine function using symmetries of cos(x). std::cos" }, { "line": 96, "text": "// isn't constexpr until C++20, and we're targeting C++17 at the" }, { "line": 97, "text": "// moment. We only use this function during compilation; std::cos" }, { "line": 98, "text": "// is the better choice at runtime. Once we move to requiring a" }, { "line": 99, "text": "// C++20 compiler, we can just use std::cos." }, { "line": 100, "text": "" }, { "line": 101, "text": "constexpr double cos_approx(double x) {" }, { "line": 102, "text": " constexpr auto RAD_360 = std::numbers::pi * 2;" }, { "line": 103, "text": " constexpr auto RAD_180 = std::numbers::pi;" }, { "line": 104, "text": " constexpr auto RAD_90 = std::numbers::pi / 2;" }, { "line": 105, "text": "" }, { "line": 106, "text": " // Polynomial approximation of cos(x) for x in [0, RAD_90]," }, { "line": 107, "text": " // Accuracy here in theory is 1e-18, but double precision" }, { "line": 108, "text": " // itself is only 1-e16, so within the domain of doubles," }, { "line": 109, "text": " // this should be extremely accurate." }, { "line": 110, "text": "" }, { "line": 111, "text": " constexpr auto poly = [](double const x) {" }, { "line": 112, "text": " constexpr std::array coefficients = {" }, { "line": 113, "text": " 1.0, // Coefficient for x^0" }, { "line": 114, "text": " -0.49999999999999994, // Coefficient for x^2" }, { "line": 115, "text": " 0.041666666666666664, // Coefficient for x^4" } ] } }, { "function": "CRC12", "line": 891, "signature": "template std::uint16_t CRC12(T const &range) {", "snippet": { "start_line": 877, "end_line": 905, "lines": [ { "line": 877, "text": " }" }, { "line": 878, "text": "" }, { "line": 879, "text": " throw std::runtime_error(\"Invalid character in message\");" }, { "line": 880, "text": " };" }, { "line": 881, "text": "}();" }, { "line": 882, "text": "" }, { "line": 883, "text": "// Sanity check key bounds of the 6-bit encoding table." }, { "line": 884, "text": "" }, { "line": 885, "text": "static_assert(alphabetWord('0') == 0);" }, { "line": 886, "text": "static_assert(alphabetWord('A') == 10);" }, { "line": 887, "text": "static_assert(alphabetWord('a') == 36);" }, { "line": 888, "text": "static_assert(alphabetWord('-') == 62);" }, { "line": 889, "text": "static_assert(alphabetWord('+') == 63);" }, { "line": 890, "text": "" }, { "line": 891, "text": "template std::uint16_t CRC12(T const &range) {" }, { "line": 892, "text": " return boost::augmented_crc<12, 0xc06>(range.data(), range.size()) ^ 42;" }, { "line": 893, "text": "}" }, { "line": 894, "text": "" }, { "line": 895, "text": "bool checkCRC12(std::array const &decoded) {" }, { "line": 896, "text": " std::array bits = {};" }, { "line": 897, "text": "" }, { "line": 898, "text": " for (std::size_t i = 0; i < decoded.size(); ++i) {" }, { "line": 899, "text": " if (decoded[i])" }, { "line": 900, "text": " bits[i / 8] |= (1 << (7 - (i % 8)));" }, { "line": 901, "text": " }" }, { "line": 902, "text": "" }, { "line": 903, "text": " // Extract the received CRC-12." }, { "line": 904, "text": "" }, { "line": 905, "text": " uint16_t crc = (static_cast(bits[9] & 0x1F) << 7) |" } ] } }, { "function": "checkCRC12", "line": 895, "signature": "bool checkCRC12(std::array const &decoded) {", "snippet": { "start_line": 881, "end_line": 909, "lines": [ { "line": 881, "text": "}();" }, { "line": 882, "text": "" }, { "line": 883, "text": "// Sanity check key bounds of the 6-bit encoding table." }, { "line": 884, "text": "" }, { "line": 885, "text": "static_assert(alphabetWord('0') == 0);" }, { "line": 886, "text": "static_assert(alphabetWord('A') == 10);" }, { "line": 887, "text": "static_assert(alphabetWord('a') == 36);" }, { "line": 888, "text": "static_assert(alphabetWord('-') == 62);" }, { "line": 889, "text": "static_assert(alphabetWord('+') == 63);" }, { "line": 890, "text": "" }, { "line": 891, "text": "template std::uint16_t CRC12(T const &range) {" }, { "line": 892, "text": " return boost::augmented_crc<12, 0xc06>(range.data(), range.size()) ^ 42;" }, { "line": 893, "text": "}" }, { "line": 894, "text": "" }, { "line": 895, "text": "bool checkCRC12(std::array const &decoded) {" }, { "line": 896, "text": " std::array bits = {};" }, { "line": 897, "text": "" }, { "line": 898, "text": " for (std::size_t i = 0; i < decoded.size(); ++i) {" }, { "line": 899, "text": " if (decoded[i])" }, { "line": 900, "text": " bits[i / 8] |= (1 << (7 - (i % 8)));" }, { "line": 901, "text": " }" }, { "line": 902, "text": "" }, { "line": 903, "text": " // Extract the received CRC-12." }, { "line": 904, "text": "" }, { "line": 905, "text": " uint16_t crc = (static_cast(bits[9] & 0x1F) << 7) |" }, { "line": 906, "text": " (static_cast(bits[10]) >> 1);" }, { "line": 907, "text": "" }, { "line": 908, "text": " // Clear bits that correspond to the CRC in the last bytes." }, { "line": 909, "text": "" } ] } }, { "function": "extractmessage174", "line": 918, "signature": "std::string extractmessage174(std::array const &decoded) {", "snippet": { "start_line": 904, "end_line": 932, "lines": [ { "line": 904, "text": "" }, { "line": 905, "text": " uint16_t crc = (static_cast(bits[9] & 0x1F) << 7) |" }, { "line": 906, "text": " (static_cast(bits[10]) >> 1);" }, { "line": 907, "text": "" }, { "line": 908, "text": " // Clear bits that correspond to the CRC in the last bytes." }, { "line": 909, "text": "" }, { "line": 910, "text": " bits[9] &= 0xE0;" }, { "line": 911, "text": " bits[10] = 0x00;" }, { "line": 912, "text": "" }, { "line": 913, "text": " // Compute CRC and indicate if we have a match." }, { "line": 914, "text": "" }, { "line": 915, "text": " return crc == CRC12(bits);" }, { "line": 916, "text": "}" }, { "line": 917, "text": "" }, { "line": 918, "text": "std::string extractmessage174(std::array const &decoded) {" }, { "line": 919, "text": " std::string message;" }, { "line": 920, "text": "" }, { "line": 921, "text": " // Ensure received CRC matches computed CRC." }, { "line": 922, "text": "" }, { "line": 923, "text": " if (checkCRC12(decoded)) {" }, { "line": 924, "text": " message.reserve(12);" }, { "line": 925, "text": "" }, { "line": 926, "text": " // Decode the message from the 72 data bits" }, { "line": 927, "text": "" }, { "line": 928, "text": " std::array words;" }, { "line": 929, "text": "" }, { "line": 930, "text": " for (std::size_t i = 0; i < 12; ++i) {" }, { "line": 931, "text": " words[i] = (decoded[i * 6 + 0] << 5) | (decoded[i * 6 + 1] << 4) |" }, { "line": 932, "text": " (decoded[i * 6 + 2] << 3) | (decoded[i * 6 + 3] << 2) |" } ] } }, { "function": "evaluate", "line": 1126, "signature": "inline auto evaluate(float const x) const {", "snippet": { "start_line": 1112, "end_line": 1140, "lines": [ { "line": 1112, "text": " using Points = Eigen::Matrix;" }, { "line": 1113, "text": " using Vandermonde =" }, { "line": 1114, "text": " Eigen::Matrix;" }, { "line": 1115, "text": " using Coefficients = Eigen::Vector;" }, { "line": 1116, "text": "" }, { "line": 1117, "text": " Points p;" }, { "line": 1118, "text": " Vandermonde V;" }, { "line": 1119, "text": " Coefficients c;" }, { "line": 1120, "text": "" }, { "line": 1121, "text": " // Polynomial evaluation using Estrin's method, loop is unrolled at" }, { "line": 1122, "text": " // compile time. A compiler should emit SIMD instructions from what" }, { "line": 1123, "text": " // it sees here when the optimizer is involved, but even without it," }, { "line": 1124, "text": " // we'll likely see fused multiply-add instructions." }, { "line": 1125, "text": "" }, { "line": 1126, "text": " inline auto evaluate(float const x) const {" }, { "line": 1127, "text": " return [this](" }, { "line": 1128, "text": " float const x, std::integer_sequence) {" }, { "line": 1129, "text": " auto baseline = 0.0;" }, { "line": 1130, "text": " auto exponent = 1.0;" }, { "line": 1131, "text": "" }, { "line": 1132, "text": " ((baseline += (c[I * 2] + c[I * 2 + 1] * x) * exponent," }, { "line": 1133, "text": " exponent *= x * x)," }, { "line": 1134, "text": " ...);" }, { "line": 1135, "text": "" }, { "line": 1136, "text": " return static_cast(baseline);" }, { "line": 1137, "text": " }(x, std::make_integer_sequence{});" }, { "line": 1139, "text": " }" }, { "line": 1140, "text": "" } ] } }, { "function": "if", "line": 1612, "signature": "else if (ipass == 4)", "snippet": { "start_line": 1598, "end_line": 1626, "lines": [ { "line": 1598, "text": " }" }, { "line": 1599, "text": "" }, { "line": 1600, "text": " return std::nullopt;" }, { "line": 1601, "text": " };" }, { "line": 1602, "text": "" }, { "line": 1603, "text": " // Loop over decoding passes" }, { "line": 1604, "text": " for (int ipass = 1; ipass <= 4 && totalLdpcPasses < m_maxLdpcPasses;" }, { "line": 1605, "text": " ++ipass) {" }, { "line": 1606, "text": " auto &llr = ipass == 2 ? llr1Combined : llr0Combined;" }, { "line": 1607, "text": "" }, { "line": 1608, "text": " // Zero ranges for certain passes to mirror legacy behavior." }, { "line": 1609, "text": " if (ipass == 3)" }, { "line": 1610, "text": " std::fill(llr0Combined.begin(), llr0Combined.begin() + 24," }, { "line": 1611, "text": " 0.0f);" }, { "line": 1612, "text": " else if (ipass == 4)" }, { "line": 1613, "text": " std::fill(llr0Combined.begin() + 24, llr0Combined.begin() + 48," }, { "line": 1614, "text": " 0.0f);" }, { "line": 1615, "text": "" }, { "line": 1616, "text": " std::array llrPrimary = llr;" }, { "line": 1617, "text": " if (auto result = tryDecode(llrPrimary, ipass)) {" }, { "line": 1618, "text": " ++totalLdpcPasses;" }, { "line": 1619, "text": " return result;" }, { "line": 1620, "text": " }" }, { "line": 1621, "text": " ++totalLdpcPasses;" }, { "line": 1622, "text": "" }, { "line": 1623, "text": " // Feedback refinement and second attempt, if enabled and budget" }, { "line": 1624, "text": " // allows." }, { "line": 1625, "text": " if (m_enableLdpcFeedback && totalLdpcPasses < m_maxLdpcPasses) {" }, { "line": 1626, "text": " std::array llrRefined;" } ] } }, { "function": "baselinejs8", "line": 1695, "signature": "void baselinejs8(int const ia, int const ib) {", "snippet": { "start_line": 1681, "end_line": 1709, "lines": [ { "line": 1681, "text": " // ill-conditioned; we're just looking for a low-order polynomial" }, { "line": 1682, "text": " // here, and a massively tall matrix isn't in general going to be" }, { "line": 1683, "text": " // helpful there. Additionally, the methodology seemed to be very" }, { "line": 1684, "text": " // susceptible to Runge's phenomenon." }, { "line": 1685, "text": " //" }, { "line": 1686, "text": " // This approach instead uses a number of Chebyshev nodes proportional" }, { "line": 1687, "text": " // to the polynomial degree, and we evaluate 2 kHz of `savg`, centered" }, { "line": 1688, "text": " // around 1.5 kHz, to determine the polynomial, figuring that that's" }, { "line": 1689, "text": " // going to be an optimal place to measure the 10% noise floor. We then" }, { "line": 1690, "text": " // map the [ia, ib] range to the domain of the polynomial to compute" }, { "line": 1691, "text": " // the baseline. Since `savg` would otherwise no longer be referenced" }, { "line": 1692, "text": " // beyond this function, we dispense with `sbase` and instead overwrite" }, { "line": 1693, "text": " // `savg` with the baseline." }, { "line": 1694, "text": "" }, { "line": 1695, "text": " void baselinejs8(int const ia, int const ib) {" }, { "line": 1696, "text": " // Data referenced in savg is defined by the closed range [bmin, bmax]." }, { "line": 1697, "text": " // From this we can derive the size of the closed range and the number" }, { "line": 1698, "text": " // of points in each of the arms on either side of a node. All of these" }, { "line": 1699, "text": " // values can be computed at compile time." }, { "line": 1700, "text": "" }, { "line": 1701, "text": " using boost::math::ccmath::round;" }, { "line": 1702, "text": "" }, { "line": 1703, "text": " constexpr auto bmin =" }, { "line": 1704, "text": " static_cast(round(BASELINE_MIN / Mode::DF));" }, { "line": 1705, "text": " constexpr auto bmax =" }, { "line": 1706, "text": " static_cast(round(BASELINE_MAX / Mode::DF));" }, { "line": 1707, "text": " constexpr auto size = bmax - bmin + 1;" }, { "line": 1708, "text": " constexpr auto arm = size / (2 * BASELINE_NODES.size());" }, { "line": 1709, "text": "" } ] } }, { "function": "js8_downsample", "line": 1807, "signature": "void js8_downsample(float const f0) {", "snippet": { "start_line": 1793, "end_line": 1821, "lines": [ { "line": 1793, "text": " // a remainder." }, { "line": 1794, "text": "" }, { "line": 1795, "text": " std::copy(dd.begin(), dd.end(), fftw_real);" }, { "line": 1796, "text": " std::fill(fftw_real + dd.size(), fftw_real + Mode::NDFFT1, 0.0f);" }, { "line": 1797, "text": "" }, { "line": 1798, "text": " fftwf_execute(plans[Plan::BB]);" }, { "line": 1799, "text": " }" }, { "line": 1800, "text": "" }, { "line": 1801, "text": " // This function extracts a narrow frequency band around the target" }, { "line": 1802, "text": " // frequency f0, applies tapering to reduce spectral artifacts, aligns the" }, { "line": 1803, "text": " // signal to the center frequency, performs an inverse FFT to convert the" }, { "line": 1804, "text": " // data back into the time domain, and normalizes the result for further" }, { "line": 1805, "text": " // processing in the JS8 decoding pipeline." }, { "line": 1806, "text": "" }, { "line": 1807, "text": " void js8_downsample(float const f0) {" }, { "line": 1808, "text": " // Frequency band extraction; identifies a narrow frequency band around" }, { "line": 1809, "text": " // the target frequency (f0) based on a predefined range (8.5 baud above" }, { "line": 1810, "text": " // and 1.5 baud below). The indices of this range in the" }, { "line": 1811, "text": " // frequency-domain representation (ds_cx) are calculated (ib and it)," }, { "line": 1812, "text": " // and the relevant frequency-domain samples are extracted into cd0." }, { "line": 1813, "text": "" }, { "line": 1814, "text": " constexpr float DF = 12000.0f / Mode::NDFFT1;" }, { "line": 1815, "text": " constexpr float BAUD = 12000.0f / Mode::NSPS;" }, { "line": 1816, "text": "" }, { "line": 1817, "text": " float const ft = f0 + 8.5f * BAUD;" }, { "line": 1818, "text": " float const fb = f0 - 1.5f * BAUD;" }, { "line": 1819, "text": " int const i0 = static_cast(std::round(f0 / DF));" }, { "line": 1820, "text": " int const it =" }, { "line": 1821, "text": " std::min(static_cast(std::round(ft / DF)), Mode::NDFFT1 / 2);" } ] } }, { "function": "syncjs8", "line": 1940, "signature": "std::vector syncjs8(int nfa, int nfb) {", "snippet": { "start_line": 1926, "end_line": 1954, "lines": [ { "line": 1926, "text": " // 7. Output:" }, { "line": 1927, "text": " //" }, { "line": 1928, "text": " //\t - Returns a vector of the most promising signal candidates, sorted by" }, { "line": 1929, "text": " // their" }, { "line": 1930, "text": " // synchronization power. It's expected that these will be re-sorted" }, { "line": 1931, "text": " // by the caller into a desirable order, but synchronization power" }, { "line": 1932, "text": " // order facilitates debugging this function." }, { "line": 1933, "text": " //" }, { "line": 1934, "text": " // Note: The Fortran version of this routine would normalize `s` at the end" }, { "line": 1935, "text": " // of this" }, { "line": 1936, "text": " // function, but I'm unsure why; nothing beyond this function" }, { "line": 1937, "text": " // references `s`, so it was effectively a somewhat expensive dead" }, { "line": 1938, "text": " // store. It's been eliminated in this version." }, { "line": 1939, "text": "" }, { "line": 1940, "text": " std::vector syncjs8(int nfa, int nfb) {" }, { "line": 1941, "text": " // Compute symbol spectra" }, { "line": 1942, "text": "" }, { "line": 1943, "text": " savg.fill(0.0f);" }, { "line": 1944, "text": "" }, { "line": 1945, "text": " for (int j = 0; j < Mode::NHSYM; ++j) {" }, { "line": 1946, "text": " int const ia = j * Mode::NSTEP;" }, { "line": 1947, "text": " int const ib = ia + Mode::NFFT1;" }, { "line": 1948, "text": "" }, { "line": 1949, "text": " if (ib > Mode::NMAX)" }, { "line": 1950, "text": " break;" }, { "line": 1951, "text": "" }, { "line": 1952, "text": " std::transform(dd.begin() + ia, dd.begin() + ib, nuttal.begin()," }, { "line": 1953, "text": " reinterpret_cast(sd.data())," }, { "line": 1954, "text": " std::multiplies{});" } ] } }, { "function": "syncjs8d", "line": 2115, "signature": "float syncjs8d(int const i0, float const delf) {", "snippet": { "start_line": 2101, "end_line": 2129, "lines": [ { "line": 2101, "text": " // to the index begin in the loop increment condition." }, { "line": 2102, "text": "" }, { "line": 2103, "text": " freqIndex.erase(freqIndex.lower_bound(it->freq - Mode::AZ)," }, { "line": 2104, "text": " freqIndex.upper_bound(it->freq + Mode::AZ));" }, { "line": 2105, "text": " }" }, { "line": 2106, "text": "" }, { "line": 2107, "text": " return candidates;" }, { "line": 2108, "text": " }" }, { "line": 2109, "text": "" }, { "line": 2110, "text": " // Returns the total synchronization power, which is a measure of how well" }, { "line": 2111, "text": " // the signal aligns with the Costas sequence after accounting for the" }, { "line": 2112, "text": " // frequency adjustment. Used to identify the best alignment for further" }, { "line": 2113, "text": " // decoding." }, { "line": 2114, "text": "" }, { "line": 2115, "text": " float syncjs8d(int const i0, float const delf) {" }, { "line": 2116, "text": " constexpr float BASE_DPHI = TAU * (1.0f / (12000.0f / Mode::NDOWN));" }, { "line": 2117, "text": "" }, { "line": 2118, "text": " // If delta frequency is non-zero, compute the frequency" }, { "line": 2119, "text": " // adjustment array, otherwise, use what'll be an identity" }, { "line": 2120, "text": " // transfrom when multiplied." }, { "line": 2121, "text": "" }, { "line": 2122, "text": " std::array, Mode::NDOWNSPS> freqAdjust;" }, { "line": 2123, "text": "" }, { "line": 2124, "text": " if (delf != 0.0f) {" }, { "line": 2125, "text": " float const dphi = BASE_DPHI * delf;" }, { "line": 2126, "text": " float phi = 0.0f;" }, { "line": 2127, "text": "" }, { "line": 2128, "text": " // std::fmod() is almost like Fortran's mod(), but not quite;" }, { "line": 2129, "text": " // Since delf can be negative, we must ensure that phi stays" } ] } }, { "function": "makeDecodeEntry", "line": 2615, "signature": "DecodeEntry makeDecodeEntry(int shift, int &kpos, int &ksz) {", "snippet": { "start_line": 2601, "end_line": 2629, "lines": [ { "line": 2601, "text": " DecodeEntry(std::in_place_type_t, int mode," }, { "line": 2602, "text": " int &kpos, int &ksz)" }, { "line": 2603, "text": " : decode(std::in_place_type), mode(mode)," }, { "line": 2604, "text": " kpos(kpos), ksz(ksz) {}" }, { "line": 2605, "text": " };" }, { "line": 2606, "text": "" }, { "line": 2607, "text": " // Since a strategy can be neither moved nor copied, we must" }, { "line": 2608, "text": " // instantiate them in-place. Note that with the advent of the" }, { "line": 2609, "text": " // multi-decoder, mode identifiers became a bitset instead of" }, { "line": 2610, "text": " // integral values. The order defined here is the order that" }, { "line": 2611, "text": " // the decode loop will run in; we're matching the Fortran" }, { "line": 2612, "text": " // version here in terms of faster modes first." }, { "line": 2613, "text": "" }, { "line": 2614, "text": " template " }, { "line": 2615, "text": " DecodeEntry makeDecodeEntry(int shift, int &kpos, int &ksz) {" }, { "line": 2616, "text": " return DecodeEntry(std::in_place_type>," }, { "line": 2617, "text": " 1 << shift, kpos, ksz);" }, { "line": 2618, "text": " }" }, { "line": 2619, "text": "" }, { "line": 2620, "text": " std::array m_decodes = {" }, { "line": 2621, "text": " {makeDecodeEntry(4, m_data.params.kposI, m_data.params.kszI)," }, { "line": 2622, "text": " makeDecodeEntry(3, m_data.params.kposE, m_data.params.kszE)," }, { "line": 2623, "text": " makeDecodeEntry(2, m_data.params.kposC, m_data.params.kszC)," }, { "line": 2624, "text": " makeDecodeEntry(1, m_data.params.kposB, m_data.params.kszB)," }, { "line": 2625, "text": " makeDecodeEntry(0, m_data.params.kposA," }, { "line": 2626, "text": " m_data.params.kszA)}};" }, { "line": 2627, "text": "" }, { "line": 2628, "text": " public:" }, { "line": 2629, "text": " // Constructor" } ] } }, { "function": "Impl", "line": 2631, "signature": "explicit Impl(struct dec_data &data) : m_data(data) {}", "snippet": { "start_line": 2617, "end_line": 2645, "lines": [ { "line": 2617, "text": " 1 << shift, kpos, ksz);" }, { "line": 2618, "text": " }" }, { "line": 2619, "text": "" }, { "line": 2620, "text": " std::array m_decodes = {" }, { "line": 2621, "text": " {makeDecodeEntry(4, m_data.params.kposI, m_data.params.kszI)," }, { "line": 2622, "text": " makeDecodeEntry(3, m_data.params.kposE, m_data.params.kszE)," }, { "line": 2623, "text": " makeDecodeEntry(2, m_data.params.kposC, m_data.params.kszC)," }, { "line": 2624, "text": " makeDecodeEntry(1, m_data.params.kposB, m_data.params.kszB)," }, { "line": 2625, "text": " makeDecodeEntry(0, m_data.params.kposA," }, { "line": 2626, "text": " m_data.params.kszA)}};" }, { "line": 2627, "text": "" }, { "line": 2628, "text": " public:" }, { "line": 2629, "text": " // Constructor" }, { "line": 2630, "text": "" }, { "line": 2631, "text": " explicit Impl(struct dec_data &data) : m_data(data) {}" }, { "line": 2632, "text": "" }, { "line": 2633, "text": " // Execute a decoding pass, using the supplied event emitter to" }, { "line": 2634, "text": " // emit events as they occur." }, { "line": 2635, "text": "" }, { "line": 2636, "text": " void operator()(::JS8::Event::Emitter emitEvent) {" }, { "line": 2637, "text": " // The multi-decoder can provide data for multiple modes at" }, { "line": 2638, "text": " // the same time; specific decodes to be performed for this" }, { "line": 2639, "text": " // pass are in the `nsubmodes` bitset." }, { "line": 2640, "text": "" }, { "line": 2641, "text": " auto const set = m_data.params.nsubmodes;" }, { "line": 2642, "text": " std::size_t sum = 0;" }, { "line": 2643, "text": "" }, { "line": 2644, "text": " // Let any interested parties know that we've started a run" }, { "line": 2645, "text": " // for the set of modes requested." } ] } } ], "keyword_snippets": [ { "line": 11, "matches": [ "whiten" ], "snippet": { "start_line": 5, "end_line": 17, "lines": [ { "line": 5, "text": " * (C) 2025 Allan Bazinet - All Rights Reserved" }, { "line": 6, "text": " */" }, { "line": 7, "text": "" }, { "line": 8, "text": "#include \"JS8.h\"" }, { "line": 9, "text": "#include \"JS8_Include/commons.h\"" }, { "line": 10, "text": "#include \"JS8_Mode/FrequencyTracker.h\"" }, { "line": 11, "text": "#include \"JS8_Mode/whitening_processor.h\"" }, { "line": 12, "text": "#include \"ldpc_feedback.h\"" }, { "line": 13, "text": "#include \"soft_combiner.h\"" }, { "line": 14, "text": "" }, { "line": 15, "text": "#include " }, { "line": 16, "text": "#include " }, { "line": 17, "text": "#include " } ] } }, { "line": 21, "matches": [ "crc" ], "snippet": { "start_line": 15, "end_line": 27, "lines": [ { "line": 15, "text": "#include " }, { "line": 16, "text": "#include " }, { "line": 17, "text": "#include " }, { "line": 18, "text": "" }, { "line": 19, "text": "#include " }, { "line": 20, "text": "#include " }, { "line": 21, "text": "#include " }, { "line": 22, "text": "#include " }, { "line": 23, "text": "#include " }, { "line": 24, "text": "#include " }, { "line": 25, "text": "#include " }, { "line": 26, "text": "#include " }, { "line": 27, "text": "#include " } ] } }, { "line": 50, "matches": [ "decode" ], "snippet": { "start_line": 44, "end_line": 56, "lines": [ { "line": 44, "text": "#include " }, { "line": 45, "text": "#include " }, { "line": 46, "text": "#include " }, { "line": 47, "text": "#include " }, { "line": 48, "text": "#include " }, { "line": 49, "text": "" }, { "line": 50, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);" }, { "line": 51, "text": "" }, { "line": 52, "text": "// A C++ conversion of the Fortran JS8 encoding and decoder function." }, { "line": 53, "text": "// Some notes on the conversion:" }, { "line": 54, "text": "//" }, { "line": 55, "text": "// 1. Names of variables and functions as much as possible match those" }, { "line": 56, "text": "// of the Fortran routines, for ease in cross-referencing during the" } ] } }, { "line": 52, "matches": [ "decode" ], "snippet": { "start_line": 46, "end_line": 58, "lines": [ { "line": 46, "text": "#include " }, { "line": 47, "text": "#include " }, { "line": 48, "text": "#include " }, { "line": 49, "text": "" }, { "line": 50, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);" }, { "line": 51, "text": "" }, { "line": 52, "text": "// A C++ conversion of the Fortran JS8 encoding and decoder function." }, { "line": 53, "text": "// Some notes on the conversion:" }, { "line": 54, "text": "//" }, { "line": 55, "text": "// 1. Names of variables and functions as much as possible match those" }, { "line": 56, "text": "// of the Fortran routines, for ease in cross-referencing during the" }, { "line": 57, "text": "// debug comparison phase of testing. You don't have to like them; I" }, { "line": 58, "text": "// don't like them either, frankly, but it's the reasonable approach" } ] } }, { "line": 61, "matches": [ "decode" ], "snippet": { "start_line": 55, "end_line": 67, "lines": [ { "line": 55, "text": "// 1. Names of variables and functions as much as possible match those" }, { "line": 56, "text": "// of the Fortran routines, for ease in cross-referencing during the" }, { "line": 57, "text": "// debug comparison phase of testing. You don't have to like them; I" }, { "line": 58, "text": "// don't like them either, frankly, but it's the reasonable approach" }, { "line": 59, "text": "// to the problem as of this writing; we can make 'em pretty later." }, { "line": 60, "text": "//" }, { "line": 61, "text": "// 2. The BP decoder should be a faithful reproduction of the Fortran" }, { "line": 62, "text": "// version, albeit modified for the column-major vs. row-major" }, { "line": 63, "text": "// differences between the two languages." }, { "line": 64, "text": "//" }, { "line": 65, "text": "// 3. The OSD decoder is no longer used, and the depth is now fixed at" }, { "line": 66, "text": "// 2, instead of being variable 1 to 4." }, { "line": 67, "text": "//" } ] } }, { "line": 83, "matches": [ "decode" ], "snippet": { "start_line": 77, "end_line": 89, "lines": [ { "line": 77, "text": "// a number of Chebyshev nodes proportional to the desired polynomial" }, { "line": 78, "text": "// terms." }, { "line": 79, "text": "//" }, { "line": 80, "text": "// 6. The Fortran version normalized `s1` by dividing by the median in" }, { "line": 81, "text": "// js8dec(), but did so in a naive manner, not checking for a median" }, { "line": 82, "text": "// of zero. Testing indicates that the normalization does not appear" }, { "line": 83, "text": "// to contribute to decoder yield, so it's been removed." }, { "line": 84, "text": "//" }, { "line": 85, "text": "// 7. Translating array indices from the world of Fortran to that of C++" }, { "line": 86, "text": "// is no one's fun task. If you see things that aren't behaving as" }, { "line": 87, "text": "// expected, look at the Fortran code and compare the array indexing;" }, { "line": 88, "text": "// would not be surprised in the least to have off-by-one errors here." }, { "line": 89, "text": "" } ] } }, { "line": 164, "matches": [ "crc" ], "snippet": { "start_line": 158, "end_line": 170, "lines": [ { "line": 158, "text": "" }, { "line": 159, "text": "namespace {" }, { "line": 160, "text": "/* COMMON PARAMETERS */" }, { "line": 161, "text": "" }, { "line": 162, "text": "// !Common" }, { "line": 163, "text": "//" }, { "line": 164, "text": "// parameter (KK=87) !Information bits (75 + CRC12)" }, { "line": 165, "text": "// parameter (ND=58) !Data symbols" }, { "line": 166, "text": "// parameter (NS=21) !Sync symbols (3 @ Costas 7x7)" }, { "line": 167, "text": "// parameter (NN=NS+ND) !Total channel symbols (79)" }, { "line": 168, "text": "// parameter (ASYNCMIN=1.5) !Minimum Sync" }, { "line": 169, "text": "// parameter (NFSRCH=5) !Search frequency range in Hz (i.e.," }, { "line": 170, "text": "// +/- 2.5 Hz) parameter (NMAXCAND=300) !Maximum number of" } ] } }, { "line": 166, "matches": [ "symbol" ], "snippet": { "start_line": 160, "end_line": 172, "lines": [ { "line": 160, "text": "/* COMMON PARAMETERS */" }, { "line": 161, "text": "" }, { "line": 162, "text": "// !Common" }, { "line": 163, "text": "//" }, { "line": 164, "text": "// parameter (KK=87) !Information bits (75 + CRC12)" }, { "line": 165, "text": "// parameter (ND=58) !Data symbols" }, { "line": 166, "text": "// parameter (NS=21) !Sync symbols (3 @ Costas 7x7)" }, { "line": 167, "text": "// parameter (NN=NS+ND) !Total channel symbols (79)" }, { "line": 168, "text": "// parameter (ASYNCMIN=1.5) !Minimum Sync" }, { "line": 169, "text": "// parameter (NFSRCH=5) !Search frequency range in Hz (i.e.," }, { "line": 170, "text": "// +/- 2.5 Hz) parameter (NMAXCAND=300) !Maximum number of" }, { "line": 171, "text": "// candidate signals" }, { "line": 172, "text": "" } ] } }, { "line": 174, "matches": [ "message", "crc" ], "snippet": { "start_line": 168, "end_line": 180, "lines": [ { "line": 168, "text": "// parameter (ASYNCMIN=1.5) !Minimum Sync" }, { "line": 169, "text": "// parameter (NFSRCH=5) !Search frequency range in Hz (i.e.," }, { "line": 170, "text": "// +/- 2.5 Hz) parameter (NMAXCAND=300) !Maximum number of" }, { "line": 171, "text": "// candidate signals" }, { "line": 172, "text": "" }, { "line": 173, "text": "// Parameter\tValue\tDescription" }, { "line": 174, "text": "// KK\t87\tNumber of information bits (75 message bits + 12 CRC bits)." }, { "line": 175, "text": "// ND\t58\tNumber of data symbols in the JS8 transmission." }, { "line": 176, "text": "// NS\t21\tNumber of synchronization symbols (3 Costas arrays of size 7)." }, { "line": 177, "text": "// NN\t79\tTotal number of channel symbols (NN = NS + ND)." }, { "line": 178, "text": "// ASYNCMIN\t1.5\tMinimum sync value for successful decoding." }, { "line": 179, "text": "// NFSRCH\t5\tSearch frequency range in Hz (±2.5 Hz)." }, { "line": 180, "text": "// NMAXCAND\t300\tMaximum number of candidate signals." } ] } }, { "line": 176, "matches": [ "symbol" ], "snippet": { "start_line": 170, "end_line": 182, "lines": [ { "line": 170, "text": "// +/- 2.5 Hz) parameter (NMAXCAND=300) !Maximum number of" }, { "line": 171, "text": "// candidate signals" }, { "line": 172, "text": "" }, { "line": 173, "text": "// Parameter\tValue\tDescription" }, { "line": 174, "text": "// KK\t87\tNumber of information bits (75 message bits + 12 CRC bits)." }, { "line": 175, "text": "// ND\t58\tNumber of data symbols in the JS8 transmission." }, { "line": 176, "text": "// NS\t21\tNumber of synchronization symbols (3 Costas arrays of size 7)." }, { "line": 177, "text": "// NN\t79\tTotal number of channel symbols (NN = NS + ND)." }, { "line": 178, "text": "// ASYNCMIN\t1.5\tMinimum sync value for successful decoding." }, { "line": 179, "text": "// NFSRCH\t5\tSearch frequency range in Hz (±2.5 Hz)." }, { "line": 180, "text": "// NMAXCAND\t300\tMaximum number of candidate signals." }, { "line": 181, "text": "" }, { "line": 182, "text": "constexpr int N = 174; // Total bits" } ] } }, { "line": 183, "matches": [ "message" ], "snippet": { "start_line": 177, "end_line": 189, "lines": [ { "line": 177, "text": "// NN\t79\tTotal number of channel symbols (NN = NS + ND)." }, { "line": 178, "text": "// ASYNCMIN\t1.5\tMinimum sync value for successful decoding." }, { "line": 179, "text": "// NFSRCH\t5\tSearch frequency range in Hz (±2.5 Hz)." }, { "line": 180, "text": "// NMAXCAND\t300\tMaximum number of candidate signals." }, { "line": 181, "text": "" }, { "line": 182, "text": "constexpr int N = 174; // Total bits" }, { "line": 183, "text": "constexpr int K = 87; // Message bits" }, { "line": 184, "text": "constexpr int M = N - K; // Check bits" }, { "line": 185, "text": "constexpr int KK = 87; // Information bits (75 + CRC12)" }, { "line": 186, "text": "constexpr int ND = 58; // Data symbols" }, { "line": 187, "text": "constexpr int NS = 21; // Sync symbols (3 @ Costas 7x7)" }, { "line": 188, "text": "constexpr int NN = NS + ND; // Total channel symbols (79)" }, { "line": 189, "text": "constexpr float ASYNCMIN = 1.5f; // Minimum sync" } ] } }, { "line": 186, "matches": [ "symbol" ], "snippet": { "start_line": 180, "end_line": 192, "lines": [ { "line": 180, "text": "// NMAXCAND\t300\tMaximum number of candidate signals." }, { "line": 181, "text": "" }, { "line": 182, "text": "constexpr int N = 174; // Total bits" }, { "line": 183, "text": "constexpr int K = 87; // Message bits" }, { "line": 184, "text": "constexpr int M = N - K; // Check bits" }, { "line": 185, "text": "constexpr int KK = 87; // Information bits (75 + CRC12)" }, { "line": 186, "text": "constexpr int ND = 58; // Data symbols" }, { "line": 187, "text": "constexpr int NS = 21; // Sync symbols (3 @ Costas 7x7)" }, { "line": 188, "text": "constexpr int NN = NS + ND; // Total channel symbols (79)" }, { "line": 189, "text": "constexpr float ASYNCMIN = 1.5f; // Minimum sync" }, { "line": 190, "text": "constexpr int NFSRCH = 5; // Search frequency range in Hz (i.e., +/- 2.5 Hz)" }, { "line": 191, "text": "constexpr std::size_t NMAXCAND = 300; // Maxiumum number of candidate signals" }, { "line": 192, "text": "constexpr int NFILT = 1400; // Filter length" } ] } }, { "line": 207, "matches": [ "symbol" ], "snippet": { "start_line": 201, "end_line": 213, "lines": [ { "line": 201, "text": "// Key for the constants that follow:" }, { "line": 202, "text": "//" }, { "line": 203, "text": "// NSUBMODE - ID of the submode" }, { "line": 204, "text": "// NCOSTAS - Which JS8 Costas Arrays to use" }, { "line": 205, "text": "// NSPS - Number of samples per second" }, { "line": 206, "text": "// NTXDUR - Duration of the transmission in seconds." }, { "line": 207, "text": "// NDOWNSPS - Number of samples per symbol after downsampling." }, { "line": 208, "text": "// NDD - Parameter used in waveform tapering and related calculations." }, { "line": 209, "text": "// XXX JZ - Range of symbol offsets considered during decoding. ASTART" }, { "line": 210, "text": "// - Start delay in seconds for decoding. BASESUB - XXX NMAX - Samples in" }, { "line": 211, "text": "// input wave NSTEP - Rough time-sync step size NHSYM - Number of symbol" }, { "line": 212, "text": "// spectra (1/4-sym steps) NDOW - Downsample factor to 32 samples per" }, { "line": 213, "text": "// symbol NQSYMBOL - Downsample factor of a quarter symbol" } ] } }, { "line": 211, "matches": [ "symbol" ], "snippet": { "start_line": 205, "end_line": 217, "lines": [ { "line": 205, "text": "// NSPS - Number of samples per second" }, { "line": 206, "text": "// NTXDUR - Duration of the transmission in seconds." }, { "line": 207, "text": "// NDOWNSPS - Number of samples per symbol after downsampling." }, { "line": 208, "text": "// NDD - Parameter used in waveform tapering and related calculations." }, { "line": 209, "text": "// XXX JZ - Range of symbol offsets considered during decoding. ASTART" }, { "line": 210, "text": "// - Start delay in seconds for decoding. BASESUB - XXX NMAX - Samples in" }, { "line": 211, "text": "// input wave NSTEP - Rough time-sync step size NHSYM - Number of symbol" }, { "line": 212, "text": "// spectra (1/4-sym steps) NDOW - Downsample factor to 32 samples per" }, { "line": 213, "text": "// symbol NQSYMBOL - Downsample factor of a quarter symbol" }, { "line": 214, "text": "" }, { "line": 215, "text": "/* A MODE DECODER */" }, { "line": 216, "text": "" }, { "line": 217, "text": "struct ModeA {" } ] } }, { "line": 221, "matches": [ "symbol" ], "snippet": { "start_line": 215, "end_line": 227, "lines": [ { "line": 215, "text": "/* A MODE DECODER */" }, { "line": 216, "text": "" }, { "line": 217, "text": "struct ModeA {" }, { "line": 218, "text": " // Static constants" }, { "line": 219, "text": " inline static constexpr int NSUBMODE = 0;" }, { "line": 220, "text": " inline static constexpr auto NCOSTAS = JS8::Costas::Type::ORIGINAL;" }, { "line": 221, "text": " inline static constexpr int NSPS = JS8A_SYMBOL_SAMPLES;" }, { "line": 222, "text": " inline static constexpr int NTXDUR = JS8A_TX_SECONDS;" }, { "line": 223, "text": " inline static constexpr int NDOWNSPS = 32;" }, { "line": 224, "text": " inline static constexpr int NDD = 100;" }, { "line": 225, "text": " inline static constexpr int JZ = 62;" }, { "line": 226, "text": " inline static constexpr float ASTART = 0.5f;" }, { "line": 227, "text": " inline static constexpr float BASESUB = 40.0f;" } ] } }, { "line": 236, "matches": [ "symbol" ], "snippet": { "start_line": 230, "end_line": 242, "lines": [ { "line": 230, "text": " inline static constexpr float AZ = (12000.0f / NSPS) * 0.64f;" }, { "line": 231, "text": " inline static constexpr int NMAX = NTXDUR * JS8_RX_SAMPLE_RATE;" }, { "line": 232, "text": " inline static constexpr int NFFT1 = NSPS * NFOS;" }, { "line": 233, "text": " inline static constexpr int NSTEP = NSPS / NSSY;" }, { "line": 234, "text": " inline static constexpr int NHSYM = NMAX / NSTEP - 3;" }, { "line": 235, "text": " inline static constexpr int NDOWN = NSPS / NDOWNSPS;" }, { "line": 236, "text": " inline static constexpr int NQSYMBOL = NDOWNSPS / 4;" }, { "line": 237, "text": " inline static constexpr int NDFFT1 = NSPS * NDD;" }, { "line": 238, "text": " inline static constexpr int NDFFT2 = NDFFT1 / NDOWN;" }, { "line": 239, "text": " inline static constexpr int NP2 = NN * NDOWNSPS;" }, { "line": 240, "text": " inline static constexpr float TSTEP = NSTEP / 12000.0f;" }, { "line": 241, "text": " inline static constexpr int JSTRT = ASTART / TSTEP;" }, { "line": 242, "text": " inline static constexpr float DF = 12000.0f / NFFT1;" } ] } }, { "line": 245, "matches": [ "decode" ], "snippet": { "start_line": 239, "end_line": 251, "lines": [ { "line": 239, "text": " inline static constexpr int NP2 = NN * NDOWNSPS;" }, { "line": 240, "text": " inline static constexpr float TSTEP = NSTEP / 12000.0f;" }, { "line": 241, "text": " inline static constexpr int JSTRT = ASTART / TSTEP;" }, { "line": 242, "text": " inline static constexpr float DF = 12000.0f / NFFT1;" }, { "line": 243, "text": "};" }, { "line": 244, "text": "" }, { "line": 245, "text": "/* B MODE DECODER */" }, { "line": 246, "text": "" }, { "line": 247, "text": "struct ModeB {" }, { "line": 248, "text": " // Static constants" }, { "line": 249, "text": " inline static constexpr int NSUBMODE = 1;" }, { "line": 250, "text": " inline static constexpr auto NCOSTAS = JS8::Costas::Type::MODIFIED;" }, { "line": 251, "text": " inline static constexpr int NSPS = JS8B_SYMBOL_SAMPLES;" } ] } }, { "line": 251, "matches": [ "symbol" ], "snippet": { "start_line": 245, "end_line": 257, "lines": [ { "line": 245, "text": "/* B MODE DECODER */" }, { "line": 246, "text": "" }, { "line": 247, "text": "struct ModeB {" }, { "line": 248, "text": " // Static constants" }, { "line": 249, "text": " inline static constexpr int NSUBMODE = 1;" }, { "line": 250, "text": " inline static constexpr auto NCOSTAS = JS8::Costas::Type::MODIFIED;" }, { "line": 251, "text": " inline static constexpr int NSPS = JS8B_SYMBOL_SAMPLES;" }, { "line": 252, "text": " inline static constexpr int NTXDUR = JS8B_TX_SECONDS;" }, { "line": 253, "text": " inline static constexpr int NDOWNSPS = 20;" }, { "line": 254, "text": " inline static constexpr int NDD = 100;" }, { "line": 255, "text": " inline static constexpr int JZ = 144;" }, { "line": 256, "text": " inline static constexpr float ASTART = 0.2f;" }, { "line": 257, "text": " inline static constexpr float BASESUB = 39.0f;" } ] } }, { "line": 266, "matches": [ "symbol" ], "snippet": { "start_line": 260, "end_line": 272, "lines": [ { "line": 260, "text": " inline static constexpr float AZ = (12000.0f / NSPS) * 0.8f;" }, { "line": 261, "text": " inline static constexpr int NMAX = NTXDUR * JS8_RX_SAMPLE_RATE;" }, { "line": 262, "text": " inline static constexpr int NFFT1 = NSPS * NFOS;" }, { "line": 263, "text": " inline static constexpr int NSTEP = NSPS / NSSY;" }, { "line": 264, "text": " inline static constexpr int NHSYM = NMAX / NSTEP - 3;" }, { "line": 265, "text": " inline static constexpr int NDOWN = NSPS / NDOWNSPS;" }, { "line": 266, "text": " inline static constexpr int NQSYMBOL = NDOWNSPS / 4;" }, { "line": 267, "text": " inline static constexpr int NDFFT1 = NSPS * NDD;" }, { "line": 268, "text": " inline static constexpr int NDFFT2 = NDFFT1 / NDOWN;" }, { "line": 269, "text": " inline static constexpr int NP2 = NN * NDOWNSPS;" }, { "line": 270, "text": " inline static constexpr float TSTEP = NSTEP / 12000.0f;" }, { "line": 271, "text": " inline static constexpr int JSTRT = ASTART / TSTEP;" }, { "line": 272, "text": " inline static constexpr float DF = 12000.0f / NFFT1;" } ] } }, { "line": 275, "matches": [ "decode" ], "snippet": { "start_line": 269, "end_line": 281, "lines": [ { "line": 269, "text": " inline static constexpr int NP2 = NN * NDOWNSPS;" }, { "line": 270, "text": " inline static constexpr float TSTEP = NSTEP / 12000.0f;" }, { "line": 271, "text": " inline static constexpr int JSTRT = ASTART / TSTEP;" }, { "line": 272, "text": " inline static constexpr float DF = 12000.0f / NFFT1;" }, { "line": 273, "text": "};" }, { "line": 274, "text": "" }, { "line": 275, "text": "/* C MODE DECODER */" }, { "line": 276, "text": "" }, { "line": 277, "text": "struct ModeC {" }, { "line": 278, "text": " // Static constants" }, { "line": 279, "text": " inline static constexpr int NSUBMODE = 2;" }, { "line": 280, "text": " inline static constexpr auto NCOSTAS = JS8::Costas::Type::MODIFIED;" }, { "line": 281, "text": " inline static constexpr int NSPS = JS8C_SYMBOL_SAMPLES;" } ] } }, { "line": 281, "matches": [ "symbol" ], "snippet": { "start_line": 275, "end_line": 287, "lines": [ { "line": 275, "text": "/* C MODE DECODER */" }, { "line": 276, "text": "" }, { "line": 277, "text": "struct ModeC {" }, { "line": 278, "text": " // Static constants" }, { "line": 279, "text": " inline static constexpr int NSUBMODE = 2;" }, { "line": 280, "text": " inline static constexpr auto NCOSTAS = JS8::Costas::Type::MODIFIED;" }, { "line": 281, "text": " inline static constexpr int NSPS = JS8C_SYMBOL_SAMPLES;" }, { "line": 282, "text": " inline static constexpr int NTXDUR = JS8C_TX_SECONDS;" }, { "line": 283, "text": " inline static constexpr int NDOWNSPS = 12;" }, { "line": 284, "text": " inline static constexpr int NDD = 120;" }, { "line": 285, "text": " inline static constexpr int JZ = 172;" }, { "line": 286, "text": " inline static constexpr float ASTART = 0.1f;" }, { "line": 287, "text": " inline static constexpr float BASESUB = 38.0f;" } ] } }, { "line": 296, "matches": [ "symbol" ], "snippet": { "start_line": 290, "end_line": 302, "lines": [ { "line": 290, "text": " inline static constexpr float AZ = (12000.0f / NSPS) * 0.6f;" }, { "line": 291, "text": " inline static constexpr int NMAX = NTXDUR * JS8_RX_SAMPLE_RATE;" }, { "line": 292, "text": " inline static constexpr int NFFT1 = NSPS * NFOS;" }, { "line": 293, "text": " inline static constexpr int NSTEP = NSPS / NSSY;" }, { "line": 294, "text": " inline static constexpr int NHSYM = NMAX / NSTEP - 3;" }, { "line": 295, "text": " inline static constexpr int NDOWN = NSPS / NDOWNSPS;" }, { "line": 296, "text": " inline static constexpr int NQSYMBOL = NDOWNSPS / 4;" }, { "line": 297, "text": " inline static constexpr int NDFFT1 = NSPS * NDD;" }, { "line": 298, "text": " inline static constexpr int NDFFT2 = NDFFT1 / NDOWN;" }, { "line": 299, "text": " inline static constexpr int NP2 = NN * NDOWNSPS;" }, { "line": 300, "text": " inline static constexpr float TSTEP = NSTEP / 12000.0f;" }, { "line": 301, "text": " inline static constexpr int JSTRT = ASTART / TSTEP;" }, { "line": 302, "text": " inline static constexpr float DF = 12000.0f / NFFT1;" } ] } } ] }, { "path": "JS8_Mode/Decoder.cpp", "exists": true, "bytes": 3646, "sha256": "9662f0bb9c739aad5b4e3031f2c4707b9c5f15746ae1739830c78fbbcf1d66d1", "line_count": 139, "phase_hits": { "timing_submode": 0, "symbol_to_soft_bits": 0, "bit_order_interleaver": 0, "whitening_erasure": 0, "ldpc_decode": 0, "message91_crc_text": 0 }, "function_blocks": [ { "function": "Decoder::lock", "line": 24, "signature": "void Decoder::lock() {", "snippet": { "start_line": 10, "end_line": 38, "lines": [ { "line": 10, "text": "#include " }, { "line": 11, "text": "#include " }, { "line": 12, "text": "" }, { "line": 13, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8)" }, { "line": 14, "text": "" }, { "line": 15, "text": "Do not let youself be confused" }, { "line": 16, "text": " : This source file does not presently take part in the build." }, { "line": 17, "text": "" }, { "line": 18, "text": " Decoder::Decoder(QObject * parent)" }, { "line": 19, "text": " : QObject(parent) {}" }, { "line": 20, "text": "" }, { "line": 21, "text": "Decoder::~Decoder() {}" }, { "line": 22, "text": "" }, { "line": 23, "text": "//" }, { "line": 24, "text": "void Decoder::lock() {" }, { "line": 25, "text": " // NOOP" }, { "line": 26, "text": "}" }, { "line": 27, "text": "" }, { "line": 28, "text": "//" }, { "line": 29, "text": "void Decoder::unlock() {" }, { "line": 30, "text": " // NOOP" }, { "line": 31, "text": "}" }, { "line": 32, "text": "" }, { "line": 33, "text": "//" }, { "line": 34, "text": "Worker *Decoder::createWorker() {" }, { "line": 35, "text": " auto worker = new Worker();" }, { "line": 36, "text": " worker->moveToThread(&m_thread);" }, { "line": 37, "text": " connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);" }, { "line": 38, "text": " connect(this, &Decoder::startWorker, worker, &Worker::start);" } ] } }, { "function": "Decoder::unlock", "line": 29, "signature": "void Decoder::unlock() {", "snippet": { "start_line": 15, "end_line": 43, "lines": [ { "line": 15, "text": "Do not let youself be confused" }, { "line": 16, "text": " : This source file does not presently take part in the build." }, { "line": 17, "text": "" }, { "line": 18, "text": " Decoder::Decoder(QObject * parent)" }, { "line": 19, "text": " : QObject(parent) {}" }, { "line": 20, "text": "" }, { "line": 21, "text": "Decoder::~Decoder() {}" }, { "line": 22, "text": "" }, { "line": 23, "text": "//" }, { "line": 24, "text": "void Decoder::lock() {" }, { "line": 25, "text": " // NOOP" }, { "line": 26, "text": "}" }, { "line": 27, "text": "" }, { "line": 28, "text": "//" }, { "line": 29, "text": "void Decoder::unlock() {" }, { "line": 30, "text": " // NOOP" }, { "line": 31, "text": "}" }, { "line": 32, "text": "" }, { "line": 33, "text": "//" }, { "line": 34, "text": "Worker *Decoder::createWorker() {" }, { "line": 35, "text": " auto worker = new Worker();" }, { "line": 36, "text": " worker->moveToThread(&m_thread);" }, { "line": 37, "text": " connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);" }, { "line": 38, "text": " connect(this, &Decoder::startWorker, worker, &Worker::start);" }, { "line": 39, "text": " connect(this, &Decoder::quitWorker, worker, &Worker::quit);" }, { "line": 40, "text": " connect(worker, &Worker::ready, this, &Decoder::processReady);" }, { "line": 41, "text": " connect(worker, &Worker::error, this, &Decoder::processError);" }, { "line": 42, "text": " connect(worker, &Worker::finished, this, &Decoder::processFinished);" }, { "line": 43, "text": " return worker;" } ] } }, { "function": "Decoder::start", "line": 47, "signature": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }", "snippet": { "start_line": 33, "end_line": 61, "lines": [ { "line": 33, "text": "//" }, { "line": 34, "text": "Worker *Decoder::createWorker() {" }, { "line": 35, "text": " auto worker = new Worker();" }, { "line": 36, "text": " worker->moveToThread(&m_thread);" }, { "line": 37, "text": " connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);" }, { "line": 38, "text": " connect(this, &Decoder::startWorker, worker, &Worker::start);" }, { "line": 39, "text": " connect(this, &Decoder::quitWorker, worker, &Worker::quit);" }, { "line": 40, "text": " connect(worker, &Worker::ready, this, &Decoder::processReady);" }, { "line": 41, "text": " connect(worker, &Worker::error, this, &Decoder::processError);" }, { "line": 42, "text": " connect(worker, &Worker::finished, this, &Decoder::processFinished);" }, { "line": 43, "text": " return worker;" }, { "line": 44, "text": "}" }, { "line": 45, "text": "" }, { "line": 46, "text": "//" }, { "line": 47, "text": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }" }, { "line": 48, "text": "" }, { "line": 49, "text": "//" }, { "line": 50, "text": "void Decoder::quit() { m_thread.quit(); }" }, { "line": 51, "text": "" }, { "line": 52, "text": "//" }, { "line": 53, "text": "bool Decoder::wait() { return m_thread.wait(); }" }, { "line": 54, "text": "" }, { "line": 55, "text": "//" }, { "line": 56, "text": "void Decoder::processStart(QString path, QStringList args) {" }, { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" }, { "line": 60, "text": "" }, { "line": 61, "text": " emit startWorker(path, args);" } ] } }, { "function": "Decoder::quit", "line": 50, "signature": "void Decoder::quit() { m_thread.quit(); }", "snippet": { "start_line": 36, "end_line": 64, "lines": [ { "line": 36, "text": " worker->moveToThread(&m_thread);" }, { "line": 37, "text": " connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);" }, { "line": 38, "text": " connect(this, &Decoder::startWorker, worker, &Worker::start);" }, { "line": 39, "text": " connect(this, &Decoder::quitWorker, worker, &Worker::quit);" }, { "line": 40, "text": " connect(worker, &Worker::ready, this, &Decoder::processReady);" }, { "line": 41, "text": " connect(worker, &Worker::error, this, &Decoder::processError);" }, { "line": 42, "text": " connect(worker, &Worker::finished, this, &Decoder::processFinished);" }, { "line": 43, "text": " return worker;" }, { "line": 44, "text": "}" }, { "line": 45, "text": "" }, { "line": 46, "text": "//" }, { "line": 47, "text": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }" }, { "line": 48, "text": "" }, { "line": 49, "text": "//" }, { "line": 50, "text": "void Decoder::quit() { m_thread.quit(); }" }, { "line": 51, "text": "" }, { "line": 52, "text": "//" }, { "line": 53, "text": "bool Decoder::wait() { return m_thread.wait(); }" }, { "line": 54, "text": "" }, { "line": 55, "text": "//" }, { "line": 56, "text": "void Decoder::processStart(QString path, QStringList args) {" }, { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" }, { "line": 60, "text": "" }, { "line": 61, "text": " emit startWorker(path, args);" }, { "line": 62, "text": "}" }, { "line": 63, "text": "" }, { "line": 64, "text": "//" } ] } }, { "function": "Decoder::wait", "line": 53, "signature": "bool Decoder::wait() { return m_thread.wait(); }", "snippet": { "start_line": 39, "end_line": 67, "lines": [ { "line": 39, "text": " connect(this, &Decoder::quitWorker, worker, &Worker::quit);" }, { "line": 40, "text": " connect(worker, &Worker::ready, this, &Decoder::processReady);" }, { "line": 41, "text": " connect(worker, &Worker::error, this, &Decoder::processError);" }, { "line": 42, "text": " connect(worker, &Worker::finished, this, &Decoder::processFinished);" }, { "line": 43, "text": " return worker;" }, { "line": 44, "text": "}" }, { "line": 45, "text": "" }, { "line": 46, "text": "//" }, { "line": 47, "text": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }" }, { "line": 48, "text": "" }, { "line": 49, "text": "//" }, { "line": 50, "text": "void Decoder::quit() { m_thread.quit(); }" }, { "line": 51, "text": "" }, { "line": 52, "text": "//" }, { "line": 53, "text": "bool Decoder::wait() { return m_thread.wait(); }" }, { "line": 54, "text": "" }, { "line": 55, "text": "//" }, { "line": 56, "text": "void Decoder::processStart(QString path, QStringList args) {" }, { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" }, { "line": 60, "text": "" }, { "line": 61, "text": " emit startWorker(path, args);" }, { "line": 62, "text": "}" }, { "line": 63, "text": "" }, { "line": 64, "text": "//" }, { "line": 65, "text": "void Decoder::processReady(QByteArray t) { emit ready(t); }" }, { "line": 66, "text": "" }, { "line": 67, "text": "//" } ] } }, { "function": "Decoder::processStart", "line": 56, "signature": "void Decoder::processStart(QString path, QStringList args) {", "snippet": { "start_line": 42, "end_line": 70, "lines": [ { "line": 42, "text": " connect(worker, &Worker::finished, this, &Decoder::processFinished);" }, { "line": 43, "text": " return worker;" }, { "line": 44, "text": "}" }, { "line": 45, "text": "" }, { "line": 46, "text": "//" }, { "line": 47, "text": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }" }, { "line": 48, "text": "" }, { "line": 49, "text": "//" }, { "line": 50, "text": "void Decoder::quit() { m_thread.quit(); }" }, { "line": 51, "text": "" }, { "line": 52, "text": "//" }, { "line": 53, "text": "bool Decoder::wait() { return m_thread.wait(); }" }, { "line": 54, "text": "" }, { "line": 55, "text": "//" }, { "line": 56, "text": "void Decoder::processStart(QString path, QStringList args) {" }, { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" }, { "line": 60, "text": "" }, { "line": 61, "text": " emit startWorker(path, args);" }, { "line": 62, "text": "}" }, { "line": 63, "text": "" }, { "line": 64, "text": "//" }, { "line": 65, "text": "void Decoder::processReady(QByteArray t) { emit ready(t); }" }, { "line": 66, "text": "" }, { "line": 67, "text": "//" }, { "line": 68, "text": "void Decoder::processQuit() { emit quitWorker(); }" }, { "line": 69, "text": "" }, { "line": 70, "text": "//" } ] } }, { "function": "Decoder::processReady", "line": 65, "signature": "void Decoder::processReady(QByteArray t) { emit ready(t); }", "snippet": { "start_line": 51, "end_line": 79, "lines": [ { "line": 51, "text": "" }, { "line": 52, "text": "//" }, { "line": 53, "text": "bool Decoder::wait() { return m_thread.wait(); }" }, { "line": 54, "text": "" }, { "line": 55, "text": "//" }, { "line": 56, "text": "void Decoder::processStart(QString path, QStringList args) {" }, { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" }, { "line": 60, "text": "" }, { "line": 61, "text": " emit startWorker(path, args);" }, { "line": 62, "text": "}" }, { "line": 63, "text": "" }, { "line": 64, "text": "//" }, { "line": 65, "text": "void Decoder::processReady(QByteArray t) { emit ready(t); }" }, { "line": 66, "text": "" }, { "line": 67, "text": "//" }, { "line": 68, "text": "void Decoder::processQuit() { emit quitWorker(); }" }, { "line": 69, "text": "" }, { "line": 70, "text": "//" }, { "line": 71, "text": "void Decoder::processError(int errorCode, QString errorString) {" }, { "line": 72, "text": " qCDebug(decoder_js8) << \"decoder process error\" << errorCode << errorString;" }, { "line": 73, "text": " emit error(errorCode, errorString);" }, { "line": 74, "text": "}" }, { "line": 75, "text": "" }, { "line": 76, "text": "//" }, { "line": 77, "text": "void Decoder::processFinished(int exitCode, int statusCode," }, { "line": 78, "text": " QString errorString) {" }, { "line": 79, "text": " qCDebug(decoder_js8) << \"decoder process finished\" << exitCode << statusCode" } ] } }, { "function": "Decoder::processQuit", "line": 68, "signature": "void Decoder::processQuit() { emit quitWorker(); }", "snippet": { "start_line": 54, "end_line": 82, "lines": [ { "line": 54, "text": "" }, { "line": 55, "text": "//" }, { "line": 56, "text": "void Decoder::processStart(QString path, QStringList args) {" }, { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" }, { "line": 60, "text": "" }, { "line": 61, "text": " emit startWorker(path, args);" }, { "line": 62, "text": "}" }, { "line": 63, "text": "" }, { "line": 64, "text": "//" }, { "line": 65, "text": "void Decoder::processReady(QByteArray t) { emit ready(t); }" }, { "line": 66, "text": "" }, { "line": 67, "text": "//" }, { "line": 68, "text": "void Decoder::processQuit() { emit quitWorker(); }" }, { "line": 69, "text": "" }, { "line": 70, "text": "//" }, { "line": 71, "text": "void Decoder::processError(int errorCode, QString errorString) {" }, { "line": 72, "text": " qCDebug(decoder_js8) << \"decoder process error\" << errorCode << errorString;" }, { "line": 73, "text": " emit error(errorCode, errorString);" }, { "line": 74, "text": "}" }, { "line": 75, "text": "" }, { "line": 76, "text": "//" }, { "line": 77, "text": "void Decoder::processFinished(int exitCode, int statusCode," }, { "line": 78, "text": " QString errorString) {" }, { "line": 79, "text": " qCDebug(decoder_js8) << \"decoder process finished\" << exitCode << statusCode" }, { "line": 80, "text": " << errorString;" }, { "line": 81, "text": " emit finished(exitCode, statusCode, errorString);" }, { "line": 82, "text": "}" } ] } }, { "function": "Decoder::processError", "line": 71, "signature": "void Decoder::processError(int errorCode, QString errorString) {", "snippet": { "start_line": 57, "end_line": 85, "lines": [ { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" }, { "line": 60, "text": "" }, { "line": 61, "text": " emit startWorker(path, args);" }, { "line": 62, "text": "}" }, { "line": 63, "text": "" }, { "line": 64, "text": "//" }, { "line": 65, "text": "void Decoder::processReady(QByteArray t) { emit ready(t); }" }, { "line": 66, "text": "" }, { "line": 67, "text": "//" }, { "line": 68, "text": "void Decoder::processQuit() { emit quitWorker(); }" }, { "line": 69, "text": "" }, { "line": 70, "text": "//" }, { "line": 71, "text": "void Decoder::processError(int errorCode, QString errorString) {" }, { "line": 72, "text": " qCDebug(decoder_js8) << \"decoder process error\" << errorCode << errorString;" }, { "line": 73, "text": " emit error(errorCode, errorString);" }, { "line": 74, "text": "}" }, { "line": 75, "text": "" }, { "line": 76, "text": "//" }, { "line": 77, "text": "void Decoder::processFinished(int exitCode, int statusCode," }, { "line": 78, "text": " QString errorString) {" }, { "line": 79, "text": " qCDebug(decoder_js8) << \"decoder process finished\" << exitCode << statusCode" }, { "line": 80, "text": " << errorString;" }, { "line": 81, "text": " emit finished(exitCode, statusCode, errorString);" }, { "line": 82, "text": "}" }, { "line": 83, "text": "" }, { "line": 84, "text": "////////////////////////////////////////" }, { "line": 85, "text": "//////////////// WORKER ////////////////" } ] } }, { "function": "Worker::setProcess", "line": 92, "signature": "void Worker::setProcess(QProcess *proc, int msecs) {", "snippet": { "start_line": 78, "end_line": 106, "lines": [ { "line": 78, "text": " QString errorString) {" }, { "line": 79, "text": " qCDebug(decoder_js8) << \"decoder process finished\" << exitCode << statusCode" }, { "line": 80, "text": " << errorString;" }, { "line": 81, "text": " emit finished(exitCode, statusCode, errorString);" }, { "line": 82, "text": "}" }, { "line": 83, "text": "" }, { "line": 84, "text": "////////////////////////////////////////" }, { "line": 85, "text": "//////////////// WORKER ////////////////" }, { "line": 86, "text": "////////////////////////////////////////" }, { "line": 87, "text": "" }, { "line": 88, "text": "//" }, { "line": 89, "text": "Worker::~Worker() {}" }, { "line": 90, "text": "" }, { "line": 91, "text": "//" }, { "line": 92, "text": "void Worker::setProcess(QProcess *proc, int msecs) {" }, { "line": 93, "text": " if (!m_proc.isNull()) {" }, { "line": 94, "text": " bool b = m_proc->waitForFinished(msecs);" }, { "line": 95, "text": " if (!b)" }, { "line": 96, "text": " m_proc->close();" }, { "line": 97, "text": " m_proc.reset();" }, { "line": 98, "text": " }" }, { "line": 99, "text": "" }, { "line": 100, "text": " if (proc) {" }, { "line": 101, "text": " m_proc.reset(proc);" }, { "line": 102, "text": " }" }, { "line": 103, "text": "}" }, { "line": 104, "text": "" }, { "line": 105, "text": "//" }, { "line": 106, "text": "void Worker::start(QString path, QStringList args) {" } ] } }, { "function": "Worker::start", "line": 106, "signature": "void Worker::start(QString path, QStringList args) {", "snippet": { "start_line": 92, "end_line": 120, "lines": [ { "line": 92, "text": "void Worker::setProcess(QProcess *proc, int msecs) {" }, { "line": 93, "text": " if (!m_proc.isNull()) {" }, { "line": 94, "text": " bool b = m_proc->waitForFinished(msecs);" }, { "line": 95, "text": " if (!b)" }, { "line": 96, "text": " m_proc->close();" }, { "line": 97, "text": " m_proc.reset();" }, { "line": 98, "text": " }" }, { "line": 99, "text": "" }, { "line": 100, "text": " if (proc) {" }, { "line": 101, "text": " m_proc.reset(proc);" }, { "line": 102, "text": " }" }, { "line": 103, "text": "}" }, { "line": 104, "text": "" }, { "line": 105, "text": "//" }, { "line": 106, "text": "void Worker::start(QString path, QStringList args) {" }, { "line": 107, "text": " qCDebug(decoder_js8) << \"decoder process starting...\";" }, { "line": 108, "text": "" }, { "line": 109, "text": " auto proc = new QProcess(this);" }, { "line": 110, "text": "" }, { "line": 111, "text": " connect(proc, &QProcess::readyReadStandardOutput, [this, proc]() {" }, { "line": 112, "text": " while (proc->canReadLine()) {" }, { "line": 113, "text": " emit ready(proc->readLine());" }, { "line": 114, "text": " }" }, { "line": 115, "text": " });" }, { "line": 116, "text": "" }, { "line": 117, "text": " connect(proc, &QProcess::errorOccurred," }, { "line": 118, "text": " [this, proc](QProcess::ProcessError errorCode) {" }, { "line": 119, "text": " emit error(int(errorCode), proc->errorString());" }, { "line": 120, "text": " });" } ] } }, { "function": "Worker::quit", "line": 137, "signature": "void Worker::quit() { setProcess(nullptr); }", "snippet": { "start_line": 123, "end_line": 139, "lines": [ { "line": 123, "text": " [this, proc](int exitCode, QProcess::ExitStatus status) {" }, { "line": 124, "text": " emit finished(exitCode, int(status)," }, { "line": 125, "text": " QString{proc->readAllStandardError()});" }, { "line": 126, "text": " });" }, { "line": 127, "text": "" }, { "line": 128, "text": " QProcessEnvironment env{QProcessEnvironment::systemEnvironment()};" }, { "line": 129, "text": " env.insert(\"OMP_STACKSIZE\", \"4M\");" }, { "line": 130, "text": " proc->setProcessEnvironment(env);" }, { "line": 131, "text": " proc->start(path, args, QIODevice::ReadWrite | QIODevice::Unbuffered);" }, { "line": 132, "text": "" }, { "line": 133, "text": " setProcess(proc);" }, { "line": 134, "text": "}" }, { "line": 135, "text": "" }, { "line": 136, "text": "//" }, { "line": 137, "text": "void Worker::quit() { setProcess(nullptr); }" }, { "line": 138, "text": "" }, { "line": 139, "text": "Q_LOGGING_CATEGORY(decoder_js8, \"decoder.js8\", QtWarningMsg)" } ] } } ], "keyword_snippets": [ { "line": 2, "matches": [ "decode" ], "snippet": { "start_line": 1, "end_line": 8, "lines": [ { "line": 1, "text": "/**" }, { "line": 2, "text": " * @file Decoder.cpp" }, { "line": 3, "text": " * @brief Implementation of the JS8 decoder and worker classes" }, { "line": 4, "text": " * (C) 2019 Jordan Sherer - All Rights Reserved" }, { "line": 5, "text": " */" }, { "line": 6, "text": "" }, { "line": 7, "text": "#include \"Decoder.h\"" }, { "line": 8, "text": "#include \"JS8_Include/commons.h\"" } ] } }, { "line": 7, "matches": [ "decode" ], "snippet": { "start_line": 1, "end_line": 13, "lines": [ { "line": 1, "text": "/**" }, { "line": 2, "text": " * @file Decoder.cpp" }, { "line": 3, "text": " * @brief Implementation of the JS8 decoder and worker classes" }, { "line": 4, "text": " * (C) 2019 Jordan Sherer - All Rights Reserved" }, { "line": 5, "text": " */" }, { "line": 6, "text": "" }, { "line": 7, "text": "#include \"Decoder.h\"" }, { "line": 8, "text": "#include \"JS8_Include/commons.h\"" }, { "line": 9, "text": "" }, { "line": 10, "text": "#include " }, { "line": 11, "text": "#include " }, { "line": 12, "text": "" }, { "line": 13, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8)" } ] } }, { "line": 13, "matches": [ "decode", "JS8" ], "snippet": { "start_line": 7, "end_line": 19, "lines": [ { "line": 7, "text": "#include \"Decoder.h\"" }, { "line": 8, "text": "#include \"JS8_Include/commons.h\"" }, { "line": 9, "text": "" }, { "line": 10, "text": "#include " }, { "line": 11, "text": "#include " }, { "line": 12, "text": "" }, { "line": 13, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8)" }, { "line": 14, "text": "" }, { "line": 15, "text": "Do not let youself be confused" }, { "line": 16, "text": " : This source file does not presently take part in the build." }, { "line": 17, "text": "" }, { "line": 18, "text": " Decoder::Decoder(QObject * parent)" }, { "line": 19, "text": " : QObject(parent) {}" } ] } }, { "line": 18, "matches": [ "decode" ], "snippet": { "start_line": 12, "end_line": 24, "lines": [ { "line": 12, "text": "" }, { "line": 13, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8)" }, { "line": 14, "text": "" }, { "line": 15, "text": "Do not let youself be confused" }, { "line": 16, "text": " : This source file does not presently take part in the build." }, { "line": 17, "text": "" }, { "line": 18, "text": " Decoder::Decoder(QObject * parent)" }, { "line": 19, "text": " : QObject(parent) {}" }, { "line": 20, "text": "" }, { "line": 21, "text": "Decoder::~Decoder() {}" }, { "line": 22, "text": "" }, { "line": 23, "text": "//" }, { "line": 24, "text": "void Decoder::lock() {" } ] } }, { "line": 21, "matches": [ "decode" ], "snippet": { "start_line": 15, "end_line": 27, "lines": [ { "line": 15, "text": "Do not let youself be confused" }, { "line": 16, "text": " : This source file does not presently take part in the build." }, { "line": 17, "text": "" }, { "line": 18, "text": " Decoder::Decoder(QObject * parent)" }, { "line": 19, "text": " : QObject(parent) {}" }, { "line": 20, "text": "" }, { "line": 21, "text": "Decoder::~Decoder() {}" }, { "line": 22, "text": "" }, { "line": 23, "text": "//" }, { "line": 24, "text": "void Decoder::lock() {" }, { "line": 25, "text": " // NOOP" }, { "line": 26, "text": "}" }, { "line": 27, "text": "" } ] } }, { "line": 29, "matches": [ "decode" ], "snippet": { "start_line": 23, "end_line": 35, "lines": [ { "line": 23, "text": "//" }, { "line": 24, "text": "void Decoder::lock() {" }, { "line": 25, "text": " // NOOP" }, { "line": 26, "text": "}" }, { "line": 27, "text": "" }, { "line": 28, "text": "//" }, { "line": 29, "text": "void Decoder::unlock() {" }, { "line": 30, "text": " // NOOP" }, { "line": 31, "text": "}" }, { "line": 32, "text": "" }, { "line": 33, "text": "//" }, { "line": 34, "text": "Worker *Decoder::createWorker() {" }, { "line": 35, "text": " auto worker = new Worker();" } ] } }, { "line": 34, "matches": [ "decode", "Worker" ], "snippet": { "start_line": 28, "end_line": 40, "lines": [ { "line": 28, "text": "//" }, { "line": 29, "text": "void Decoder::unlock() {" }, { "line": 30, "text": " // NOOP" }, { "line": 31, "text": "}" }, { "line": 32, "text": "" }, { "line": 33, "text": "//" }, { "line": 34, "text": "Worker *Decoder::createWorker() {" }, { "line": 35, "text": " auto worker = new Worker();" }, { "line": 36, "text": " worker->moveToThread(&m_thread);" }, { "line": 37, "text": " connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);" }, { "line": 38, "text": " connect(this, &Decoder::startWorker, worker, &Worker::start);" }, { "line": 39, "text": " connect(this, &Decoder::quitWorker, worker, &Worker::quit);" }, { "line": 40, "text": " connect(worker, &Worker::ready, this, &Decoder::processReady);" } ] } }, { "line": 36, "matches": [ "Worker" ], "snippet": { "start_line": 30, "end_line": 42, "lines": [ { "line": 30, "text": " // NOOP" }, { "line": 31, "text": "}" }, { "line": 32, "text": "" }, { "line": 33, "text": "//" }, { "line": 34, "text": "Worker *Decoder::createWorker() {" }, { "line": 35, "text": " auto worker = new Worker();" }, { "line": 36, "text": " worker->moveToThread(&m_thread);" }, { "line": 37, "text": " connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);" }, { "line": 38, "text": " connect(this, &Decoder::startWorker, worker, &Worker::start);" }, { "line": 39, "text": " connect(this, &Decoder::quitWorker, worker, &Worker::quit);" }, { "line": 40, "text": " connect(worker, &Worker::ready, this, &Decoder::processReady);" }, { "line": 41, "text": " connect(worker, &Worker::error, this, &Decoder::processError);" }, { "line": 42, "text": " connect(worker, &Worker::finished, this, &Decoder::processFinished);" } ] } }, { "line": 41, "matches": [ "decode", "Worker" ], "snippet": { "start_line": 35, "end_line": 47, "lines": [ { "line": 35, "text": " auto worker = new Worker();" }, { "line": 36, "text": " worker->moveToThread(&m_thread);" }, { "line": 37, "text": " connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);" }, { "line": 38, "text": " connect(this, &Decoder::startWorker, worker, &Worker::start);" }, { "line": 39, "text": " connect(this, &Decoder::quitWorker, worker, &Worker::quit);" }, { "line": 40, "text": " connect(worker, &Worker::ready, this, &Decoder::processReady);" }, { "line": 41, "text": " connect(worker, &Worker::error, this, &Decoder::processError);" }, { "line": 42, "text": " connect(worker, &Worker::finished, this, &Decoder::processFinished);" }, { "line": 43, "text": " return worker;" }, { "line": 44, "text": "}" }, { "line": 45, "text": "" }, { "line": 46, "text": "//" }, { "line": 47, "text": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }" } ] } }, { "line": 47, "matches": [ "decode" ], "snippet": { "start_line": 41, "end_line": 53, "lines": [ { "line": 41, "text": " connect(worker, &Worker::error, this, &Decoder::processError);" }, { "line": 42, "text": " connect(worker, &Worker::finished, this, &Decoder::processFinished);" }, { "line": 43, "text": " return worker;" }, { "line": 44, "text": "}" }, { "line": 45, "text": "" }, { "line": 46, "text": "//" }, { "line": 47, "text": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }" }, { "line": 48, "text": "" }, { "line": 49, "text": "//" }, { "line": 50, "text": "void Decoder::quit() { m_thread.quit(); }" }, { "line": 51, "text": "" }, { "line": 52, "text": "//" }, { "line": 53, "text": "bool Decoder::wait() { return m_thread.wait(); }" } ] } }, { "line": 53, "matches": [ "decode" ], "snippet": { "start_line": 47, "end_line": 59, "lines": [ { "line": 47, "text": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }" }, { "line": 48, "text": "" }, { "line": 49, "text": "//" }, { "line": 50, "text": "void Decoder::quit() { m_thread.quit(); }" }, { "line": 51, "text": "" }, { "line": 52, "text": "//" }, { "line": 53, "text": "bool Decoder::wait() { return m_thread.wait(); }" }, { "line": 54, "text": "" }, { "line": 55, "text": "//" }, { "line": 56, "text": "void Decoder::processStart(QString path, QStringList args) {" }, { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" } ] } }, { "line": 56, "matches": [ "decode" ], "snippet": { "start_line": 50, "end_line": 62, "lines": [ { "line": 50, "text": "void Decoder::quit() { m_thread.quit(); }" }, { "line": 51, "text": "" }, { "line": 52, "text": "//" }, { "line": 53, "text": "bool Decoder::wait() { return m_thread.wait(); }" }, { "line": 54, "text": "" }, { "line": 55, "text": "//" }, { "line": 56, "text": "void Decoder::processStart(QString path, QStringList args) {" }, { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" }, { "line": 60, "text": "" }, { "line": 61, "text": " emit startWorker(path, args);" }, { "line": 62, "text": "}" } ] } }, { "line": 61, "matches": [ "Worker" ], "snippet": { "start_line": 55, "end_line": 67, "lines": [ { "line": 55, "text": "//" }, { "line": 56, "text": "void Decoder::processStart(QString path, QStringList args) {" }, { "line": 57, "text": " if (m_worker.isNull()) {" }, { "line": 58, "text": " m_worker = createWorker();" }, { "line": 59, "text": " }" }, { "line": 60, "text": "" }, { "line": 61, "text": " emit startWorker(path, args);" }, { "line": 62, "text": "}" }, { "line": 63, "text": "" }, { "line": 64, "text": "//" }, { "line": 65, "text": "void Decoder::processReady(QByteArray t) { emit ready(t); }" }, { "line": 66, "text": "" }, { "line": 67, "text": "//" } ] } }, { "line": 68, "matches": [ "decode", "Worker" ], "snippet": { "start_line": 62, "end_line": 74, "lines": [ { "line": 62, "text": "}" }, { "line": 63, "text": "" }, { "line": 64, "text": "//" }, { "line": 65, "text": "void Decoder::processReady(QByteArray t) { emit ready(t); }" }, { "line": 66, "text": "" }, { "line": 67, "text": "//" }, { "line": 68, "text": "void Decoder::processQuit() { emit quitWorker(); }" }, { "line": 69, "text": "" }, { "line": 70, "text": "//" }, { "line": 71, "text": "void Decoder::processError(int errorCode, QString errorString) {" }, { "line": 72, "text": " qCDebug(decoder_js8) << \"decoder process error\" << errorCode << errorString;" }, { "line": 73, "text": " emit error(errorCode, errorString);" }, { "line": 74, "text": "}" } ] } }, { "line": 71, "matches": [ "decode" ], "snippet": { "start_line": 65, "end_line": 77, "lines": [ { "line": 65, "text": "void Decoder::processReady(QByteArray t) { emit ready(t); }" }, { "line": 66, "text": "" }, { "line": 67, "text": "//" }, { "line": 68, "text": "void Decoder::processQuit() { emit quitWorker(); }" }, { "line": 69, "text": "" }, { "line": 70, "text": "//" }, { "line": 71, "text": "void Decoder::processError(int errorCode, QString errorString) {" }, { "line": 72, "text": " qCDebug(decoder_js8) << \"decoder process error\" << errorCode << errorString;" }, { "line": 73, "text": " emit error(errorCode, errorString);" }, { "line": 74, "text": "}" }, { "line": 75, "text": "" }, { "line": 76, "text": "//" }, { "line": 77, "text": "void Decoder::processFinished(int exitCode, int statusCode," } ] } }, { "line": 77, "matches": [ "decode" ], "snippet": { "start_line": 71, "end_line": 83, "lines": [ { "line": 71, "text": "void Decoder::processError(int errorCode, QString errorString) {" }, { "line": 72, "text": " qCDebug(decoder_js8) << \"decoder process error\" << errorCode << errorString;" }, { "line": 73, "text": " emit error(errorCode, errorString);" }, { "line": 74, "text": "}" }, { "line": 75, "text": "" }, { "line": 76, "text": "//" }, { "line": 77, "text": "void Decoder::processFinished(int exitCode, int statusCode," }, { "line": 78, "text": " QString errorString) {" }, { "line": 79, "text": " qCDebug(decoder_js8) << \"decoder process finished\" << exitCode << statusCode" }, { "line": 80, "text": " << errorString;" }, { "line": 81, "text": " emit finished(exitCode, statusCode, errorString);" }, { "line": 82, "text": "}" }, { "line": 83, "text": "" } ] } }, { "line": 85, "matches": [ "Worker" ], "snippet": { "start_line": 79, "end_line": 91, "lines": [ { "line": 79, "text": " qCDebug(decoder_js8) << \"decoder process finished\" << exitCode << statusCode" }, { "line": 80, "text": " << errorString;" }, { "line": 81, "text": " emit finished(exitCode, statusCode, errorString);" }, { "line": 82, "text": "}" }, { "line": 83, "text": "" }, { "line": 84, "text": "////////////////////////////////////////" }, { "line": 85, "text": "//////////////// WORKER ////////////////" }, { "line": 86, "text": "////////////////////////////////////////" }, { "line": 87, "text": "" }, { "line": 88, "text": "//" }, { "line": 89, "text": "Worker::~Worker() {}" }, { "line": 90, "text": "" }, { "line": 91, "text": "//" } ] } }, { "line": 89, "matches": [ "Worker" ], "snippet": { "start_line": 83, "end_line": 95, "lines": [ { "line": 83, "text": "" }, { "line": 84, "text": "////////////////////////////////////////" }, { "line": 85, "text": "//////////////// WORKER ////////////////" }, { "line": 86, "text": "////////////////////////////////////////" }, { "line": 87, "text": "" }, { "line": 88, "text": "//" }, { "line": 89, "text": "Worker::~Worker() {}" }, { "line": 90, "text": "" }, { "line": 91, "text": "//" }, { "line": 92, "text": "void Worker::setProcess(QProcess *proc, int msecs) {" }, { "line": 93, "text": " if (!m_proc.isNull()) {" }, { "line": 94, "text": " bool b = m_proc->waitForFinished(msecs);" }, { "line": 95, "text": " if (!b)" } ] } }, { "line": 92, "matches": [ "Worker" ], "snippet": { "start_line": 86, "end_line": 98, "lines": [ { "line": 86, "text": "////////////////////////////////////////" }, { "line": 87, "text": "" }, { "line": 88, "text": "//" }, { "line": 89, "text": "Worker::~Worker() {}" }, { "line": 90, "text": "" }, { "line": 91, "text": "//" }, { "line": 92, "text": "void Worker::setProcess(QProcess *proc, int msecs) {" }, { "line": 93, "text": " if (!m_proc.isNull()) {" }, { "line": 94, "text": " bool b = m_proc->waitForFinished(msecs);" }, { "line": 95, "text": " if (!b)" }, { "line": 96, "text": " m_proc->close();" }, { "line": 97, "text": " m_proc.reset();" }, { "line": 98, "text": " }" } ] } }, { "line": 106, "matches": [ "Worker" ], "snippet": { "start_line": 100, "end_line": 112, "lines": [ { "line": 100, "text": " if (proc) {" }, { "line": 101, "text": " m_proc.reset(proc);" }, { "line": 102, "text": " }" }, { "line": 103, "text": "}" }, { "line": 104, "text": "" }, { "line": 105, "text": "//" }, { "line": 106, "text": "void Worker::start(QString path, QStringList args) {" }, { "line": 107, "text": " qCDebug(decoder_js8) << \"decoder process starting...\";" }, { "line": 108, "text": "" }, { "line": 109, "text": " auto proc = new QProcess(this);" }, { "line": 110, "text": "" }, { "line": 111, "text": " connect(proc, &QProcess::readyReadStandardOutput, [this, proc]() {" }, { "line": 112, "text": " while (proc->canReadLine()) {" } ] } }, { "line": 137, "matches": [ "Worker" ], "snippet": { "start_line": 131, "end_line": 139, "lines": [ { "line": 131, "text": " proc->start(path, args, QIODevice::ReadWrite | QIODevice::Unbuffered);" }, { "line": 132, "text": "" }, { "line": 133, "text": " setProcess(proc);" }, { "line": 134, "text": "}" }, { "line": 135, "text": "" }, { "line": 136, "text": "//" }, { "line": 137, "text": "void Worker::quit() { setProcess(nullptr); }" }, { "line": 138, "text": "" }, { "line": 139, "text": "Q_LOGGING_CATEGORY(decoder_js8, \"decoder.js8\", QtWarningMsg)" } ] } } ] }, { "path": "JS8_Mode/JS8Submode.cpp", "exists": true, "bytes": 13093, "sha256": "10d60fcdd5c908d85b26df1379b0dbc3afd75412aa269b3216196c0bc93aedfd", "line_count": 399, "phase_hits": { "timing_submode": 26, "symbol_to_soft_bits": 41, "bit_order_interleaver": 2, "whitening_erasure": 0, "ldpc_decode": 0, "message91_crc_text": 7 }, "function_blocks": [ { "function": "floor", "line": 25, "signature": "template constexpr int floor(T const v) {", "snippet": { "start_line": 11, "end_line": 39, "lines": [ { "line": 11, "text": "#include " }, { "line": 12, "text": "" }, { "line": 13, "text": "/******************************************************************************/" }, { "line": 14, "text": "// Private Implementation" }, { "line": 15, "text": "/******************************************************************************/" }, { "line": 16, "text": "" }, { "line": 17, "text": "Q_DECLARE_LOGGING_CATEGORY(js8submode_js8)" }, { "line": 18, "text": "" }, { "line": 19, "text": "namespace JS8::Submode {" }, { "line": 20, "text": "namespace {" }, { "line": 21, "text": "// std::floor doesn't become constexpr until C++23; until then, our own" }, { "line": 22, "text": "// implementation. We only use this for computation of the number of" }, { "line": 23, "text": "// frames needed for a submode, so it doesn't need to be complicated." }, { "line": 24, "text": "" }, { "line": 25, "text": "template constexpr int floor(T const v) {" }, { "line": 26, "text": " auto const i = static_cast(v);" }, { "line": 27, "text": " return v < i ? i - 1 : i;" }, { "line": 28, "text": "}" }, { "line": 29, "text": "" }, { "line": 30, "text": "// Ensure that our implementation works as expected." }, { "line": 31, "text": "" }, { "line": 32, "text": "static_assert(floor(0.0) == 0);" }, { "line": 33, "text": "static_assert(floor(0.499999) == 0);" }, { "line": 34, "text": "static_assert(floor(0.5) == 0);" }, { "line": 35, "text": "static_assert(floor(0.999999) == 0);" }, { "line": 36, "text": "static_assert(floor(1.0) == 1);" }, { "line": 37, "text": "static_assert(floor(123.0) == 123);" }, { "line": 38, "text": "static_assert(floor(123.4) == 123);" }, { "line": 39, "text": "static_assert(floor(-0.499999) == -1);" } ] } }, { "function": "samplesForOneSymbol", "line": 79, "signature": "constexpr unsigned int samplesForOneSymbol() const {", "snippet": { "start_line": 65, "end_line": 93, "lines": [ { "line": 65, "text": " m_rxSNRThreshold(rxSNRThreshold), m_rxThreshold(rxThreshold)," }, { "line": 66, "text": " m_samplesForSymbols(JS8_NUM_SYMBOLS * samplesForOneSymbol)," }, { "line": 67, "text": " m_bandwidth(8 * JS8_RX_SAMPLE_RATE / samplesForOneSymbol)," }, { "line": 68, "text": " m_samplesPerPeriod(JS8_RX_SAMPLE_RATE * period)," }, { "line": 69, "text": " m_toneSpacing(JS8_RX_SAMPLE_RATE / (double)samplesForOneSymbol)," }, { "line": 70, "text": " m_samplesNeeded(" }, { "line": 71, "text": " floor(m_samplesForSymbols +" }, { "line": 72, "text": " (0.5 + startDelayMS / 1000.0) * JS8_RX_SAMPLE_RATE))," }, { "line": 73, "text": " m_dataDuration(m_samplesForSymbols / (double)JS8_RX_SAMPLE_RATE)," }, { "line": 74, "text": " m_txDuration(m_dataDuration + startDelayMS / 1000.0) {}" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" } ] } }, { "function": "startDelayMS", "line": 82, "signature": "constexpr unsigned int startDelayMS() const { return m_startDelayMS; }", "snippet": { "start_line": 68, "end_line": 96, "lines": [ { "line": 68, "text": " m_samplesPerPeriod(JS8_RX_SAMPLE_RATE * period)," }, { "line": 69, "text": " m_toneSpacing(JS8_RX_SAMPLE_RATE / (double)samplesForOneSymbol)," }, { "line": 70, "text": " m_samplesNeeded(" }, { "line": 71, "text": " floor(m_samplesForSymbols +" }, { "line": 72, "text": " (0.5 + startDelayMS / 1000.0) * JS8_RX_SAMPLE_RATE))," }, { "line": 73, "text": " m_dataDuration(m_samplesForSymbols / (double)JS8_RX_SAMPLE_RATE)," }, { "line": 74, "text": " m_txDuration(m_dataDuration + startDelayMS / 1000.0) {}" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" } ] } }, { "function": "period", "line": 83, "signature": "constexpr unsigned int period() const { return m_period; }", "snippet": { "start_line": 69, "end_line": 97, "lines": [ { "line": 69, "text": " m_toneSpacing(JS8_RX_SAMPLE_RATE / (double)samplesForOneSymbol)," }, { "line": 70, "text": " m_samplesNeeded(" }, { "line": 71, "text": " floor(m_samplesForSymbols +" }, { "line": 72, "text": " (0.5 + startDelayMS / 1000.0) * JS8_RX_SAMPLE_RATE))," }, { "line": 73, "text": " m_dataDuration(m_samplesForSymbols / (double)JS8_RX_SAMPLE_RATE)," }, { "line": 74, "text": " m_txDuration(m_dataDuration + startDelayMS / 1000.0) {}" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" } ] } }, { "function": "costas", "line": 84, "signature": "constexpr Costas::Type costas() const { return m_costas; }", "snippet": { "start_line": 70, "end_line": 98, "lines": [ { "line": 70, "text": " m_samplesNeeded(" }, { "line": 71, "text": " floor(m_samplesForSymbols +" }, { "line": 72, "text": " (0.5 + startDelayMS / 1000.0) * JS8_RX_SAMPLE_RATE))," }, { "line": 73, "text": " m_dataDuration(m_samplesForSymbols / (double)JS8_RX_SAMPLE_RATE)," }, { "line": 74, "text": " m_txDuration(m_dataDuration + startDelayMS / 1000.0) {}" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" } ] } }, { "function": "rxSNRThreshold", "line": 85, "signature": "constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }", "snippet": { "start_line": 71, "end_line": 99, "lines": [ { "line": 71, "text": " floor(m_samplesForSymbols +" }, { "line": 72, "text": " (0.5 + startDelayMS / 1000.0) * JS8_RX_SAMPLE_RATE))," }, { "line": 73, "text": " m_dataDuration(m_samplesForSymbols / (double)JS8_RX_SAMPLE_RATE)," }, { "line": 74, "text": " m_txDuration(m_dataDuration + startDelayMS / 1000.0) {}" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" }, { "line": 99, "text": " unsigned int m_samplesForOneSymbol;" } ] } }, { "function": "rxThreshold", "line": 86, "signature": "constexpr int rxThreshold() const { return m_rxThreshold; }", "snippet": { "start_line": 72, "end_line": 100, "lines": [ { "line": 72, "text": " (0.5 + startDelayMS / 1000.0) * JS8_RX_SAMPLE_RATE))," }, { "line": 73, "text": " m_dataDuration(m_samplesForSymbols / (double)JS8_RX_SAMPLE_RATE)," }, { "line": 74, "text": " m_txDuration(m_dataDuration + startDelayMS / 1000.0) {}" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" }, { "line": 99, "text": " unsigned int m_samplesForOneSymbol;" }, { "line": 100, "text": " unsigned int m_startDelayMS;" } ] } }, { "function": "samplesForSymbols", "line": 87, "signature": "constexpr int samplesForSymbols() const { return m_samplesForSymbols; }", "snippet": { "start_line": 73, "end_line": 101, "lines": [ { "line": 73, "text": " m_dataDuration(m_samplesForSymbols / (double)JS8_RX_SAMPLE_RATE)," }, { "line": 74, "text": " m_txDuration(m_dataDuration + startDelayMS / 1000.0) {}" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" }, { "line": 99, "text": " unsigned int m_samplesForOneSymbol;" }, { "line": 100, "text": " unsigned int m_startDelayMS;" }, { "line": 101, "text": " unsigned int m_period;" } ] } }, { "function": "bandwidth", "line": 88, "signature": "constexpr int bandwidth() const { return m_bandwidth; }", "snippet": { "start_line": 74, "end_line": 102, "lines": [ { "line": 74, "text": " m_txDuration(m_dataDuration + startDelayMS / 1000.0) {}" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" }, { "line": 99, "text": " unsigned int m_samplesForOneSymbol;" }, { "line": 100, "text": " unsigned int m_startDelayMS;" }, { "line": 101, "text": " unsigned int m_period;" }, { "line": 102, "text": " Costas::Type m_costas;" } ] } }, { "function": "samplesPerPeriod", "line": 89, "signature": "constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }", "snippet": { "start_line": 75, "end_line": 103, "lines": [ { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" }, { "line": 99, "text": " unsigned int m_samplesForOneSymbol;" }, { "line": 100, "text": " unsigned int m_startDelayMS;" }, { "line": 101, "text": " unsigned int m_period;" }, { "line": 102, "text": " Costas::Type m_costas;" }, { "line": 103, "text": " int m_rxSNRThreshold;" } ] } }, { "function": "samplesNeeded", "line": 90, "signature": "constexpr int samplesNeeded() const { return m_samplesNeeded; }", "snippet": { "start_line": 76, "end_line": 104, "lines": [ { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" }, { "line": 99, "text": " unsigned int m_samplesForOneSymbol;" }, { "line": 100, "text": " unsigned int m_startDelayMS;" }, { "line": 101, "text": " unsigned int m_period;" }, { "line": 102, "text": " Costas::Type m_costas;" }, { "line": 103, "text": " int m_rxSNRThreshold;" }, { "line": 104, "text": " int m_rxThreshold;" } ] } }, { "function": "dataDuration", "line": 91, "signature": "constexpr double dataDuration() const { return m_dataDuration; }", "snippet": { "start_line": 77, "end_line": 105, "lines": [ { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" }, { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" }, { "line": 99, "text": " unsigned int m_samplesForOneSymbol;" }, { "line": 100, "text": " unsigned int m_startDelayMS;" }, { "line": 101, "text": " unsigned int m_period;" }, { "line": 102, "text": " Costas::Type m_costas;" }, { "line": 103, "text": " int m_rxSNRThreshold;" }, { "line": 104, "text": " int m_rxThreshold;" }, { "line": 105, "text": " int m_samplesForSymbols;" } ] } } ], "keyword_snippets": [ { "line": 2, "matches": [ "submode" ], "snippet": { "start_line": 1, "end_line": 8, "lines": [ { "line": 1, "text": "/**" }, { "line": 2, "text": " * @file JS8Submode.cpp" }, { "line": 3, "text": " * @brief Implementation of JS8 submode parameter inquiry functions" }, { "line": 4, "text": " */" }, { "line": 5, "text": "#include \"JS8Submode.h\"" }, { "line": 6, "text": "#include \"JS8_Include/commons.h\"" }, { "line": 7, "text": "#include \"JS8_Main/Varicode.h\"" }, { "line": 8, "text": "" } ] } }, { "line": 17, "matches": [ "submode" ], "snippet": { "start_line": 11, "end_line": 23, "lines": [ { "line": 11, "text": "#include " }, { "line": 12, "text": "" }, { "line": 13, "text": "/******************************************************************************/" }, { "line": 14, "text": "// Private Implementation" }, { "line": 15, "text": "/******************************************************************************/" }, { "line": 16, "text": "" }, { "line": 17, "text": "Q_DECLARE_LOGGING_CATEGORY(js8submode_js8)" }, { "line": 18, "text": "" }, { "line": 19, "text": "namespace JS8::Submode {" }, { "line": 20, "text": "namespace {" }, { "line": 21, "text": "// std::floor doesn't become constexpr until C++23; until then, our own" }, { "line": 22, "text": "// implementation. We only use this for computation of the number of" }, { "line": 23, "text": "// frames needed for a submode, so it doesn't need to be complicated." } ] } }, { "line": 23, "matches": [ "submode" ], "snippet": { "start_line": 17, "end_line": 29, "lines": [ { "line": 17, "text": "Q_DECLARE_LOGGING_CATEGORY(js8submode_js8)" }, { "line": 18, "text": "" }, { "line": 19, "text": "namespace JS8::Submode {" }, { "line": 20, "text": "namespace {" }, { "line": 21, "text": "// std::floor doesn't become constexpr until C++23; until then, our own" }, { "line": 22, "text": "// implementation. We only use this for computation of the number of" }, { "line": 23, "text": "// frames needed for a submode, so it doesn't need to be complicated." }, { "line": 24, "text": "" }, { "line": 25, "text": "template constexpr int floor(T const v) {" }, { "line": 26, "text": " auto const i = static_cast(v);" }, { "line": 27, "text": " return v < i ? i - 1 : i;" }, { "line": 28, "text": "}" }, { "line": 29, "text": "" } ] } }, { "line": 46, "matches": [ "submode" ], "snippet": { "start_line": 40, "end_line": 52, "lines": [ { "line": 40, "text": "static_assert(floor(-0.5) == -1);" }, { "line": 41, "text": "static_assert(floor(-0.999999) == -1);" }, { "line": 42, "text": "static_assert(floor(-1.0) == -1);" }, { "line": 43, "text": "static_assert(floor(-123.0) == -123);" }, { "line": 44, "text": "static_assert(floor(-123.4) == -124);" }, { "line": 45, "text": "" }, { "line": 46, "text": "// Data that describes a JS8 submode. Anything here should be able to be" }, { "line": 47, "text": "// completely determined at compile time, i.e., any instance of this is" }, { "line": 48, "text": "// just constant data." }, { "line": 49, "text": "" }, { "line": 50, "text": "class Data {" }, { "line": 51, "text": " public:" }, { "line": 52, "text": " // Constructor; in addition to the basics provided by the constructor" } ] } }, { "line": 59, "matches": [ "samplesForOneSymbol" ], "snippet": { "start_line": 53, "end_line": 65, "lines": [ { "line": 53, "text": " // parameters, we'll determine various convenience constants in order" }, { "line": 54, "text": " // to simplify calling code. These derived values depend only on the" }, { "line": 55, "text": " // JS8_NUM_SYMBOLS and RX_SAMPLE_RATE definitions, and therefore can" }, { "line": 56, "text": " // be entirely computed at compile time." }, { "line": 57, "text": "" }, { "line": 58, "text": " constexpr Data(const char *const name," }, { "line": 59, "text": " unsigned int const samplesForOneSymbol," }, { "line": 60, "text": " unsigned int const startDelayMS, unsigned int const period," }, { "line": 61, "text": " Costas::Type const costas, int const rxSNRThreshold," }, { "line": 62, "text": " int const rxThreshold = 10)" }, { "line": 63, "text": " : m_name(name), m_samplesForOneSymbol(samplesForOneSymbol)," }, { "line": 64, "text": " m_startDelayMS(startDelayMS), m_period(period), m_costas(costas)," }, { "line": 65, "text": " m_rxSNRThreshold(rxSNRThreshold), m_rxThreshold(rxThreshold)," } ] } }, { "line": 63, "matches": [ "samplesForOneSymbol" ], "snippet": { "start_line": 57, "end_line": 69, "lines": [ { "line": 57, "text": "" }, { "line": 58, "text": " constexpr Data(const char *const name," }, { "line": 59, "text": " unsigned int const samplesForOneSymbol," }, { "line": 60, "text": " unsigned int const startDelayMS, unsigned int const period," }, { "line": 61, "text": " Costas::Type const costas, int const rxSNRThreshold," }, { "line": 62, "text": " int const rxThreshold = 10)" }, { "line": 63, "text": " : m_name(name), m_samplesForOneSymbol(samplesForOneSymbol)," }, { "line": 64, "text": " m_startDelayMS(startDelayMS), m_period(period), m_costas(costas)," }, { "line": 65, "text": " m_rxSNRThreshold(rxSNRThreshold), m_rxThreshold(rxThreshold)," }, { "line": 66, "text": " m_samplesForSymbols(JS8_NUM_SYMBOLS * samplesForOneSymbol)," }, { "line": 67, "text": " m_bandwidth(8 * JS8_RX_SAMPLE_RATE / samplesForOneSymbol)," }, { "line": 68, "text": " m_samplesPerPeriod(JS8_RX_SAMPLE_RATE * period)," }, { "line": 69, "text": " m_toneSpacing(JS8_RX_SAMPLE_RATE / (double)samplesForOneSymbol)," } ] } }, { "line": 66, "matches": [ "samplesForOneSymbol" ], "snippet": { "start_line": 60, "end_line": 72, "lines": [ { "line": 60, "text": " unsigned int const startDelayMS, unsigned int const period," }, { "line": 61, "text": " Costas::Type const costas, int const rxSNRThreshold," }, { "line": 62, "text": " int const rxThreshold = 10)" }, { "line": 63, "text": " : m_name(name), m_samplesForOneSymbol(samplesForOneSymbol)," }, { "line": 64, "text": " m_startDelayMS(startDelayMS), m_period(period), m_costas(costas)," }, { "line": 65, "text": " m_rxSNRThreshold(rxSNRThreshold), m_rxThreshold(rxThreshold)," }, { "line": 66, "text": " m_samplesForSymbols(JS8_NUM_SYMBOLS * samplesForOneSymbol)," }, { "line": 67, "text": " m_bandwidth(8 * JS8_RX_SAMPLE_RATE / samplesForOneSymbol)," }, { "line": 68, "text": " m_samplesPerPeriod(JS8_RX_SAMPLE_RATE * period)," }, { "line": 69, "text": " m_toneSpacing(JS8_RX_SAMPLE_RATE / (double)samplesForOneSymbol)," }, { "line": 70, "text": " m_samplesNeeded(" }, { "line": 71, "text": " floor(m_samplesForSymbols +" }, { "line": 72, "text": " (0.5 + startDelayMS / 1000.0) * JS8_RX_SAMPLE_RATE))," } ] } }, { "line": 79, "matches": [ "samplesForOneSymbol" ], "snippet": { "start_line": 73, "end_line": 85, "lines": [ { "line": 73, "text": " m_dataDuration(m_samplesForSymbols / (double)JS8_RX_SAMPLE_RATE)," }, { "line": 74, "text": " m_txDuration(m_dataDuration + startDelayMS / 1000.0) {}" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Inline accessors" }, { "line": 77, "text": "" }, { "line": 78, "text": " constexpr const char *name() const { return m_name; }" }, { "line": 79, "text": " constexpr unsigned int samplesForOneSymbol() const {" }, { "line": 80, "text": " return m_samplesForOneSymbol;" }, { "line": 81, "text": " }" }, { "line": 82, "text": " constexpr unsigned int startDelayMS() const { return m_startDelayMS; }" }, { "line": 83, "text": " constexpr unsigned int period() const { return m_period; }" }, { "line": 84, "text": " constexpr Costas::Type costas() const { return m_costas; }" }, { "line": 85, "text": " constexpr int rxSNRThreshold() const { return m_rxSNRThreshold; }" } ] } }, { "line": 92, "matches": [ "toneSpacing" ], "snippet": { "start_line": 86, "end_line": 98, "lines": [ { "line": 86, "text": " constexpr int rxThreshold() const { return m_rxThreshold; }" }, { "line": 87, "text": " constexpr int samplesForSymbols() const { return m_samplesForSymbols; }" }, { "line": 88, "text": " constexpr int bandwidth() const { return m_bandwidth; }" }, { "line": 89, "text": " constexpr int samplesPerPeriod() const { return m_samplesPerPeriod; }" }, { "line": 90, "text": " constexpr int samplesNeeded() const { return m_samplesNeeded; }" }, { "line": 91, "text": " constexpr double dataDuration() const { return m_dataDuration; }" }, { "line": 92, "text": " constexpr double toneSpacing() const { return m_toneSpacing; }" }, { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" } ] } }, { "line": 99, "matches": [ "samplesForOneSymbol" ], "snippet": { "start_line": 93, "end_line": 105, "lines": [ { "line": 93, "text": " constexpr double txDuration() const { return m_txDuration; }" }, { "line": 94, "text": "" }, { "line": 95, "text": " private:" }, { "line": 96, "text": " // Data members ** ORDER DEPENDENCY **" }, { "line": 97, "text": "" }, { "line": 98, "text": " const char *m_name;" }, { "line": 99, "text": " unsigned int m_samplesForOneSymbol;" }, { "line": 100, "text": " unsigned int m_startDelayMS;" }, { "line": 101, "text": " unsigned int m_period;" }, { "line": 102, "text": " Costas::Type m_costas;" }, { "line": 103, "text": " int m_rxSNRThreshold;" }, { "line": 104, "text": " int m_rxThreshold;" }, { "line": 105, "text": " int m_samplesForSymbols;" } ] } }, { "line": 108, "matches": [ "toneSpacing" ], "snippet": { "start_line": 102, "end_line": 114, "lines": [ { "line": 102, "text": " Costas::Type m_costas;" }, { "line": 103, "text": " int m_rxSNRThreshold;" }, { "line": 104, "text": " int m_rxThreshold;" }, { "line": 105, "text": " int m_samplesForSymbols;" }, { "line": 106, "text": " int m_bandwidth;" }, { "line": 107, "text": " int m_samplesPerPeriod;" }, { "line": 108, "text": " double m_toneSpacing;" }, { "line": 109, "text": " int m_samplesNeeded;" }, { "line": 110, "text": " double m_dataDuration;" }, { "line": 111, "text": " double m_txDuration;" }, { "line": 112, "text": "};" }, { "line": 113, "text": "" }, { "line": 114, "text": "// Data for known submodes. Normal mode uses the old Costas Array" } ] } }, { "line": 114, "matches": [ "submode" ], "snippet": { "start_line": 108, "end_line": 120, "lines": [ { "line": 108, "text": " double m_toneSpacing;" }, { "line": 109, "text": " int m_samplesNeeded;" }, { "line": 110, "text": " double m_dataDuration;" }, { "line": 111, "text": " double m_txDuration;" }, { "line": 112, "text": "};" }, { "line": 113, "text": "" }, { "line": 114, "text": "// Data for known submodes. Normal mode uses the old Costas Array" }, { "line": 115, "text": "// definition; all other modes use the new one." }, { "line": 116, "text": "" }, { "line": 117, "text": "constexpr Data Normal = {\"NORMAL\"," }, { "line": 118, "text": " JS8A_SYMBOL_SAMPLES," }, { "line": 119, "text": " JS8A_START_DELAY_MS," }, { "line": 120, "text": " JS8A_TX_SECONDS," } ] } }, { "line": 155, "matches": [ "submode" ], "snippet": { "start_line": 149, "end_line": 161, "lines": [ { "line": 149, "text": " JS8I_START_DELAY_MS," }, { "line": 150, "text": " JS8I_TX_SECONDS," }, { "line": 151, "text": " Costas::Type::MODIFIED," }, { "line": 152, "text": " -18," }, { "line": 153, "text": " 50};" }, { "line": 154, "text": "" }, { "line": 155, "text": "// Given a submode, return data for it, or, if we don't have any idea" }, { "line": 156, "text": "// what the caller is talking about, throw." }, { "line": 157, "text": "//" }, { "line": 158, "text": "// Note that the original code in all cases did its best to just carry" }, { "line": 159, "text": "// on in the event of an invalid submode, e.g., by returning 0, etc.," }, { "line": 160, "text": "// but that approach will in general lead to things like division by" }, { "line": 161, "text": "// zero in computeCycleForDecode(), below, so either way we're going" } ] } }, { "line": 159, "matches": [ "submode" ], "snippet": { "start_line": 153, "end_line": 165, "lines": [ { "line": 153, "text": " 50};" }, { "line": 154, "text": "" }, { "line": 155, "text": "// Given a submode, return data for it, or, if we don't have any idea" }, { "line": 156, "text": "// what the caller is talking about, throw." }, { "line": 157, "text": "//" }, { "line": 158, "text": "// Note that the original code in all cases did its best to just carry" }, { "line": 159, "text": "// on in the event of an invalid submode, e.g., by returning 0, etc.," }, { "line": 160, "text": "// but that approach will in general lead to things like division by" }, { "line": 161, "text": "// zero in computeCycleForDecode(), below, so either way we're going" }, { "line": 162, "text": "// to end up with a runtime error, and it seems preferable that it's" }, { "line": 163, "text": "// an informative one." }, { "line": 164, "text": "//" }, { "line": 165, "text": "// Note that the Varicode::SubModeType enum is not dense, so we can't" } ] } }, { "line": 165, "matches": [ "submode" ], "snippet": { "start_line": 159, "end_line": 171, "lines": [ { "line": 159, "text": "// on in the event of an invalid submode, e.g., by returning 0, etc.," }, { "line": 160, "text": "// but that approach will in general lead to things like division by" }, { "line": 161, "text": "// zero in computeCycleForDecode(), below, so either way we're going" }, { "line": 162, "text": "// to end up with a runtime error, and it seems preferable that it's" }, { "line": 163, "text": "// an informative one." }, { "line": 164, "text": "//" }, { "line": 165, "text": "// Note that the Varicode::SubModeType enum is not dense, so we can't" }, { "line": 166, "text": "// just do direct indexed access here." }, { "line": 167, "text": "" }, { "line": 168, "text": "constexpr Data const &data(int const submode) {" }, { "line": 169, "text": " switch (submode) {" }, { "line": 170, "text": " case Varicode::JS8CallNormal:" }, { "line": 171, "text": " return Normal;" } ] } }, { "line": 168, "matches": [ "submode" ], "snippet": { "start_line": 162, "end_line": 174, "lines": [ { "line": 162, "text": "// to end up with a runtime error, and it seems preferable that it's" }, { "line": 163, "text": "// an informative one." }, { "line": 164, "text": "//" }, { "line": 165, "text": "// Note that the Varicode::SubModeType enum is not dense, so we can't" }, { "line": 166, "text": "// just do direct indexed access here." }, { "line": 167, "text": "" }, { "line": 168, "text": "constexpr Data const &data(int const submode) {" }, { "line": 169, "text": " switch (submode) {" }, { "line": 170, "text": " case Varicode::JS8CallNormal:" }, { "line": 171, "text": " return Normal;" }, { "line": 172, "text": " case Varicode::JS8CallFast:" }, { "line": 173, "text": " return Fast;" }, { "line": 174, "text": " case Varicode::JS8CallTurbo:" } ] } }, { "line": 181, "matches": [ "submode" ], "snippet": { "start_line": 175, "end_line": 187, "lines": [ { "line": 175, "text": " return Turbo;" }, { "line": 176, "text": " case Varicode::JS8CallSlow:" }, { "line": 177, "text": " return Slow;" }, { "line": 178, "text": " case Varicode::JS8CallUltra:" }, { "line": 179, "text": " return Ultra;" }, { "line": 180, "text": " default: {" }, { "line": 181, "text": " throw error{QObject::tr(\"Invalid JS8 submode %1\").arg(submode)};" }, { "line": 182, "text": " }" }, { "line": 183, "text": " }" }, { "line": 184, "text": "};" }, { "line": 185, "text": "" }, { "line": 186, "text": "class ListDataAsDebugOutput {" }, { "line": 187, "text": " private:" } ] } }, { "line": 189, "matches": [ "submode" ], "snippet": { "start_line": 183, "end_line": 195, "lines": [ { "line": 183, "text": " }" }, { "line": 184, "text": "};" }, { "line": 185, "text": "" }, { "line": 186, "text": "class ListDataAsDebugOutput {" }, { "line": 187, "text": " private:" }, { "line": 188, "text": " inline void list_one_mode(Data data) {" }, { "line": 189, "text": " qCDebug(js8submode_js8)" }, { "line": 190, "text": " << \"\\nname \" << data.name() << \"\\nsamplesForOneSymbol\"" }, { "line": 191, "text": " << data.samplesForOneSymbol() << \"\\nstartDelayMS \"" }, { "line": 192, "text": " << data.startDelayMS() << \"\\nperiod \" << data.period()" }, { "line": 193, "text": " << \"\\ncostas \"" }, { "line": 194, "text": " << (data.costas() == Costas::Type::MODIFIED" }, { "line": 195, "text": " ? \"MODIFIED\"" } ] } }, { "line": 191, "matches": [ "samplesForOneSymbol" ], "snippet": { "start_line": 185, "end_line": 197, "lines": [ { "line": 185, "text": "" }, { "line": 186, "text": "class ListDataAsDebugOutput {" }, { "line": 187, "text": " private:" }, { "line": 188, "text": " inline void list_one_mode(Data data) {" }, { "line": 189, "text": " qCDebug(js8submode_js8)" }, { "line": 190, "text": " << \"\\nname \" << data.name() << \"\\nsamplesForOneSymbol\"" }, { "line": 191, "text": " << data.samplesForOneSymbol() << \"\\nstartDelayMS \"" }, { "line": 192, "text": " << data.startDelayMS() << \"\\nperiod \" << data.period()" }, { "line": 193, "text": " << \"\\ncostas \"" }, { "line": 194, "text": " << (data.costas() == Costas::Type::MODIFIED" }, { "line": 195, "text": " ? \"MODIFIED\"" }, { "line": 196, "text": " : (data.costas() == Costas::Type::ORIGINAL ? \"ORIGINAL\"" }, { "line": 197, "text": " : \"????\"))" } ] } }, { "line": 205, "matches": [ "toneSpacing" ], "snippet": { "start_line": 199, "end_line": 211, "lines": [ { "line": 199, "text": " << \"\\nrxThreshold \" << data.rxThreshold()" }, { "line": 200, "text": " << \"\\nsamplesForSymbols \" << data.samplesForSymbols()" }, { "line": 201, "text": " << \"\\nbandwidth \" << data.bandwidth()" }, { "line": 202, "text": " << \"\\nsamplesPerPeriod \" << data.samplesPerPeriod()" }, { "line": 203, "text": " << \"\\nsamplesNeeded \" << data.samplesNeeded()" }, { "line": 204, "text": " << \"\\ndataDuration \" << data.dataDuration()" }, { "line": 205, "text": " << \"\\ntoneSpacing \" << data.toneSpacing()" }, { "line": 206, "text": " << \"\\ntxDuration \" << data.txDuration() << \"\\n\";" }, { "line": 207, "text": " }" }, { "line": 208, "text": "" }, { "line": 209, "text": " public:" }, { "line": 210, "text": " inline ListDataAsDebugOutput() {" }, { "line": 211, "text": " list_one_mode(Slow);" } ] } }, { "line": 222, "matches": [ "submode" ], "snippet": { "start_line": 216, "end_line": 228, "lines": [ { "line": 216, "text": " }" }, { "line": 217, "text": "};" }, { "line": 218, "text": "" }, { "line": 219, "text": "static ListDataAsDebugOutput list_data_as_debug_output =" }, { "line": 220, "text": " ListDataAsDebugOutput{};" }, { "line": 221, "text": "} // namespace" }, { "line": 222, "text": "} // namespace JS8::Submode" }, { "line": 223, "text": "" }, { "line": 224, "text": "/******************************************************************************/" }, { "line": 225, "text": "// Public Implementation" }, { "line": 226, "text": "/******************************************************************************/" }, { "line": 227, "text": "/**" }, { "line": 228, "text": " * @brief JS8 Submode namespace implementation" } ] } }, { "line": 228, "matches": [ "submode" ], "snippet": { "start_line": 222, "end_line": 234, "lines": [ { "line": 222, "text": "} // namespace JS8::Submode" }, { "line": 223, "text": "" }, { "line": 224, "text": "/******************************************************************************/" }, { "line": 225, "text": "// Public Implementation" }, { "line": 226, "text": "/******************************************************************************/" }, { "line": 227, "text": "/**" }, { "line": 228, "text": " * @brief JS8 Submode namespace implementation" }, { "line": 229, "text": " */" }, { "line": 230, "text": "namespace JS8::Submode {" }, { "line": 231, "text": "// Submode name inquiry function; return a translated value, if there is" }, { "line": 232, "text": "// a translated value, otherwise, the untranslated mode name." }, { "line": 233, "text": "" }, { "line": 234, "text": "/**" } ] } } ] }, { "path": "JS8_Mode/soft_combiner.h", "exists": true, "bytes": 9185, "sha256": "59a2c7dafab922a1aa93d7de7c57a50fa63d6fd900507c63233390de073218ea", "line_count": 294, "phase_hits": { "timing_submode": 0, "symbol_to_soft_bits": 109, "bit_order_interleaver": 5, "whitening_erasure": 4, "ldpc_decode": 0, "message91_crc_text": 0 }, "function_blocks": [ { "function": "SoftCombiner", "line": 55, "signature": "explicit SoftCombiner(bool enabled, bool runSelfTest = true)", "snippet": { "start_line": 41, "end_line": 69, "lines": [ { "line": 41, "text": " dtBin == other.dtBin && signature == other.signature;" }, { "line": 42, "text": " }" }, { "line": 43, "text": " };" }, { "line": 44, "text": "" }, { "line": 45, "text": " struct Combined {" }, { "line": 46, "text": " Key key;" }, { "line": 47, "text": " std::array llr0;" }, { "line": 48, "text": " std::array llr1;" }, { "line": 49, "text": " int repeats;" }, { "line": 50, "text": " bool combined;" }, { "line": 51, "text": " };" }, { "line": 52, "text": "" }, { "line": 53, "text": " SoftCombiner() : SoftCombiner(defaultEnabled(), true) {}" }, { "line": 54, "text": "" }, { "line": 55, "text": " explicit SoftCombiner(bool enabled, bool runSelfTest = true)" }, { "line": 56, "text": " : m_enabled(enabled) {" }, { "line": 57, "text": " if (!m_enabled) {" }, { "line": 58, "text": " qCDebug(decoder_js8)" }, { "line": 59, "text": " << \"soft-combining disabled (JS8_SOFT_COMBINING=0)\";" }, { "line": 60, "text": " }" }, { "line": 61, "text": " if (runSelfTest)" }, { "line": 62, "text": " maybeRunSelfTest();" }, { "line": 63, "text": " }" }, { "line": 64, "text": "" }, { "line": 65, "text": " Key makeKey(int mode, float f1, float dt, std::array const &llr0," }, { "line": 66, "text": " std::array const &llr1) const {" }, { "line": 67, "text": " return Key{mode, static_cast(std::lround(f1))," }, { "line": 68, "text": " static_cast(std::lround(dt * 10.0f)), // 100 ms bins" }, { "line": 69, "text": " signature(llr0, llr1)};" } ] } }, { "function": "markDecoded", "line": 104, "signature": "void markDecoded(Key const &key) {", "snippet": { "start_line": 90, "end_line": 118, "lines": [ { "line": 90, "text": " it->llr0[i] += llr0[i];" }, { "line": 91, "text": " it->llr1[i] += llr1[i];" }, { "line": 92, "text": " }" }, { "line": 93, "text": "" }, { "line": 94, "text": " ++it->repeats;" }, { "line": 95, "text": " it->lastSeen = Clock::now();" }, { "line": 96, "text": "" }, { "line": 97, "text": " qCDebug(decoder_js8)" }, { "line": 98, "text": " << \"soft-combining repeats\" << it->repeats << \"mode\" << key.mode" }, { "line": 99, "text": " << \"freq\" << key.freqBin << \"dtbin\" << key.dtBin;" }, { "line": 100, "text": "" }, { "line": 101, "text": " return Combined{key, it->llr0, it->llr1, it->repeats, true};" }, { "line": 102, "text": " }" }, { "line": 103, "text": "" }, { "line": 104, "text": " void markDecoded(Key const &key) {" }, { "line": 105, "text": " if (!m_enabled)" }, { "line": 106, "text": " return;" }, { "line": 107, "text": "" }, { "line": 108, "text": " auto lookup = keyForLookup(key);" }, { "line": 109, "text": " auto it = m_entries.find(lookup);" }, { "line": 110, "text": "" }, { "line": 111, "text": " if (it == m_entries.end())" }, { "line": 112, "text": " return;" }, { "line": 113, "text": "" }, { "line": 114, "text": " auto &bucket = it->second;" }, { "line": 115, "text": " bucket.erase(std::remove_if(bucket.begin(), bucket.end()," }, { "line": 116, "text": " [&key](Entry const &entry) {" }, { "line": 117, "text": " return entry.signature == key.signature;" }, { "line": 118, "text": " })," } ] } }, { "function": "flush", "line": 125, "signature": "void flush(std::chrono::seconds ttl) {", "snippet": { "start_line": 111, "end_line": 139, "lines": [ { "line": 111, "text": " if (it == m_entries.end())" }, { "line": 112, "text": " return;" }, { "line": 113, "text": "" }, { "line": 114, "text": " auto &bucket = it->second;" }, { "line": 115, "text": " bucket.erase(std::remove_if(bucket.begin(), bucket.end()," }, { "line": 116, "text": " [&key](Entry const &entry) {" }, { "line": 117, "text": " return entry.signature == key.signature;" }, { "line": 118, "text": " })," }, { "line": 119, "text": " bucket.end());" }, { "line": 120, "text": "" }, { "line": 121, "text": " if (bucket.empty())" }, { "line": 122, "text": " m_entries.erase(it);" }, { "line": 123, "text": " }" }, { "line": 124, "text": "" }, { "line": 125, "text": " void flush(std::chrono::seconds ttl) {" }, { "line": 126, "text": " if (!m_enabled)" }, { "line": 127, "text": " return;" }, { "line": 128, "text": "" }, { "line": 129, "text": " auto const now = Clock::now();" }, { "line": 130, "text": "" }, { "line": 131, "text": " for (auto it = m_entries.begin(); it != m_entries.end();) {" }, { "line": 132, "text": " auto &bucket = it->second;" }, { "line": 133, "text": "" }, { "line": 134, "text": " bucket.erase(std::remove_if(bucket.begin(), bucket.end()," }, { "line": 135, "text": " [now, ttl](Entry const &entry) {" }, { "line": 136, "text": " return now - entry.lastSeen > ttl;" }, { "line": 137, "text": " })," }, { "line": 138, "text": " bucket.end());" }, { "line": 139, "text": "" } ] } }, { "function": "signatureIndices", "line": 178, "signature": "static constexpr auto signatureIndices() {", "snippet": { "start_line": 164, "end_line": 192, "lines": [ { "line": 164, "text": " return h1 ^ (h2 << 1) ^ (h3 << 2);" }, { "line": 165, "text": " }" }, { "line": 166, "text": " };" }, { "line": 167, "text": "" }, { "line": 168, "text": " struct Entry {" }, { "line": 169, "text": " uint32_t signature;" }, { "line": 170, "text": " std::array llr0;" }, { "line": 171, "text": " std::array llr1;" }, { "line": 172, "text": " int repeats;" }, { "line": 173, "text": " Clock::time_point lastSeen;" }, { "line": 174, "text": " };" }, { "line": 175, "text": "" }, { "line": 176, "text": " using Bucket = std::vector;" }, { "line": 177, "text": "" }, { "line": 178, "text": " static constexpr auto signatureIndices() {" }, { "line": 179, "text": " std::array indices{};" }, { "line": 180, "text": " int value = 0;" }, { "line": 181, "text": " for (std::size_t i = 0; i < indices.size(); ++i) {" }, { "line": 182, "text": " value = (value + 37) % static_cast(N);" }, { "line": 183, "text": " indices[i] = value;" }, { "line": 184, "text": " }" }, { "line": 185, "text": " return indices;" }, { "line": 186, "text": " }" }, { "line": 187, "text": "" }, { "line": 188, "text": " static typename Bucket::iterator findEntry(Bucket &bucket, uint32_t signature) {" }, { "line": 189, "text": " constexpr int MAX_HAMMING =" }, { "line": 190, "text": " 4; // allow small differences between noisy repeats" }, { "line": 191, "text": "" }, { "line": 192, "text": " return std::find_if(" } ] } }, { "function": "findEntry", "line": 188, "signature": "static typename Bucket::iterator findEntry(Bucket &bucket, uint32_t signature) {", "snippet": { "start_line": 174, "end_line": 202, "lines": [ { "line": 174, "text": " };" }, { "line": 175, "text": "" }, { "line": 176, "text": " using Bucket = std::vector;" }, { "line": 177, "text": "" }, { "line": 178, "text": " static constexpr auto signatureIndices() {" }, { "line": 179, "text": " std::array indices{};" }, { "line": 180, "text": " int value = 0;" }, { "line": 181, "text": " for (std::size_t i = 0; i < indices.size(); ++i) {" }, { "line": 182, "text": " value = (value + 37) % static_cast(N);" }, { "line": 183, "text": " indices[i] = value;" }, { "line": 184, "text": " }" }, { "line": 185, "text": " return indices;" }, { "line": 186, "text": " }" }, { "line": 187, "text": "" }, { "line": 188, "text": " static typename Bucket::iterator findEntry(Bucket &bucket, uint32_t signature) {" }, { "line": 189, "text": " constexpr int MAX_HAMMING =" }, { "line": 190, "text": " 4; // allow small differences between noisy repeats" }, { "line": 191, "text": "" }, { "line": 192, "text": " return std::find_if(" }, { "line": 193, "text": " bucket.begin(), bucket.end(), [signature](Entry const &entry) {" }, { "line": 194, "text": " return hamming(signature, entry.signature) <= MAX_HAMMING;" }, { "line": 195, "text": " });" }, { "line": 196, "text": " }" }, { "line": 197, "text": "" }, { "line": 198, "text": " static bool defaultEnabled() {" }, { "line": 199, "text": " bool ok = false;" }, { "line": 200, "text": " int value = qEnvironmentVariableIntValue(\"JS8_SOFT_COMBINING\", &ok);" }, { "line": 201, "text": " return ok ? value != 0 : true;" }, { "line": 202, "text": " }" } ] } }, { "function": "defaultEnabled", "line": 198, "signature": "static bool defaultEnabled() {", "snippet": { "start_line": 184, "end_line": 212, "lines": [ { "line": 184, "text": " }" }, { "line": 185, "text": " return indices;" }, { "line": 186, "text": " }" }, { "line": 187, "text": "" }, { "line": 188, "text": " static typename Bucket::iterator findEntry(Bucket &bucket, uint32_t signature) {" }, { "line": 189, "text": " constexpr int MAX_HAMMING =" }, { "line": 190, "text": " 4; // allow small differences between noisy repeats" }, { "line": 191, "text": "" }, { "line": 192, "text": " return std::find_if(" }, { "line": 193, "text": " bucket.begin(), bucket.end(), [signature](Entry const &entry) {" }, { "line": 194, "text": " return hamming(signature, entry.signature) <= MAX_HAMMING;" }, { "line": 195, "text": " });" }, { "line": 196, "text": " }" }, { "line": 197, "text": "" }, { "line": 198, "text": " static bool defaultEnabled() {" }, { "line": 199, "text": " bool ok = false;" }, { "line": 200, "text": " int value = qEnvironmentVariableIntValue(\"JS8_SOFT_COMBINING\", &ok);" }, { "line": 201, "text": " return ok ? value != 0 : true;" }, { "line": 202, "text": " }" }, { "line": 203, "text": "" }, { "line": 204, "text": " static uint32_t signature(std::array const &llr0," }, { "line": 205, "text": " std::array const &llr1) {" }, { "line": 206, "text": " static constexpr auto INDICES = signatureIndices();" }, { "line": 207, "text": "" }, { "line": 208, "text": " uint32_t sig = 0;" }, { "line": 209, "text": " for (std::size_t i = 0; i < INDICES.size(); ++i) {" }, { "line": 210, "text": " auto const idx = INDICES[i];" }, { "line": 211, "text": " float const v = 0.5f * (llr0[idx] + llr1[idx]);" }, { "line": 212, "text": " if (v >= 0.0f)" } ] } }, { "function": "hamming", "line": 218, "signature": "static int hamming(uint32_t a, uint32_t b) {", "snippet": { "start_line": 204, "end_line": 232, "lines": [ { "line": 204, "text": " static uint32_t signature(std::array const &llr0," }, { "line": 205, "text": " std::array const &llr1) {" }, { "line": 206, "text": " static constexpr auto INDICES = signatureIndices();" }, { "line": 207, "text": "" }, { "line": 208, "text": " uint32_t sig = 0;" }, { "line": 209, "text": " for (std::size_t i = 0; i < INDICES.size(); ++i) {" }, { "line": 210, "text": " auto const idx = INDICES[i];" }, { "line": 211, "text": " float const v = 0.5f * (llr0[idx] + llr1[idx]);" }, { "line": 212, "text": " if (v >= 0.0f)" }, { "line": 213, "text": " sig |= (1u << i);" }, { "line": 214, "text": " }" }, { "line": 215, "text": " return sig;" }, { "line": 216, "text": " }" }, { "line": 217, "text": "" }, { "line": 218, "text": " static int hamming(uint32_t a, uint32_t b) {" }, { "line": 219, "text": " uint32_t v = a ^ b;" }, { "line": 220, "text": " int c = 0;" }, { "line": 221, "text": " while (v) {" }, { "line": 222, "text": " v &= (v - 1);" }, { "line": 223, "text": " ++c;" }, { "line": 224, "text": " }" }, { "line": 225, "text": " return c;" }, { "line": 226, "text": " }" }, { "line": 227, "text": "" }, { "line": 228, "text": " static void maybeRunSelfTest() {" }, { "line": 229, "text": " static std::once_flag once;" }, { "line": 230, "text": " std::call_once(once, []() {" }, { "line": 231, "text": " if (!qEnvironmentVariableIsSet(\"JS8_SOFT_COMBINING_TEST\"))" }, { "line": 232, "text": " return;" } ] } }, { "function": "maybeRunSelfTest", "line": 228, "signature": "static void maybeRunSelfTest() {", "snippet": { "start_line": 214, "end_line": 242, "lines": [ { "line": 214, "text": " }" }, { "line": 215, "text": " return sig;" }, { "line": 216, "text": " }" }, { "line": 217, "text": "" }, { "line": 218, "text": " static int hamming(uint32_t a, uint32_t b) {" }, { "line": 219, "text": " uint32_t v = a ^ b;" }, { "line": 220, "text": " int c = 0;" }, { "line": 221, "text": " while (v) {" }, { "line": 222, "text": " v &= (v - 1);" }, { "line": 223, "text": " ++c;" }, { "line": 224, "text": " }" }, { "line": 225, "text": " return c;" }, { "line": 226, "text": " }" }, { "line": 227, "text": "" }, { "line": 228, "text": " static void maybeRunSelfTest() {" }, { "line": 229, "text": " static std::once_flag once;" }, { "line": 230, "text": " std::call_once(once, []() {" }, { "line": 231, "text": " if (!qEnvironmentVariableIsSet(\"JS8_SOFT_COMBINING_TEST\"))" }, { "line": 232, "text": " return;" }, { "line": 233, "text": "" }, { "line": 234, "text": " SoftCombiner combiner(true, false);" }, { "line": 235, "text": "" }, { "line": 236, "text": " std::array baseline{};" }, { "line": 237, "text": " for (std::size_t i = 0; i < baseline.size(); ++i) {" }, { "line": 238, "text": " baseline[i] = (i % 2 == 0) ? 2.0f : -2.0f;" }, { "line": 239, "text": " }" }, { "line": 240, "text": "" }, { "line": 241, "text": " auto noisy = [](std::array base, int flipStride) {" }, { "line": 242, "text": " for (std::size_t i = 0; i < base.size(); ++i) {" } ] } } ], "keyword_snippets": [ { "line": 22, "matches": [ "LLR", "llr", "candidate" ], "snippet": { "start_line": 16, "end_line": 28, "lines": [ { "line": 16, "text": "#include " }, { "line": 17, "text": "" }, { "line": 18, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);" }, { "line": 19, "text": "" }, { "line": 20, "text": "namespace js8 {" }, { "line": 21, "text": "/**" }, { "line": 22, "text": " * @brief Cache and combine repeated LLR frames for the same decode candidate." }, { "line": 23, "text": " *" }, { "line": 24, "text": " * Uses a coarse freq/dt bin and a small LLR signature as the key; repeated" }, { "line": 25, "text": " * receptions accumulate LLRs to improve decode probability without changing" }, { "line": 26, "text": " * over-the-air behavior. Templated on the LLR length so the caller binds it" }, { "line": 27, "text": " * to the decoder's bit count." }, { "line": 28, "text": " */" } ] } }, { "line": 26, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 20, "end_line": 32, "lines": [ { "line": 20, "text": "namespace js8 {" }, { "line": 21, "text": "/**" }, { "line": 22, "text": " * @brief Cache and combine repeated LLR frames for the same decode candidate." }, { "line": 23, "text": " *" }, { "line": 24, "text": " * Uses a coarse freq/dt bin and a small LLR signature as the key; repeated" }, { "line": 25, "text": " * receptions accumulate LLRs to improve decode probability without changing" }, { "line": 26, "text": " * over-the-air behavior. Templated on the LLR length so the caller binds it" }, { "line": 27, "text": " * to the decoder's bit count." }, { "line": 28, "text": " */" }, { "line": 29, "text": "template class SoftCombiner {" }, { "line": 30, "text": " using Clock = std::chrono::steady_clock;" }, { "line": 31, "text": "" }, { "line": 32, "text": " public:" } ] } }, { "line": 47, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 41, "end_line": 53, "lines": [ { "line": 41, "text": " dtBin == other.dtBin && signature == other.signature;" }, { "line": 42, "text": " }" }, { "line": 43, "text": " };" }, { "line": 44, "text": "" }, { "line": 45, "text": " struct Combined {" }, { "line": 46, "text": " Key key;" }, { "line": 47, "text": " std::array llr0;" }, { "line": 48, "text": " std::array llr1;" }, { "line": 49, "text": " int repeats;" }, { "line": 50, "text": " bool combined;" }, { "line": 51, "text": " };" }, { "line": 52, "text": "" }, { "line": 53, "text": " SoftCombiner() : SoftCombiner(defaultEnabled(), true) {}" } ] } }, { "line": 53, "matches": [ "soft" ], "snippet": { "start_line": 47, "end_line": 59, "lines": [ { "line": 47, "text": " std::array llr0;" }, { "line": 48, "text": " std::array llr1;" }, { "line": 49, "text": " int repeats;" }, { "line": 50, "text": " bool combined;" }, { "line": 51, "text": " };" }, { "line": 52, "text": "" }, { "line": 53, "text": " SoftCombiner() : SoftCombiner(defaultEnabled(), true) {}" }, { "line": 54, "text": "" }, { "line": 55, "text": " explicit SoftCombiner(bool enabled, bool runSelfTest = true)" }, { "line": 56, "text": " : m_enabled(enabled) {" }, { "line": 57, "text": " if (!m_enabled) {" }, { "line": 58, "text": " qCDebug(decoder_js8)" }, { "line": 59, "text": " << \"soft-combining disabled (JS8_SOFT_COMBINING=0)\";" } ] } }, { "line": 59, "matches": [ "soft" ], "snippet": { "start_line": 53, "end_line": 65, "lines": [ { "line": 53, "text": " SoftCombiner() : SoftCombiner(defaultEnabled(), true) {}" }, { "line": 54, "text": "" }, { "line": 55, "text": " explicit SoftCombiner(bool enabled, bool runSelfTest = true)" }, { "line": 56, "text": " : m_enabled(enabled) {" }, { "line": 57, "text": " if (!m_enabled) {" }, { "line": 58, "text": " qCDebug(decoder_js8)" }, { "line": 59, "text": " << \"soft-combining disabled (JS8_SOFT_COMBINING=0)\";" }, { "line": 60, "text": " }" }, { "line": 61, "text": " if (runSelfTest)" }, { "line": 62, "text": " maybeRunSelfTest();" }, { "line": 63, "text": " }" }, { "line": 64, "text": "" }, { "line": 65, "text": " Key makeKey(int mode, float f1, float dt, std::array const &llr0," } ] } }, { "line": 65, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 59, "end_line": 71, "lines": [ { "line": 59, "text": " << \"soft-combining disabled (JS8_SOFT_COMBINING=0)\";" }, { "line": 60, "text": " }" }, { "line": 61, "text": " if (runSelfTest)" }, { "line": 62, "text": " maybeRunSelfTest();" }, { "line": 63, "text": " }" }, { "line": 64, "text": "" }, { "line": 65, "text": " Key makeKey(int mode, float f1, float dt, std::array const &llr0," }, { "line": 66, "text": " std::array const &llr1) const {" }, { "line": 67, "text": " return Key{mode, static_cast(std::lround(f1))," }, { "line": 68, "text": " static_cast(std::lround(dt * 10.0f)), // 100 ms bins" }, { "line": 69, "text": " signature(llr0, llr1)};" }, { "line": 70, "text": " }" }, { "line": 71, "text": "" } ] } }, { "line": 66, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 60, "end_line": 72, "lines": [ { "line": 60, "text": " }" }, { "line": 61, "text": " if (runSelfTest)" }, { "line": 62, "text": " maybeRunSelfTest();" }, { "line": 63, "text": " }" }, { "line": 64, "text": "" }, { "line": 65, "text": " Key makeKey(int mode, float f1, float dt, std::array const &llr0," }, { "line": 66, "text": " std::array const &llr1) const {" }, { "line": 67, "text": " return Key{mode, static_cast(std::lround(f1))," }, { "line": 68, "text": " static_cast(std::lround(dt * 10.0f)), // 100 ms bins" }, { "line": 69, "text": " signature(llr0, llr1)};" }, { "line": 70, "text": " }" }, { "line": 71, "text": "" }, { "line": 72, "text": " Combined combine(Key const &key, std::array const &llr0," } ] } }, { "line": 72, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 66, "end_line": 78, "lines": [ { "line": 66, "text": " std::array const &llr1) const {" }, { "line": 67, "text": " return Key{mode, static_cast(std::lround(f1))," }, { "line": 68, "text": " static_cast(std::lround(dt * 10.0f)), // 100 ms bins" }, { "line": 69, "text": " signature(llr0, llr1)};" }, { "line": 70, "text": " }" }, { "line": 71, "text": "" }, { "line": 72, "text": " Combined combine(Key const &key, std::array const &llr0," }, { "line": 73, "text": " std::array const &llr1," }, { "line": 74, "text": " std::chrono::seconds ttl) {" }, { "line": 75, "text": " flush(ttl);" }, { "line": 76, "text": "" }, { "line": 77, "text": " if (!m_enabled) {" }, { "line": 78, "text": " return Combined{key, llr0, llr1, 1, false};" } ] } }, { "line": 78, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 72, "end_line": 84, "lines": [ { "line": 72, "text": " Combined combine(Key const &key, std::array const &llr0," }, { "line": 73, "text": " std::array const &llr1," }, { "line": 74, "text": " std::chrono::seconds ttl) {" }, { "line": 75, "text": " flush(ttl);" }, { "line": 76, "text": "" }, { "line": 77, "text": " if (!m_enabled) {" }, { "line": 78, "text": " return Combined{key, llr0, llr1, 1, false};" }, { "line": 79, "text": " }" }, { "line": 80, "text": "" }, { "line": 81, "text": " auto &bucket = m_entries[keyForLookup(key)];" }, { "line": 82, "text": " auto it = findEntry(bucket, key.signature);" }, { "line": 83, "text": "" }, { "line": 84, "text": " if (it == bucket.end()) {" } ] } }, { "line": 85, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 79, "end_line": 91, "lines": [ { "line": 79, "text": " }" }, { "line": 80, "text": "" }, { "line": 81, "text": " auto &bucket = m_entries[keyForLookup(key)];" }, { "line": 82, "text": " auto it = findEntry(bucket, key.signature);" }, { "line": 83, "text": "" }, { "line": 84, "text": " if (it == bucket.end()) {" }, { "line": 85, "text": " bucket.push_back(makeEntry(key.signature, llr0, llr1));" }, { "line": 86, "text": " return Combined{key, llr0, llr1, 1, false};" }, { "line": 87, "text": " }" }, { "line": 88, "text": "" }, { "line": 89, "text": " for (std::size_t i = 0; i < llr0.size(); ++i) {" }, { "line": 90, "text": " it->llr0[i] += llr0[i];" }, { "line": 91, "text": " it->llr1[i] += llr1[i];" } ] } }, { "line": 86, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 80, "end_line": 92, "lines": [ { "line": 80, "text": "" }, { "line": 81, "text": " auto &bucket = m_entries[keyForLookup(key)];" }, { "line": 82, "text": " auto it = findEntry(bucket, key.signature);" }, { "line": 83, "text": "" }, { "line": 84, "text": " if (it == bucket.end()) {" }, { "line": 85, "text": " bucket.push_back(makeEntry(key.signature, llr0, llr1));" }, { "line": 86, "text": " return Combined{key, llr0, llr1, 1, false};" }, { "line": 87, "text": " }" }, { "line": 88, "text": "" }, { "line": 89, "text": " for (std::size_t i = 0; i < llr0.size(); ++i) {" }, { "line": 90, "text": " it->llr0[i] += llr0[i];" }, { "line": 91, "text": " it->llr1[i] += llr1[i];" }, { "line": 92, "text": " }" } ] } }, { "line": 91, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 85, "end_line": 97, "lines": [ { "line": 85, "text": " bucket.push_back(makeEntry(key.signature, llr0, llr1));" }, { "line": 86, "text": " return Combined{key, llr0, llr1, 1, false};" }, { "line": 87, "text": " }" }, { "line": 88, "text": "" }, { "line": 89, "text": " for (std::size_t i = 0; i < llr0.size(); ++i) {" }, { "line": 90, "text": " it->llr0[i] += llr0[i];" }, { "line": 91, "text": " it->llr1[i] += llr1[i];" }, { "line": 92, "text": " }" }, { "line": 93, "text": "" }, { "line": 94, "text": " ++it->repeats;" }, { "line": 95, "text": " it->lastSeen = Clock::now();" }, { "line": 96, "text": "" }, { "line": 97, "text": " qCDebug(decoder_js8)" } ] } }, { "line": 98, "matches": [ "soft" ], "snippet": { "start_line": 92, "end_line": 104, "lines": [ { "line": 92, "text": " }" }, { "line": 93, "text": "" }, { "line": 94, "text": " ++it->repeats;" }, { "line": 95, "text": " it->lastSeen = Clock::now();" }, { "line": 96, "text": "" }, { "line": 97, "text": " qCDebug(decoder_js8)" }, { "line": 98, "text": " << \"soft-combining repeats\" << it->repeats << \"mode\" << key.mode" }, { "line": 99, "text": " << \"freq\" << key.freqBin << \"dtbin\" << key.dtBin;" }, { "line": 100, "text": "" }, { "line": 101, "text": " return Combined{key, it->llr0, it->llr1, it->repeats, true};" }, { "line": 102, "text": " }" }, { "line": 103, "text": "" }, { "line": 104, "text": " void markDecoded(Key const &key) {" } ] } }, { "line": 101, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 95, "end_line": 107, "lines": [ { "line": 95, "text": " it->lastSeen = Clock::now();" }, { "line": 96, "text": "" }, { "line": 97, "text": " qCDebug(decoder_js8)" }, { "line": 98, "text": " << \"soft-combining repeats\" << it->repeats << \"mode\" << key.mode" }, { "line": 99, "text": " << \"freq\" << key.freqBin << \"dtbin\" << key.dtBin;" }, { "line": 100, "text": "" }, { "line": 101, "text": " return Combined{key, it->llr0, it->llr1, it->repeats, true};" }, { "line": 102, "text": " }" }, { "line": 103, "text": "" }, { "line": 104, "text": " void markDecoded(Key const &key) {" }, { "line": 105, "text": " if (!m_enabled)" }, { "line": 106, "text": " return;" }, { "line": 107, "text": "" } ] } }, { "line": 115, "matches": [ "erase" ], "snippet": { "start_line": 109, "end_line": 121, "lines": [ { "line": 109, "text": " auto it = m_entries.find(lookup);" }, { "line": 110, "text": "" }, { "line": 111, "text": " if (it == m_entries.end())" }, { "line": 112, "text": " return;" }, { "line": 113, "text": "" }, { "line": 114, "text": " auto &bucket = it->second;" }, { "line": 115, "text": " bucket.erase(std::remove_if(bucket.begin(), bucket.end()," }, { "line": 116, "text": " [&key](Entry const &entry) {" }, { "line": 117, "text": " return entry.signature == key.signature;" }, { "line": 118, "text": " })," }, { "line": 119, "text": " bucket.end());" }, { "line": 120, "text": "" }, { "line": 121, "text": " if (bucket.empty())" } ] } }, { "line": 122, "matches": [ "erase" ], "snippet": { "start_line": 116, "end_line": 128, "lines": [ { "line": 116, "text": " [&key](Entry const &entry) {" }, { "line": 117, "text": " return entry.signature == key.signature;" }, { "line": 118, "text": " })," }, { "line": 119, "text": " bucket.end());" }, { "line": 120, "text": "" }, { "line": 121, "text": " if (bucket.empty())" }, { "line": 122, "text": " m_entries.erase(it);" }, { "line": 123, "text": " }" }, { "line": 124, "text": "" }, { "line": 125, "text": " void flush(std::chrono::seconds ttl) {" }, { "line": 126, "text": " if (!m_enabled)" }, { "line": 127, "text": " return;" }, { "line": 128, "text": "" } ] } }, { "line": 134, "matches": [ "erase" ], "snippet": { "start_line": 128, "end_line": 140, "lines": [ { "line": 128, "text": "" }, { "line": 129, "text": " auto const now = Clock::now();" }, { "line": 130, "text": "" }, { "line": 131, "text": " for (auto it = m_entries.begin(); it != m_entries.end();) {" }, { "line": 132, "text": " auto &bucket = it->second;" }, { "line": 133, "text": "" }, { "line": 134, "text": " bucket.erase(std::remove_if(bucket.begin(), bucket.end()," }, { "line": 135, "text": " [now, ttl](Entry const &entry) {" }, { "line": 136, "text": " return now - entry.lastSeen > ttl;" }, { "line": 137, "text": " })," }, { "line": 138, "text": " bucket.end());" }, { "line": 139, "text": "" }, { "line": 140, "text": " if (bucket.empty())" } ] } }, { "line": 141, "matches": [ "erase" ], "snippet": { "start_line": 135, "end_line": 147, "lines": [ { "line": 135, "text": " [now, ttl](Entry const &entry) {" }, { "line": 136, "text": " return now - entry.lastSeen > ttl;" }, { "line": 137, "text": " })," }, { "line": 138, "text": " bucket.end());" }, { "line": 139, "text": "" }, { "line": 140, "text": " if (bucket.empty())" }, { "line": 141, "text": " it = m_entries.erase(it);" }, { "line": 142, "text": " else" }, { "line": 143, "text": " ++it;" }, { "line": 144, "text": " }" }, { "line": 145, "text": " }" }, { "line": 146, "text": "" }, { "line": 147, "text": " private:" } ] } }, { "line": 170, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 164, "end_line": 176, "lines": [ { "line": 164, "text": " return h1 ^ (h2 << 1) ^ (h3 << 2);" }, { "line": 165, "text": " }" }, { "line": 166, "text": " };" }, { "line": 167, "text": "" }, { "line": 168, "text": " struct Entry {" }, { "line": 169, "text": " uint32_t signature;" }, { "line": 170, "text": " std::array llr0;" }, { "line": 171, "text": " std::array llr1;" }, { "line": 172, "text": " int repeats;" }, { "line": 173, "text": " Clock::time_point lastSeen;" }, { "line": 174, "text": " };" }, { "line": 175, "text": "" }, { "line": 176, "text": " using Bucket = std::vector;" } ] } }, { "line": 171, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 165, "end_line": 177, "lines": [ { "line": 165, "text": " }" }, { "line": 166, "text": " };" }, { "line": 167, "text": "" }, { "line": 168, "text": " struct Entry {" }, { "line": 169, "text": " uint32_t signature;" }, { "line": 170, "text": " std::array llr0;" }, { "line": 171, "text": " std::array llr1;" }, { "line": 172, "text": " int repeats;" }, { "line": 173, "text": " Clock::time_point lastSeen;" }, { "line": 174, "text": " };" }, { "line": 175, "text": "" }, { "line": 176, "text": " using Bucket = std::vector;" }, { "line": 177, "text": "" } ] } }, { "line": 200, "matches": [ "soft" ], "snippet": { "start_line": 194, "end_line": 206, "lines": [ { "line": 194, "text": " return hamming(signature, entry.signature) <= MAX_HAMMING;" }, { "line": 195, "text": " });" }, { "line": 196, "text": " }" }, { "line": 197, "text": "" }, { "line": 198, "text": " static bool defaultEnabled() {" }, { "line": 199, "text": " bool ok = false;" }, { "line": 200, "text": " int value = qEnvironmentVariableIntValue(\"JS8_SOFT_COMBINING\", &ok);" }, { "line": 201, "text": " return ok ? value != 0 : true;" }, { "line": 202, "text": " }" }, { "line": 203, "text": "" }, { "line": 204, "text": " static uint32_t signature(std::array const &llr0," }, { "line": 205, "text": " std::array const &llr1) {" }, { "line": 206, "text": " static constexpr auto INDICES = signatureIndices();" } ] } }, { "line": 204, "matches": [ "LLR", "llr" ], "snippet": { "start_line": 198, "end_line": 210, "lines": [ { "line": 198, "text": " static bool defaultEnabled() {" }, { "line": 199, "text": " bool ok = false;" }, { "line": 200, "text": " int value = qEnvironmentVariableIntValue(\"JS8_SOFT_COMBINING\", &ok);" }, { "line": 201, "text": " return ok ? value != 0 : true;" }, { "line": 202, "text": " }" }, { "line": 203, "text": "" }, { "line": 204, "text": " static uint32_t signature(std::array const &llr0," }, { "line": 205, "text": " std::array const &llr1) {" }, { "line": 206, "text": " static constexpr auto INDICES = signatureIndices();" }, { "line": 207, "text": "" }, { "line": 208, "text": " uint32_t sig = 0;" }, { "line": 209, "text": " for (std::size_t i = 0; i < INDICES.size(); ++i) {" }, { "line": 210, "text": " auto const idx = INDICES[i];" } ] } } ] }, { "path": "JS8_Mode/whitening_processor.h", "exists": true, "bytes": 9129, "sha256": "bcd61a557030caba012b501d3ea851ab0cfda16c8ec4d01ddc902bebec86fb45", "line_count": 259, "phase_hits": { "timing_submode": 0, "symbol_to_soft_bits": 112, "bit_order_interleaver": 2, "whitening_erasure": 57, "ldpc_decode": 0, "message91_crc_text": 0 }, "function_blocks": [], "keyword_snippets": [ { "line": 19, "matches": [ "whiten", "noise", "LLR" ], "snippet": { "start_line": 13, "end_line": 25, "lines": [ { "line": 13, "text": "#include " }, { "line": 14, "text": "" }, { "line": 15, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);" }, { "line": 16, "text": "" }, { "line": 17, "text": "namespace js8 {" }, { "line": 18, "text": "/**" }, { "line": 19, "text": " * @brief Compute per-tone/symbol noise medians and whiten LLRs for a JS8 frame." }, { "line": 20, "text": " *" }, { "line": 21, "text": " * Given symbol magnitudes (sans Costas) and winners, produces normalized" }, { "line": 22, "text": " * LLR0/LLR1, optionally applying noise-based whitening and erasure. Fully" }, { "line": 23, "text": " * templated on matrix dimensions, so it stays header-only; used inside the JS8" }, { "line": 24, "text": " * decoder per candidate." }, { "line": 25, "text": " */" } ] } }, { "line": 22, "matches": [ "whiten", "noise", "LLR" ], "snippet": { "start_line": 16, "end_line": 28, "lines": [ { "line": 16, "text": "" }, { "line": 17, "text": "namespace js8 {" }, { "line": 18, "text": "/**" }, { "line": 19, "text": " * @brief Compute per-tone/symbol noise medians and whiten LLRs for a JS8 frame." }, { "line": 20, "text": " *" }, { "line": 21, "text": " * Given symbol magnitudes (sans Costas) and winners, produces normalized" }, { "line": 22, "text": " * LLR0/LLR1, optionally applying noise-based whitening and erasure. Fully" }, { "line": 23, "text": " * templated on matrix dimensions, so it stays header-only; used inside the JS8" }, { "line": 24, "text": " * decoder per candidate." }, { "line": 25, "text": " */" }, { "line": 26, "text": "template class WhiteningProcessor {" }, { "line": 27, "text": " public:" }, { "line": 28, "text": " struct Result {" } ] } }, { "line": 26, "matches": [ "whiten" ], "snippet": { "start_line": 20, "end_line": 32, "lines": [ { "line": 20, "text": " *" }, { "line": 21, "text": " * Given symbol magnitudes (sans Costas) and winners, produces normalized" }, { "line": 22, "text": " * LLR0/LLR1, optionally applying noise-based whitening and erasure. Fully" }, { "line": 23, "text": " * templated on matrix dimensions, so it stays header-only; used inside the JS8" }, { "line": 24, "text": " * decoder per candidate." }, { "line": 25, "text": " */" }, { "line": 26, "text": "template class WhiteningProcessor {" }, { "line": 27, "text": " public:" }, { "line": 28, "text": " struct Result {" }, { "line": 29, "text": " std::array llr0;" }, { "line": 30, "text": " std::array llr1;" }, { "line": 31, "text": " bool whiteningApplied;" }, { "line": 32, "text": " bool erasureApplied;" } ] } }, { "line": 31, "matches": [ "whiten" ], "snippet": { "start_line": 25, "end_line": 37, "lines": [ { "line": 25, "text": " */" }, { "line": 26, "text": "template class WhiteningProcessor {" }, { "line": 27, "text": " public:" }, { "line": 28, "text": " struct Result {" }, { "line": 29, "text": " std::array llr0;" }, { "line": 30, "text": " std::array llr1;" }, { "line": 31, "text": " bool whiteningApplied;" }, { "line": 32, "text": " bool erasureApplied;" }, { "line": 33, "text": " std::size_t erasures;" }, { "line": 34, "text": " double avgAbsPre;" }, { "line": 35, "text": " double avgAbsPost;" }, { "line": 36, "text": " };" }, { "line": 37, "text": "" } ] } }, { "line": 61, "matches": [ "noise" ], "snippet": { "start_line": 55, "end_line": 67, "lines": [ { "line": 55, "text": " med = 0.5f * (med + values[mid - 1]);" }, { "line": 56, "text": " }" }, { "line": 57, "text": "" }, { "line": 58, "text": " return med;" }, { "line": 59, "text": " };" }, { "line": 60, "text": "" }, { "line": 61, "text": " // Estimate per-tone noise using non-winning tone magnitudes across the" }, { "line": 62, "text": " // frame." }, { "line": 63, "text": " auto const toneNoise =" }, { "line": 64, "text": " [&]() -> std::optional> {" }, { "line": 65, "text": " std::array, NROWS> toneSamples;" }, { "line": 66, "text": " std::array noise = {};" }, { "line": 67, "text": "" } ] } }, { "line": 66, "matches": [ "noise" ], "snippet": { "start_line": 60, "end_line": 72, "lines": [ { "line": 60, "text": "" }, { "line": 61, "text": " // Estimate per-tone noise using non-winning tone magnitudes across the" }, { "line": 62, "text": " // frame." }, { "line": 63, "text": " auto const toneNoise =" }, { "line": 64, "text": " [&]() -> std::optional> {" }, { "line": 65, "text": " std::array, NROWS> toneSamples;" }, { "line": 66, "text": " std::array noise = {};" }, { "line": 67, "text": "" }, { "line": 68, "text": " // Collect non-winning magnitudes for each tone." }, { "line": 69, "text": " for (int j = 0; j < ND; ++j) {" }, { "line": 70, "text": " int const winner = symbolWinners[j];" }, { "line": 71, "text": "" }, { "line": 72, "text": " for (int i = 0; i < NROWS; ++i) {" } ] } }, { "line": 82, "matches": [ "noise" ], "snippet": { "start_line": 76, "end_line": 88, "lines": [ { "line": 76, "text": " }" }, { "line": 77, "text": "" }, { "line": 78, "text": " bool ok = true;" }, { "line": 79, "text": "" }, { "line": 80, "text": " for (int i = 0; i < NROWS; ++i) {" }, { "line": 81, "text": " if (auto m = median(toneSamples[i]); m) {" }, { "line": 82, "text": " noise[i] = *m;" }, { "line": 83, "text": " } else {" }, { "line": 84, "text": " ok = false;" }, { "line": 85, "text": " break;" }, { "line": 86, "text": " }" }, { "line": 87, "text": " }" }, { "line": 88, "text": "" } ] } }, { "line": 92, "matches": [ "noise" ], "snippet": { "start_line": 86, "end_line": 98, "lines": [ { "line": 86, "text": " }" }, { "line": 87, "text": " }" }, { "line": 88, "text": "" }, { "line": 89, "text": " if (!ok)" }, { "line": 90, "text": " return std::nullopt;" }, { "line": 91, "text": "" }, { "line": 92, "text": " return noise;" }, { "line": 93, "text": " }();" }, { "line": 94, "text": "" }, { "line": 95, "text": " if (toneNoise && debug) {" }, { "line": 96, "text": " std::ostringstream oss;" }, { "line": 97, "text": "" }, { "line": 98, "text": " oss << \"toneNoise:\";" } ] } }, { "line": 98, "matches": [ "noise" ], "snippet": { "start_line": 92, "end_line": 104, "lines": [ { "line": 92, "text": " return noise;" }, { "line": 93, "text": " }();" }, { "line": 94, "text": "" }, { "line": 95, "text": " if (toneNoise && debug) {" }, { "line": 96, "text": " std::ostringstream oss;" }, { "line": 97, "text": "" }, { "line": 98, "text": " oss << \"toneNoise:\";" }, { "line": 99, "text": " for (auto const value : *toneNoise)" }, { "line": 100, "text": " oss << ' ' << value;" }, { "line": 101, "text": "" }, { "line": 102, "text": " qCDebug(decoder_js8).noquote() << oss.str().c_str();" }, { "line": 103, "text": " }" }, { "line": 104, "text": "" } ] } }, { "line": 105, "matches": [ "noise" ], "snippet": { "start_line": 99, "end_line": 111, "lines": [ { "line": 99, "text": " for (auto const value : *toneNoise)" }, { "line": 100, "text": " oss << ' ' << value;" }, { "line": 101, "text": "" }, { "line": 102, "text": " qCDebug(decoder_js8).noquote() << oss.str().c_str();" }, { "line": 103, "text": " }" }, { "line": 104, "text": "" }, { "line": 105, "text": " // Estimate per-symbol noise using non-winning tone magnitudes per" }, { "line": 106, "text": " // symbol." }, { "line": 107, "text": " auto const symbolNoise = [&]() -> std::optional> {" }, { "line": 108, "text": " std::vector noise;" }, { "line": 109, "text": " noise.reserve(ND);" }, { "line": 110, "text": "" }, { "line": 111, "text": " for (int j = 0; j < ND; ++j) {" } ] } }, { "line": 107, "matches": [ "noise" ], "snippet": { "start_line": 101, "end_line": 113, "lines": [ { "line": 101, "text": "" }, { "line": 102, "text": " qCDebug(decoder_js8).noquote() << oss.str().c_str();" }, { "line": 103, "text": " }" }, { "line": 104, "text": "" }, { "line": 105, "text": " // Estimate per-symbol noise using non-winning tone magnitudes per" }, { "line": 106, "text": " // symbol." }, { "line": 107, "text": " auto const symbolNoise = [&]() -> std::optional> {" }, { "line": 108, "text": " std::vector noise;" }, { "line": 109, "text": " noise.reserve(ND);" }, { "line": 110, "text": "" }, { "line": 111, "text": " for (int j = 0; j < ND; ++j) {" }, { "line": 112, "text": " std::vector bins;" }, { "line": 113, "text": " bins.reserve(NROWS - 1);" } ] } }, { "line": 123, "matches": [ "noise" ], "snippet": { "start_line": 117, "end_line": 129, "lines": [ { "line": 117, "text": " for (int i = 0; i < NROWS; ++i) {" }, { "line": 118, "text": " if (i != winner)" }, { "line": 119, "text": " bins.push_back(s1[i][j]);" }, { "line": 120, "text": " }" }, { "line": 121, "text": "" }, { "line": 122, "text": " if (auto m = median(bins); m) {" }, { "line": 123, "text": " noise.push_back(*m);" }, { "line": 124, "text": " } else {" }, { "line": 125, "text": " return std::nullopt;" }, { "line": 126, "text": " }" }, { "line": 127, "text": " }" }, { "line": 128, "text": "" }, { "line": 129, "text": " return noise;" } ] } }, { "line": 129, "matches": [ "noise" ], "snippet": { "start_line": 123, "end_line": 135, "lines": [ { "line": 123, "text": " noise.push_back(*m);" }, { "line": 124, "text": " } else {" }, { "line": 125, "text": " return std::nullopt;" }, { "line": 126, "text": " }" }, { "line": 127, "text": " }" }, { "line": 128, "text": "" }, { "line": 129, "text": " return noise;" }, { "line": 130, "text": " }();" }, { "line": 131, "text": "" }, { "line": 132, "text": " if (symbolNoise && !symbolNoise->empty() && debug) {" }, { "line": 133, "text": " auto const [minIt, maxIt] =" }, { "line": 134, "text": " std::minmax_element(symbolNoise->begin(), symbolNoise->end());" }, { "line": 135, "text": " float const avg = std::accumulate(symbolNoise->begin()," } ] } }, { "line": 132, "matches": [ "noise" ], "snippet": { "start_line": 126, "end_line": 138, "lines": [ { "line": 126, "text": " }" }, { "line": 127, "text": " }" }, { "line": 128, "text": "" }, { "line": 129, "text": " return noise;" }, { "line": 130, "text": " }();" }, { "line": 131, "text": "" }, { "line": 132, "text": " if (symbolNoise && !symbolNoise->empty() && debug) {" }, { "line": 133, "text": " auto const [minIt, maxIt] =" }, { "line": 134, "text": " std::minmax_element(symbolNoise->begin(), symbolNoise->end());" }, { "line": 135, "text": " float const avg = std::accumulate(symbolNoise->begin()," }, { "line": 136, "text": " symbolNoise->end(), 0.0f) /" }, { "line": 137, "text": " static_cast(symbolNoise->size());" }, { "line": 138, "text": "" } ] } }, { "line": 136, "matches": [ "noise" ], "snippet": { "start_line": 130, "end_line": 142, "lines": [ { "line": 130, "text": " }();" }, { "line": 131, "text": "" }, { "line": 132, "text": " if (symbolNoise && !symbolNoise->empty() && debug) {" }, { "line": 133, "text": " auto const [minIt, maxIt] =" }, { "line": 134, "text": " std::minmax_element(symbolNoise->begin(), symbolNoise->end());" }, { "line": 135, "text": " float const avg = std::accumulate(symbolNoise->begin()," }, { "line": 136, "text": " symbolNoise->end(), 0.0f) /" }, { "line": 137, "text": " static_cast(symbolNoise->size());" }, { "line": 138, "text": "" }, { "line": 139, "text": " qCDebug(decoder_js8)" }, { "line": 140, "text": " << \"symbolNoise avg/min/max\" << avg << *minIt << *maxIt;" }, { "line": 141, "text": " }" }, { "line": 142, "text": "" } ] } }, { "line": 145, "matches": [ "whiten" ], "snippet": { "start_line": 139, "end_line": 151, "lines": [ { "line": 139, "text": " qCDebug(decoder_js8)" }, { "line": 140, "text": " << \"symbolNoise avg/min/max\" << avg << *minIt << *maxIt;" }, { "line": 141, "text": " }" }, { "line": 142, "text": "" }, { "line": 143, "text": " Result result{};" }, { "line": 144, "text": "" }, { "line": 145, "text": " bool const disableWhitening =" }, { "line": 146, "text": " std::getenv(\"JS8_DISABLE_WHITENING\") != nullptr;" }, { "line": 147, "text": " bool const whiteningAvailable = toneNoise && symbolNoise &&" }, { "line": 148, "text": " !symbolNoise->empty() &&" }, { "line": 149, "text": " !disableWhitening;" }, { "line": 150, "text": " bool const applyErasureInWhitening =" }, { "line": 151, "text": " whiteningAvailable && erasureThreshold > 0.0f;" } ] } }, { "line": 146, "matches": [ "whiten" ], "snippet": { "start_line": 140, "end_line": 152, "lines": [ { "line": 140, "text": " << \"symbolNoise avg/min/max\" << avg << *minIt << *maxIt;" }, { "line": 141, "text": " }" }, { "line": 142, "text": "" }, { "line": 143, "text": " Result result{};" }, { "line": 144, "text": "" }, { "line": 145, "text": " bool const disableWhitening =" }, { "line": 146, "text": " std::getenv(\"JS8_DISABLE_WHITENING\") != nullptr;" }, { "line": 147, "text": " bool const whiteningAvailable = toneNoise && symbolNoise &&" }, { "line": 148, "text": " !symbolNoise->empty() &&" }, { "line": 149, "text": " !disableWhitening;" }, { "line": 150, "text": " bool const applyErasureInWhitening =" }, { "line": 151, "text": " whiteningAvailable && erasureThreshold > 0.0f;" }, { "line": 152, "text": " double sumAbsPre = 0.0;" } ] } }, { "line": 151, "matches": [ "whiten" ], "snippet": { "start_line": 145, "end_line": 157, "lines": [ { "line": 145, "text": " bool const disableWhitening =" }, { "line": 146, "text": " std::getenv(\"JS8_DISABLE_WHITENING\") != nullptr;" }, { "line": 147, "text": " bool const whiteningAvailable = toneNoise && symbolNoise &&" }, { "line": 148, "text": " !symbolNoise->empty() &&" }, { "line": 149, "text": " !disableWhitening;" }, { "line": 150, "text": " bool const applyErasureInWhitening =" }, { "line": 151, "text": " whiteningAvailable && erasureThreshold > 0.0f;" }, { "line": 152, "text": " double sumAbsPre = 0.0;" }, { "line": 153, "text": " double sumAbsPost = 0.0;" }, { "line": 154, "text": " std::size_t erasures = 0;" }, { "line": 155, "text": "" }, { "line": 156, "text": " for (int j = 0; j < ND; ++j) {" }, { "line": 157, "text": " int const i1 = 3 * j; // First column (matches Fortran's i1)" } ] } }, { "line": 167, "matches": [ "LLR" ], "snippet": { "start_line": 161, "end_line": 173, "lines": [ { "line": 161, "text": " std::array ps;" }, { "line": 162, "text": "" }, { "line": 163, "text": " for (int i = 0; i < NROWS; ++i)" }, { "line": 164, "text": " ps[i] = s1[i][j];" }, { "line": 165, "text": "" }, { "line": 166, "text": " // Assign to `bmeta` in column order, with correct values" }, { "line": 167, "text": " result.llr0[i1] = std::max({ps[4], ps[5], ps[6], ps[7]}) -" }, { "line": 168, "text": " std::max({ps[0], ps[1], ps[2], ps[3]}); // r4" }, { "line": 169, "text": " result.llr0[i2] = std::max({ps[2], ps[3], ps[6], ps[7]}) -" }, { "line": 170, "text": " std::max({ps[0], ps[1], ps[4], ps[5]}); // r2" }, { "line": 171, "text": " result.llr0[i4] = std::max({ps[1], ps[3], ps[5], ps[7]}) -" }, { "line": 172, "text": " std::max({ps[0], ps[2], ps[4], ps[6]}); // r1" }, { "line": 173, "text": "" } ] } }, { "line": 171, "matches": [ "LLR" ], "snippet": { "start_line": 165, "end_line": 177, "lines": [ { "line": 165, "text": "" }, { "line": 166, "text": " // Assign to `bmeta` in column order, with correct values" }, { "line": 167, "text": " result.llr0[i1] = std::max({ps[4], ps[5], ps[6], ps[7]}) -" }, { "line": 168, "text": " std::max({ps[0], ps[1], ps[2], ps[3]}); // r4" }, { "line": 169, "text": " result.llr0[i2] = std::max({ps[2], ps[3], ps[6], ps[7]}) -" }, { "line": 170, "text": " std::max({ps[0], ps[1], ps[4], ps[5]}); // r2" }, { "line": 171, "text": " result.llr0[i4] = std::max({ps[1], ps[3], ps[5], ps[7]}) -" }, { "line": 172, "text": " std::max({ps[0], ps[2], ps[4], ps[6]}); // r1" }, { "line": 173, "text": "" }, { "line": 174, "text": " for (auto &x : ps)" }, { "line": 175, "text": " x = std::log(x + 1e-32f);" }, { "line": 176, "text": "" }, { "line": 177, "text": " // Assign to `bmetb` in column order, with correct values" } ] } }, { "line": 178, "matches": [ "LLR" ], "snippet": { "start_line": 172, "end_line": 184, "lines": [ { "line": 172, "text": " std::max({ps[0], ps[2], ps[4], ps[6]}); // r1" }, { "line": 173, "text": "" }, { "line": 174, "text": " for (auto &x : ps)" }, { "line": 175, "text": " x = std::log(x + 1e-32f);" }, { "line": 176, "text": "" }, { "line": 177, "text": " // Assign to `bmetb` in column order, with correct values" }, { "line": 178, "text": " result.llr1[i1] = std::max({ps[4], ps[5], ps[6], ps[7]}) -" }, { "line": 179, "text": " std::max({ps[0], ps[1], ps[2], ps[3]}); // r4" }, { "line": 180, "text": " result.llr1[i2] = std::max({ps[2], ps[3], ps[6], ps[7]}) -" }, { "line": 181, "text": " std::max({ps[0], ps[1], ps[4], ps[5]}); // r2" }, { "line": 182, "text": " result.llr1[i4] = std::max({ps[1], ps[3], ps[5], ps[7]}) -" }, { "line": 183, "text": " std::max({ps[0], ps[2], ps[4], ps[6]}); // r1" }, { "line": 184, "text": "" } ] } }, { "line": 182, "matches": [ "LLR" ], "snippet": { "start_line": 176, "end_line": 188, "lines": [ { "line": 176, "text": "" }, { "line": 177, "text": " // Assign to `bmetb` in column order, with correct values" }, { "line": 178, "text": " result.llr1[i1] = std::max({ps[4], ps[5], ps[6], ps[7]}) -" }, { "line": 179, "text": " std::max({ps[0], ps[1], ps[2], ps[3]}); // r4" }, { "line": 180, "text": " result.llr1[i2] = std::max({ps[2], ps[3], ps[6], ps[7]}) -" }, { "line": 181, "text": " std::max({ps[0], ps[1], ps[4], ps[5]}); // r2" }, { "line": 182, "text": " result.llr1[i4] = std::max({ps[1], ps[3], ps[5], ps[7]}) -" }, { "line": 183, "text": " std::max({ps[0], ps[2], ps[4], ps[6]}); // r1" }, { "line": 184, "text": "" }, { "line": 185, "text": " if (whiteningAvailable) {" }, { "line": 186, "text": " int const winner = symbolWinners[j];" }, { "line": 187, "text": " float const tn = std::max(0.0f, (*toneNoise)[winner]);" }, { "line": 188, "text": " float const sn = std::max(0.0f, (*symbolNoise)[j]);" } ] } } ] }, { "path": "JS8_Mode/ldpc_feedback.h", "exists": true, "bytes": 3293, "sha256": "c9bb4ccc8f3def26952a29e97a88f4d912f7f79ed6006e843601b9d30fb974d0", "line_count": 109, "phase_hits": { "timing_submode": 0, "symbol_to_soft_bits": 50, "bit_order_interleaver": 4, "whitening_erasure": 0, "ldpc_decode": 24, "message91_crc_text": 0 }, "function_blocks": [ { "function": "llrErasureThreshold", "line": 33, "signature": "inline float llrErasureThreshold() {", "snippet": { "start_line": 19, "end_line": 47, "lines": [ { "line": 19, "text": " *" }, { "line": 20, "text": " * Inline env readers expose thresholds/pass limits; the templated" }, { "line": 21, "text": " * refineLlrsWithLdpcFeedback shrinks/boosts LLRs using the decoded" }, { "line": 22, "text": " * codeword to retry LDPC. Used inside the JS8 decode loop between" }, { "line": 23, "text": " * LDPC passes." }, { "line": 24, "text": " */" }, { "line": 25, "text": "constexpr float LLR_ERASURE_THRESHOLD_DEFAULT = 0.25f;" }, { "line": 26, "text": "constexpr float LLR_FEEDBACK_CONFIDENT_MIN = 3.0f;" }, { "line": 27, "text": "constexpr float LLR_FEEDBACK_UNCERTAIN_MAX = 1.0f;" }, { "line": 28, "text": "constexpr float LLR_FEEDBACK_CONFIDENT_BOOST = 1.2f;" }, { "line": 29, "text": "constexpr float LLR_FEEDBACK_UNCERTAIN_SHRINK = 0.5f;" }, { "line": 30, "text": "constexpr float LLR_FEEDBACK_MAX_MAG = 6.0f;" }, { "line": 31, "text": "constexpr int LDPC_FEEDBACK_MAX_PASSES_DEFAULT = 8;" }, { "line": 32, "text": "" }, { "line": 33, "text": "inline float llrErasureThreshold() {" }, { "line": 34, "text": " float threshold = LLR_ERASURE_THRESHOLD_DEFAULT;" }, { "line": 35, "text": "" }, { "line": 36, "text": " if (auto const env = std::getenv(\"JS8_LLR_ERASURE_THRESH\"); env) {" }, { "line": 37, "text": " char *end = nullptr;" }, { "line": 38, "text": " float val = std::strtof(env, &end);" }, { "line": 39, "text": "" }, { "line": 40, "text": " if (end != env && std::isfinite(val)) {" }, { "line": 41, "text": " threshold = val;" }, { "line": 42, "text": " }" }, { "line": 43, "text": " }" }, { "line": 44, "text": "" }, { "line": 45, "text": " if (threshold <= 0.0f || !std::isfinite(threshold) ||" }, { "line": 46, "text": " std::getenv(\"JS8_DISABLE_ERASURE_THRESHOLDING\")) {" }, { "line": 47, "text": " return 0.0f;" } ] } }, { "function": "ldpcFeedbackEnabled", "line": 53, "signature": "inline bool ldpcFeedbackEnabled() {", "snippet": { "start_line": 39, "end_line": 67, "lines": [ { "line": 39, "text": "" }, { "line": 40, "text": " if (end != env && std::isfinite(val)) {" }, { "line": 41, "text": " threshold = val;" }, { "line": 42, "text": " }" }, { "line": 43, "text": " }" }, { "line": 44, "text": "" }, { "line": 45, "text": " if (threshold <= 0.0f || !std::isfinite(threshold) ||" }, { "line": 46, "text": " std::getenv(\"JS8_DISABLE_ERASURE_THRESHOLDING\")) {" }, { "line": 47, "text": " return 0.0f;" }, { "line": 48, "text": " }" }, { "line": 49, "text": "" }, { "line": 50, "text": " return threshold;" }, { "line": 51, "text": "}" }, { "line": 52, "text": "" }, { "line": 53, "text": "inline bool ldpcFeedbackEnabled() {" }, { "line": 54, "text": " bool ok = false;" }, { "line": 55, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_FEEDBACK\", &ok);" }, { "line": 56, "text": " return ok ? value != 0 : true;" }, { "line": 57, "text": "}" }, { "line": 58, "text": "" }, { "line": 59, "text": "inline int ldpcFeedbackMaxPasses() {" }, { "line": 60, "text": " bool ok = false;" }, { "line": 61, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_MAX_PASSES\", &ok);" }, { "line": 62, "text": "" }, { "line": 63, "text": " if (!ok)" }, { "line": 64, "text": " return LDPC_FEEDBACK_MAX_PASSES_DEFAULT;" }, { "line": 65, "text": "" }, { "line": 66, "text": " return std::clamp(value, 1, LDPC_FEEDBACK_MAX_PASSES_DEFAULT);" }, { "line": 67, "text": "}" } ] } }, { "function": "ldpcFeedbackMaxPasses", "line": 59, "signature": "inline int ldpcFeedbackMaxPasses() {", "snippet": { "start_line": 45, "end_line": 73, "lines": [ { "line": 45, "text": " if (threshold <= 0.0f || !std::isfinite(threshold) ||" }, { "line": 46, "text": " std::getenv(\"JS8_DISABLE_ERASURE_THRESHOLDING\")) {" }, { "line": 47, "text": " return 0.0f;" }, { "line": 48, "text": " }" }, { "line": 49, "text": "" }, { "line": 50, "text": " return threshold;" }, { "line": 51, "text": "}" }, { "line": 52, "text": "" }, { "line": 53, "text": "inline bool ldpcFeedbackEnabled() {" }, { "line": 54, "text": " bool ok = false;" }, { "line": 55, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_FEEDBACK\", &ok);" }, { "line": 56, "text": " return ok ? value != 0 : true;" }, { "line": 57, "text": "}" }, { "line": 58, "text": "" }, { "line": 59, "text": "inline int ldpcFeedbackMaxPasses() {" }, { "line": 60, "text": " bool ok = false;" }, { "line": 61, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_MAX_PASSES\", &ok);" }, { "line": 62, "text": "" }, { "line": 63, "text": " if (!ok)" }, { "line": 64, "text": " return LDPC_FEEDBACK_MAX_PASSES_DEFAULT;" }, { "line": 65, "text": "" }, { "line": 66, "text": " return std::clamp(value, 1, LDPC_FEEDBACK_MAX_PASSES_DEFAULT);" }, { "line": 67, "text": "}" }, { "line": 68, "text": "" }, { "line": 69, "text": "template " }, { "line": 70, "text": "void refineLlrsWithLdpcFeedback(std::array const &llrIn," }, { "line": 71, "text": " std::array const &cw," }, { "line": 72, "text": " float erasureThreshold," }, { "line": 73, "text": " std::array &llrOut," } ] } } ], "keyword_snippets": [ { "line": 14, "matches": [ "decode" ], "snippet": { "start_line": 8, "end_line": 20, "lines": [ { "line": 8, "text": "#include " }, { "line": 9, "text": "#include " }, { "line": 10, "text": "#include " }, { "line": 11, "text": "#include " }, { "line": 12, "text": "#include " }, { "line": 13, "text": "" }, { "line": 14, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);" }, { "line": 15, "text": "" }, { "line": 16, "text": "namespace js8 {" }, { "line": 17, "text": "/**" }, { "line": 18, "text": " * @brief LDPC erasure threshold config and feedback refinement helpers." }, { "line": 19, "text": " *" }, { "line": 20, "text": " * Inline env readers expose thresholds/pass limits; the templated" } ] } }, { "line": 18, "matches": [ "ldpc" ], "snippet": { "start_line": 12, "end_line": 24, "lines": [ { "line": 12, "text": "#include " }, { "line": 13, "text": "" }, { "line": 14, "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);" }, { "line": 15, "text": "" }, { "line": 16, "text": "namespace js8 {" }, { "line": 17, "text": "/**" }, { "line": 18, "text": " * @brief LDPC erasure threshold config and feedback refinement helpers." }, { "line": 19, "text": " *" }, { "line": 20, "text": " * Inline env readers expose thresholds/pass limits; the templated" }, { "line": 21, "text": " * refineLlrsWithLdpcFeedback shrinks/boosts LLRs using the decoded" }, { "line": 22, "text": " * codeword to retry LDPC. Used inside the JS8 decode loop between" }, { "line": 23, "text": " * LDPC passes." }, { "line": 24, "text": " */" } ] } }, { "line": 21, "matches": [ "ldpc", "decode", "LLR" ], "snippet": { "start_line": 15, "end_line": 27, "lines": [ { "line": 15, "text": "" }, { "line": 16, "text": "namespace js8 {" }, { "line": 17, "text": "/**" }, { "line": 18, "text": " * @brief LDPC erasure threshold config and feedback refinement helpers." }, { "line": 19, "text": " *" }, { "line": 20, "text": " * Inline env readers expose thresholds/pass limits; the templated" }, { "line": 21, "text": " * refineLlrsWithLdpcFeedback shrinks/boosts LLRs using the decoded" }, { "line": 22, "text": " * codeword to retry LDPC. Used inside the JS8 decode loop between" }, { "line": 23, "text": " * LDPC passes." }, { "line": 24, "text": " */" }, { "line": 25, "text": "constexpr float LLR_ERASURE_THRESHOLD_DEFAULT = 0.25f;" }, { "line": 26, "text": "constexpr float LLR_FEEDBACK_CONFIDENT_MIN = 3.0f;" }, { "line": 27, "text": "constexpr float LLR_FEEDBACK_UNCERTAIN_MAX = 1.0f;" } ] } }, { "line": 26, "matches": [ "LLR" ], "snippet": { "start_line": 20, "end_line": 32, "lines": [ { "line": 20, "text": " * Inline env readers expose thresholds/pass limits; the templated" }, { "line": 21, "text": " * refineLlrsWithLdpcFeedback shrinks/boosts LLRs using the decoded" }, { "line": 22, "text": " * codeword to retry LDPC. Used inside the JS8 decode loop between" }, { "line": 23, "text": " * LDPC passes." }, { "line": 24, "text": " */" }, { "line": 25, "text": "constexpr float LLR_ERASURE_THRESHOLD_DEFAULT = 0.25f;" }, { "line": 26, "text": "constexpr float LLR_FEEDBACK_CONFIDENT_MIN = 3.0f;" }, { "line": 27, "text": "constexpr float LLR_FEEDBACK_UNCERTAIN_MAX = 1.0f;" }, { "line": 28, "text": "constexpr float LLR_FEEDBACK_CONFIDENT_BOOST = 1.2f;" }, { "line": 29, "text": "constexpr float LLR_FEEDBACK_UNCERTAIN_SHRINK = 0.5f;" }, { "line": 30, "text": "constexpr float LLR_FEEDBACK_MAX_MAG = 6.0f;" }, { "line": 31, "text": "constexpr int LDPC_FEEDBACK_MAX_PASSES_DEFAULT = 8;" }, { "line": 32, "text": "" } ] } }, { "line": 31, "matches": [ "ldpc" ], "snippet": { "start_line": 25, "end_line": 37, "lines": [ { "line": 25, "text": "constexpr float LLR_ERASURE_THRESHOLD_DEFAULT = 0.25f;" }, { "line": 26, "text": "constexpr float LLR_FEEDBACK_CONFIDENT_MIN = 3.0f;" }, { "line": 27, "text": "constexpr float LLR_FEEDBACK_UNCERTAIN_MAX = 1.0f;" }, { "line": 28, "text": "constexpr float LLR_FEEDBACK_CONFIDENT_BOOST = 1.2f;" }, { "line": 29, "text": "constexpr float LLR_FEEDBACK_UNCERTAIN_SHRINK = 0.5f;" }, { "line": 30, "text": "constexpr float LLR_FEEDBACK_MAX_MAG = 6.0f;" }, { "line": 31, "text": "constexpr int LDPC_FEEDBACK_MAX_PASSES_DEFAULT = 8;" }, { "line": 32, "text": "" }, { "line": 33, "text": "inline float llrErasureThreshold() {" }, { "line": 34, "text": " float threshold = LLR_ERASURE_THRESHOLD_DEFAULT;" }, { "line": 35, "text": "" }, { "line": 36, "text": " if (auto const env = std::getenv(\"JS8_LLR_ERASURE_THRESH\"); env) {" }, { "line": 37, "text": " char *end = nullptr;" } ] } }, { "line": 36, "matches": [ "LLR" ], "snippet": { "start_line": 30, "end_line": 42, "lines": [ { "line": 30, "text": "constexpr float LLR_FEEDBACK_MAX_MAG = 6.0f;" }, { "line": 31, "text": "constexpr int LDPC_FEEDBACK_MAX_PASSES_DEFAULT = 8;" }, { "line": 32, "text": "" }, { "line": 33, "text": "inline float llrErasureThreshold() {" }, { "line": 34, "text": " float threshold = LLR_ERASURE_THRESHOLD_DEFAULT;" }, { "line": 35, "text": "" }, { "line": 36, "text": " if (auto const env = std::getenv(\"JS8_LLR_ERASURE_THRESH\"); env) {" }, { "line": 37, "text": " char *end = nullptr;" }, { "line": 38, "text": " float val = std::strtof(env, &end);" }, { "line": 39, "text": "" }, { "line": 40, "text": " if (end != env && std::isfinite(val)) {" }, { "line": 41, "text": " threshold = val;" }, { "line": 42, "text": " }" } ] } }, { "line": 53, "matches": [ "ldpc" ], "snippet": { "start_line": 47, "end_line": 59, "lines": [ { "line": 47, "text": " return 0.0f;" }, { "line": 48, "text": " }" }, { "line": 49, "text": "" }, { "line": 50, "text": " return threshold;" }, { "line": 51, "text": "}" }, { "line": 52, "text": "" }, { "line": 53, "text": "inline bool ldpcFeedbackEnabled() {" }, { "line": 54, "text": " bool ok = false;" }, { "line": 55, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_FEEDBACK\", &ok);" }, { "line": 56, "text": " return ok ? value != 0 : true;" }, { "line": 57, "text": "}" }, { "line": 58, "text": "" }, { "line": 59, "text": "inline int ldpcFeedbackMaxPasses() {" } ] } }, { "line": 59, "matches": [ "ldpc" ], "snippet": { "start_line": 53, "end_line": 65, "lines": [ { "line": 53, "text": "inline bool ldpcFeedbackEnabled() {" }, { "line": 54, "text": " bool ok = false;" }, { "line": 55, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_FEEDBACK\", &ok);" }, { "line": 56, "text": " return ok ? value != 0 : true;" }, { "line": 57, "text": "}" }, { "line": 58, "text": "" }, { "line": 59, "text": "inline int ldpcFeedbackMaxPasses() {" }, { "line": 60, "text": " bool ok = false;" }, { "line": 61, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_MAX_PASSES\", &ok);" }, { "line": 62, "text": "" }, { "line": 63, "text": " if (!ok)" }, { "line": 64, "text": " return LDPC_FEEDBACK_MAX_PASSES_DEFAULT;" }, { "line": 65, "text": "" } ] } }, { "line": 61, "matches": [ "ldpc" ], "snippet": { "start_line": 55, "end_line": 67, "lines": [ { "line": 55, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_FEEDBACK\", &ok);" }, { "line": 56, "text": " return ok ? value != 0 : true;" }, { "line": 57, "text": "}" }, { "line": 58, "text": "" }, { "line": 59, "text": "inline int ldpcFeedbackMaxPasses() {" }, { "line": 60, "text": " bool ok = false;" }, { "line": 61, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_MAX_PASSES\", &ok);" }, { "line": 62, "text": "" }, { "line": 63, "text": " if (!ok)" }, { "line": 64, "text": " return LDPC_FEEDBACK_MAX_PASSES_DEFAULT;" }, { "line": 65, "text": "" }, { "line": 66, "text": " return std::clamp(value, 1, LDPC_FEEDBACK_MAX_PASSES_DEFAULT);" }, { "line": 67, "text": "}" } ] } }, { "line": 66, "matches": [ "ldpc" ], "snippet": { "start_line": 60, "end_line": 72, "lines": [ { "line": 60, "text": " bool ok = false;" }, { "line": 61, "text": " int value = qEnvironmentVariableIntValue(\"JS8_LDPC_MAX_PASSES\", &ok);" }, { "line": 62, "text": "" }, { "line": 63, "text": " if (!ok)" }, { "line": 64, "text": " return LDPC_FEEDBACK_MAX_PASSES_DEFAULT;" }, { "line": 65, "text": "" }, { "line": 66, "text": " return std::clamp(value, 1, LDPC_FEEDBACK_MAX_PASSES_DEFAULT);" }, { "line": 67, "text": "}" }, { "line": 68, "text": "" }, { "line": 69, "text": "template " }, { "line": 70, "text": "void refineLlrsWithLdpcFeedback(std::array const &llrIn," }, { "line": 71, "text": " std::array const &cw," }, { "line": 72, "text": " float erasureThreshold," } ] } }, { "line": 73, "matches": [ "LLR" ], "snippet": { "start_line": 67, "end_line": 79, "lines": [ { "line": 67, "text": "}" }, { "line": 68, "text": "" }, { "line": 69, "text": "template " }, { "line": 70, "text": "void refineLlrsWithLdpcFeedback(std::array const &llrIn," }, { "line": 71, "text": " std::array const &cw," }, { "line": 72, "text": " float erasureThreshold," }, { "line": 73, "text": " std::array &llrOut," }, { "line": 74, "text": " int &confidentCount, int &uncertainCount) {" }, { "line": 75, "text": " llrOut = llrIn;" }, { "line": 76, "text": " confidentCount = 0;" }, { "line": 77, "text": " uncertainCount = 0;" }, { "line": 78, "text": "" }, { "line": 79, "text": " for (std::size_t i = 0; i < llrOut.size(); ++i) {" } ] } }, { "line": 79, "matches": [ "LLR" ], "snippet": { "start_line": 73, "end_line": 85, "lines": [ { "line": 73, "text": " std::array &llrOut," }, { "line": 74, "text": " int &confidentCount, int &uncertainCount) {" }, { "line": 75, "text": " llrOut = llrIn;" }, { "line": 76, "text": " confidentCount = 0;" }, { "line": 77, "text": " uncertainCount = 0;" }, { "line": 78, "text": "" }, { "line": 79, "text": " for (std::size_t i = 0; i < llrOut.size(); ++i) {" }, { "line": 80, "text": " float &value = llrOut[i];" }, { "line": 81, "text": "" }, { "line": 82, "text": " if (!std::isfinite(value)) {" }, { "line": 83, "text": " value = 0.0f;" }, { "line": 84, "text": " ++uncertainCount;" }, { "line": 85, "text": " continue;" } ] } }, { "line": 92, "matches": [ "LLR" ], "snippet": { "start_line": 86, "end_line": 98, "lines": [ { "line": 86, "text": " }" }, { "line": 87, "text": "" }, { "line": 88, "text": " bool const bitOne = cw[i] != 0;" }, { "line": 89, "text": " float const mag = std::abs(value);" }, { "line": 90, "text": " bool const signMatch = (value >= 0.0f) == bitOne;" }, { "line": 91, "text": "" }, { "line": 92, "text": " if (signMatch && mag >= LLR_FEEDBACK_CONFIDENT_MIN) {" }, { "line": 93, "text": " ++confidentCount;" }, { "line": 94, "text": " float boosted = mag * LLR_FEEDBACK_CONFIDENT_BOOST;" }, { "line": 95, "text": " boosted = std::clamp(boosted, 0.0f, LLR_FEEDBACK_MAX_MAG);" }, { "line": 96, "text": " value = bitOne ? boosted : -boosted;" }, { "line": 97, "text": " } else if (!signMatch || mag <= LLR_FEEDBACK_UNCERTAIN_MAX) {" }, { "line": 98, "text": " ++uncertainCount;" } ] } }, { "line": 97, "matches": [ "LLR" ], "snippet": { "start_line": 91, "end_line": 103, "lines": [ { "line": 91, "text": "" }, { "line": 92, "text": " if (signMatch && mag >= LLR_FEEDBACK_CONFIDENT_MIN) {" }, { "line": 93, "text": " ++confidentCount;" }, { "line": 94, "text": " float boosted = mag * LLR_FEEDBACK_CONFIDENT_BOOST;" }, { "line": 95, "text": " boosted = std::clamp(boosted, 0.0f, LLR_FEEDBACK_MAX_MAG);" }, { "line": 96, "text": " value = bitOne ? boosted : -boosted;" }, { "line": 97, "text": " } else if (!signMatch || mag <= LLR_FEEDBACK_UNCERTAIN_MAX) {" }, { "line": 98, "text": " ++uncertainCount;" }, { "line": 99, "text": " float shrunk = mag * LLR_FEEDBACK_UNCERTAIN_SHRINK;" }, { "line": 100, "text": "" }, { "line": 101, "text": " if (erasureThreshold > 0.0f && shrunk < erasureThreshold) {" }, { "line": 102, "text": " value = 0.0f;" }, { "line": 103, "text": " } else {" } ] } } ] }, { "path": "JS8_Mode/DecodedText.cpp", "exists": true, "bytes": 10173, "sha256": "1f3d3a687a0bae5ad690bceb93b80b5854dfdfd00b1fd16487acfc83e7faf65c", "line_count": 344, "phase_hits": { "timing_submode": 0, "symbol_to_soft_bits": 0, "bit_order_interleaver": 24, "whitening_erasure": 0, "ldpc_decode": 0, "message91_crc_text": 108 }, "function_blocks": [ { "function": "submodeChar", "line": 33, "signature": "QChar submodeChar(int const submode) {", "snippet": { "start_line": 19, "end_line": 47, "lines": [ { "line": 19, "text": "// denote it as being sketchy." }, { "line": 20, "text": "" }, { "line": 21, "text": "constexpr auto QUALITY_THRESHOLD = 0.17f;" }, { "line": 22, "text": "} // namespace" }, { "line": 23, "text": "" }, { "line": 24, "text": "/******************************************************************************/" }, { "line": 25, "text": "// Local Routines" }, { "line": 26, "text": "/******************************************************************************/" }, { "line": 27, "text": "" }, { "line": 28, "text": "namespace {" }, { "line": 29, "text": "// Translation of standard submode IDs to their character equivalents." }, { "line": 30, "text": "// this is only used when writing out to ALL.TXT, so we've defined it" }, { "line": 31, "text": "// here, but arguably it should be part of JS8::Submode or Varicode." }, { "line": 32, "text": "" }, { "line": 33, "text": "QChar submodeChar(int const submode) {" }, { "line": 34, "text": " switch (submode) {" }, { "line": 35, "text": " case Varicode::SubmodeType::JS8CallNormal:" }, { "line": 36, "text": " return 'A';" }, { "line": 37, "text": " case Varicode::SubmodeType::JS8CallFast:" }, { "line": 38, "text": " return 'B';" }, { "line": 39, "text": " case Varicode::SubmodeType::JS8CallTurbo:" }, { "line": 40, "text": " return 'C';" }, { "line": 41, "text": " case Varicode::SubmodeType::JS8CallSlow:" }, { "line": 42, "text": " return 'E';" }, { "line": 43, "text": " case Varicode::SubmodeType::JS8CallUltra:" }, { "line": 44, "text": " return 'I';" }, { "line": 45, "text": " default:" }, { "line": 46, "text": " return '~';" }, { "line": 47, "text": " }" } ] } }, { "function": "buildCompound", "line": 54, "signature": "QString buildCompound(QStringList const &parts) {", "snippet": { "start_line": 40, "end_line": 68, "lines": [ { "line": 40, "text": " return 'C';" }, { "line": 41, "text": " case Varicode::SubmodeType::JS8CallSlow:" }, { "line": 42, "text": " return 'E';" }, { "line": 43, "text": " case Varicode::SubmodeType::JS8CallUltra:" }, { "line": 44, "text": " return 'I';" }, { "line": 45, "text": " default:" }, { "line": 46, "text": " return '~';" }, { "line": 47, "text": " }" }, { "line": 48, "text": "}" }, { "line": 49, "text": "" }, { "line": 50, "text": "// Create and return a potentially compound call from the provided" }, { "line": 51, "text": "// parts; the parts are at this point guaranteed to be at least of" }, { "line": 52, "text": "// size 2, but any part might be empty." }, { "line": 53, "text": "" }, { "line": 54, "text": "QString buildCompound(QStringList const &parts) {" }, { "line": 55, "text": " auto subset = parts.mid(0, 2);" }, { "line": 56, "text": " subset.removeAll(\"\");" }, { "line": 57, "text": " return subset.join('/');" }, { "line": 58, "text": "}" }, { "line": 59, "text": "} // namespace" }, { "line": 60, "text": "" }, { "line": 61, "text": "/******************************************************************************/" }, { "line": 62, "text": "// Private Implementation" }, { "line": 63, "text": "/******************************************************************************/" }, { "line": 64, "text": "" }, { "line": 65, "text": "// Core constructor, called by the two public constructors." }, { "line": 66, "text": "// Attempts to unpack, using the unpack strategies defined" }, { "line": 67, "text": "// in the order of the unpack strategies array, until one" }, { "line": 68, "text": "// of them works or all of them have failed." } ] } }, { "function": "DecodedText::tryUnpackFastData", "line": 109, "signature": "bool DecodedText::tryUnpackFastData(QString const &m) {", "snippet": { "start_line": 95, "end_line": 123, "lines": [ { "line": 95, "text": " for (auto unpack : unpackStrategies) {" }, { "line": 96, "text": " if ((this->*unpack)(m))" }, { "line": 97, "text": " break;" }, { "line": 98, "text": " }" }, { "line": 99, "text": "}" }, { "line": 100, "text": "" }, { "line": 101, "text": "/**" }, { "line": 102, "text": " * @private" }, { "line": 103, "text": " * @brief Try to unpack fast data message (private)" }, { "line": 104, "text": " *" }, { "line": 105, "text": " * @param m" }, { "line": 106, "text": " * @return true" }, { "line": 107, "text": " * @return false" }, { "line": 108, "text": " */" }, { "line": 109, "text": "bool DecodedText::tryUnpackFastData(QString const &m) {" }, { "line": 110, "text": " if ((bits_ & Varicode::JS8CallData) != Varicode::JS8CallData)" }, { "line": 111, "text": " return false;" }, { "line": 112, "text": "" }, { "line": 113, "text": " if (auto const data = Varicode::unpackFastDataMessage(m); data.isEmpty()) {" }, { "line": 114, "text": " return false;" }, { "line": 115, "text": " } else {" }, { "line": 116, "text": " message_ = data;" }, { "line": 117, "text": " frameType_ = Varicode::FrameData;" }, { "line": 118, "text": "" }, { "line": 119, "text": " return true;" }, { "line": 120, "text": " }" }, { "line": 121, "text": "}" }, { "line": 122, "text": "" }, { "line": 123, "text": "/**" } ] } }, { "function": "DecodedText::tryUnpackData", "line": 131, "signature": "bool DecodedText::tryUnpackData(QString const &m) {", "snippet": { "start_line": 117, "end_line": 145, "lines": [ { "line": 117, "text": " frameType_ = Varicode::FrameData;" }, { "line": 118, "text": "" }, { "line": 119, "text": " return true;" }, { "line": 120, "text": " }" }, { "line": 121, "text": "}" }, { "line": 122, "text": "" }, { "line": 123, "text": "/**" }, { "line": 124, "text": " * @private" }, { "line": 125, "text": " * @brief Try to unpack data message (private)" }, { "line": 126, "text": " *" }, { "line": 127, "text": " * @param m" }, { "line": 128, "text": " * @return true" }, { "line": 129, "text": " * @return false" }, { "line": 130, "text": " */" }, { "line": 131, "text": "bool DecodedText::tryUnpackData(QString const &m) {" }, { "line": 132, "text": " if ((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData)" }, { "line": 133, "text": " return false;" }, { "line": 134, "text": "" }, { "line": 135, "text": " if (auto const data = Varicode::unpackDataMessage(m); data.isEmpty()) {" }, { "line": 136, "text": " return false;" }, { "line": 137, "text": " } else {" }, { "line": 138, "text": " message_ = data;" }, { "line": 139, "text": " frameType_ = Varicode::FrameData;" }, { "line": 140, "text": "" }, { "line": 141, "text": " return true;" }, { "line": 142, "text": " }" }, { "line": 143, "text": "}" }, { "line": 144, "text": "" }, { "line": 145, "text": "/**" } ] } }, { "function": "DecodedText::tryUnpackHeartbeat", "line": 153, "signature": "bool DecodedText::tryUnpackHeartbeat(QString const &m) {", "snippet": { "start_line": 139, "end_line": 167, "lines": [ { "line": 139, "text": " frameType_ = Varicode::FrameData;" }, { "line": 140, "text": "" }, { "line": 141, "text": " return true;" }, { "line": 142, "text": " }" }, { "line": 143, "text": "}" }, { "line": 144, "text": "" }, { "line": 145, "text": "/**" }, { "line": 146, "text": " * @private" }, { "line": 147, "text": " * @brief Try to unpack heartbeat message (private)" }, { "line": 148, "text": " *" }, { "line": 149, "text": " * @param m" }, { "line": 150, "text": " * @return true" }, { "line": 151, "text": " * @return false" }, { "line": 152, "text": " */" }, { "line": 153, "text": "bool DecodedText::tryUnpackHeartbeat(QString const &m) {" }, { "line": 154, "text": " if ((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData)" }, { "line": 155, "text": " return false;" }, { "line": 156, "text": "" }, { "line": 157, "text": " bool isAlt = false;" }, { "line": 158, "text": " quint8 type = Varicode::FrameUnknown;" }, { "line": 159, "text": " quint8 bits3 = 0;" }, { "line": 160, "text": " auto const parts =" }, { "line": 161, "text": " Varicode::unpackHeartbeatMessage(m, &type, &isAlt, &bits3);" }, { "line": 162, "text": "" }, { "line": 163, "text": " if (parts.length() < 2)" }, { "line": 164, "text": " return false;" }, { "line": 165, "text": "" }, { "line": 166, "text": " // Heartbeat Alt Type" }, { "line": 167, "text": " // ------------------" } ] } }, { "function": "DecodedText::tryUnpackCompound", "line": 198, "signature": "bool DecodedText::tryUnpackCompound(QString const &m) {", "snippet": { "start_line": 184, "end_line": 212, "lines": [ { "line": 184, "text": "" }, { "line": 185, "text": " message_ += ' ' % extra_ % ' ';" }, { "line": 186, "text": "" }, { "line": 187, "text": " return true;" }, { "line": 188, "text": "}" }, { "line": 189, "text": "" }, { "line": 190, "text": "/**" }, { "line": 191, "text": " * @private" }, { "line": 192, "text": " * @brief Try to unpack compound message (private)" }, { "line": 193, "text": " *" }, { "line": 194, "text": " * @param m" }, { "line": 195, "text": " * @return true" }, { "line": 196, "text": " * @return false" }, { "line": 197, "text": " */" }, { "line": 198, "text": "bool DecodedText::tryUnpackCompound(QString const &m) {" }, { "line": 199, "text": " quint8 type = Varicode::FrameUnknown;" }, { "line": 200, "text": " quint8 bits3 = 0;" }, { "line": 201, "text": " auto const parts = Varicode::unpackCompoundMessage(m, &type, &bits3);" }, { "line": 202, "text": "" }, { "line": 203, "text": " if (parts.length() < 2 ||" }, { "line": 204, "text": " (bits_ & Varicode::JS8CallData) == Varicode::JS8CallData)" }, { "line": 205, "text": " return false;" }, { "line": 206, "text": "" }, { "line": 207, "text": " frameType_ = type;" }, { "line": 208, "text": " extra_ = parts.mid(2).join(' ');" }, { "line": 209, "text": " compound_ = buildCompound(parts);" }, { "line": 210, "text": "" }, { "line": 211, "text": " if (type == Varicode::FrameCompound) {" }, { "line": 212, "text": " message_ = compound_ % \": \";" } ] } }, { "function": "DecodedText::tryUnpackDirected", "line": 232, "signature": "bool DecodedText::tryUnpackDirected(QString const &m) {", "snippet": { "start_line": 218, "end_line": 246, "lines": [ { "line": 218, "text": " directed_ += parts.mid(2);" }, { "line": 219, "text": " }" }, { "line": 220, "text": "" }, { "line": 221, "text": " return true;" }, { "line": 222, "text": "}" }, { "line": 223, "text": "" }, { "line": 224, "text": "/**" }, { "line": 225, "text": " * @private" }, { "line": 226, "text": " * @brief Try to unpack directed message (private)" }, { "line": 227, "text": " *" }, { "line": 228, "text": " * @param m" }, { "line": 229, "text": " * @return true" }, { "line": 230, "text": " * @return false" }, { "line": 231, "text": " */" }, { "line": 232, "text": "bool DecodedText::tryUnpackDirected(QString const &m) {" }, { "line": 233, "text": " if ((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData)" }, { "line": 234, "text": " return false;" }, { "line": 235, "text": "" }, { "line": 236, "text": " quint8 type = Varicode::FrameUnknown;" }, { "line": 237, "text": " QStringList const parts = Varicode::unpackDirectedMessage(m, &type);" }, { "line": 238, "text": "" }, { "line": 239, "text": " if (parts.isEmpty())" }, { "line": 240, "text": " return false;" }, { "line": 241, "text": "" }, { "line": 242, "text": " switch (parts.length()) {" }, { "line": 243, "text": " case 3: // Directed message => \"0: 12 \"" }, { "line": 244, "text": " case 4: // Directed numeric message => \"0: 12 3 \"" }, { "line": 245, "text": " message_ =" }, { "line": 246, "text": " parts.at(0) % \": \" % parts.at(1) % parts.mid(2).join(' ') % ' ';" } ] } }, { "function": "DecodedText::messageWords", "line": 305, "signature": "QStringList DecodedText::messageWords() const {", "snippet": { "start_line": 291, "end_line": 319, "lines": [ { "line": 291, "text": " */" }, { "line": 292, "text": "DecodedText::DecodedText(QString const &frame, int const bits," }, { "line": 293, "text": " int const submode)" }, { "line": 294, "text": " : DecodedText(frame, bits, submode, false, 0, 0, 0.0f, 0.0f) {}" }, { "line": 295, "text": "" }, { "line": 296, "text": "// Simple word split for free text messages; preallocate memory for" }, { "line": 297, "text": "// efficiency; add whole message as item 0 to mimic regular expression" }, { "line": 298, "text": "// capture list." }, { "line": 299, "text": "" }, { "line": 300, "text": "/**" }, { "line": 301, "text": " * @brief Get the message words" }, { "line": 302, "text": " *" }, { "line": 303, "text": " * @return QStringList" }, { "line": 304, "text": " */" }, { "line": 305, "text": "QStringList DecodedText::messageWords() const {" }, { "line": 306, "text": " QStringList words;" }, { "line": 307, "text": "" }, { "line": 308, "text": " words.reserve(message_.count(' ') + 2);" }, { "line": 309, "text": " words.append(message_);" }, { "line": 310, "text": " words.append(message_.split(' ', Qt::SkipEmptyParts));" }, { "line": 311, "text": "" }, { "line": 312, "text": " return words;" }, { "line": 313, "text": "}" }, { "line": 314, "text": "" }, { "line": 315, "text": "// Format as a string suitable for appending to ALL.TXT. Original" }, { "line": 316, "text": "// code has no space between time and SNR; matching that here." }, { "line": 317, "text": "" }, { "line": 318, "text": "/**" }, { "line": 319, "text": " * @brief Get the string representation suitable for ALL.TXT" } ] } }, { "function": "DecodedText::string", "line": 323, "signature": "QString DecodedText::string() const {", "snippet": { "start_line": 309, "end_line": 337, "lines": [ { "line": 309, "text": " words.append(message_);" }, { "line": 310, "text": " words.append(message_.split(' ', Qt::SkipEmptyParts));" }, { "line": 311, "text": "" }, { "line": 312, "text": " return words;" }, { "line": 313, "text": "}" }, { "line": 314, "text": "" }, { "line": 315, "text": "// Format as a string suitable for appending to ALL.TXT. Original" }, { "line": 316, "text": "// code has no space between time and SNR; matching that here." }, { "line": 317, "text": "" }, { "line": 318, "text": "/**" }, { "line": 319, "text": " * @brief Get the string representation suitable for ALL.TXT" }, { "line": 320, "text": " *" }, { "line": 321, "text": " * @return QString" }, { "line": 322, "text": " */" }, { "line": 323, "text": "QString DecodedText::string() const {" }, { "line": 324, "text": " struct hour_minute_second hms = decode_time(time_);" }, { "line": 325, "text": "" }, { "line": 326, "text": " return QStringLiteral(\"%1:%2:%3%4 %5 %6 %7 %8 %9 \")" }, { "line": 327, "text": " .arg(hms.hour, 2, 10, QChar('0')) // Right-aligned integer with 2" }, { "line": 328, "text": " // characters, padded with zeroes." }, { "line": 329, "text": " .arg(hms.minute, 2, 10, QChar('0')) // Right-aligned integer with 2" }, { "line": 330, "text": " // characters, padded with zeroes." }, { "line": 331, "text": " .arg(hms.second, 2, 10, QChar('0')) // Right-aligned integer with 2" }, { "line": 332, "text": " // characters, padded with zeroes." }, { "line": 333, "text": " .arg(snr_, 3, 10, QChar(' ')) // Right-aligned integer with 3" }, { "line": 334, "text": " // characters, padded with spaces" }, { "line": 335, "text": " .arg(dt_, 4, 'f', 1) // Right-aligned float with 1 decimal point" }, { "line": 336, "text": " .arg(frequencyOffset_, 4, 10," }, { "line": 337, "text": " QChar(' ')) // Right-aligned integer with 4 characters, passed with" } ] } } ], "keyword_snippets": [ { "line": 2, "matches": [ "DecodedText", "text" ], "snippet": { "start_line": 1, "end_line": 8, "lines": [ { "line": 1, "text": "/**" }, { "line": 2, "text": " * @file DecodedText.cpp" }, { "line": 3, "text": " * @brief Implementation of DecodedText class" }, { "line": 4, "text": " */" }, { "line": 5, "text": "" }, { "line": 6, "text": "#include \"DecodedText.h\"" }, { "line": 7, "text": "#include \"JS8_Include/commons.h\"" }, { "line": 8, "text": "#include " } ] } }, { "line": 6, "matches": [ "DecodedText", "text" ], "snippet": { "start_line": 1, "end_line": 12, "lines": [ { "line": 1, "text": "/**" }, { "line": 2, "text": " * @file DecodedText.cpp" }, { "line": 3, "text": " * @brief Implementation of DecodedText class" }, { "line": 4, "text": " */" }, { "line": 5, "text": "" }, { "line": 6, "text": "#include \"DecodedText.h\"" }, { "line": 7, "text": "#include \"JS8_Include/commons.h\"" }, { "line": 8, "text": "#include " }, { "line": 9, "text": "" }, { "line": 10, "text": "#include " }, { "line": 11, "text": "" }, { "line": 12, "text": "/******************************************************************************/" } ] } }, { "line": 31, "matches": [ "Varicode" ], "snippet": { "start_line": 25, "end_line": 37, "lines": [ { "line": 25, "text": "// Local Routines" }, { "line": 26, "text": "/******************************************************************************/" }, { "line": 27, "text": "" }, { "line": 28, "text": "namespace {" }, { "line": 29, "text": "// Translation of standard submode IDs to their character equivalents." }, { "line": 30, "text": "// this is only used when writing out to ALL.TXT, so we've defined it" }, { "line": 31, "text": "// here, but arguably it should be part of JS8::Submode or Varicode." }, { "line": 32, "text": "" }, { "line": 33, "text": "QChar submodeChar(int const submode) {" }, { "line": 34, "text": " switch (submode) {" }, { "line": 35, "text": " case Varicode::SubmodeType::JS8CallNormal:" }, { "line": 36, "text": " return 'A';" }, { "line": 37, "text": " case Varicode::SubmodeType::JS8CallFast:" } ] } }, { "line": 37, "matches": [ "Varicode" ], "snippet": { "start_line": 31, "end_line": 43, "lines": [ { "line": 31, "text": "// here, but arguably it should be part of JS8::Submode or Varicode." }, { "line": 32, "text": "" }, { "line": 33, "text": "QChar submodeChar(int const submode) {" }, { "line": 34, "text": " switch (submode) {" }, { "line": 35, "text": " case Varicode::SubmodeType::JS8CallNormal:" }, { "line": 36, "text": " return 'A';" }, { "line": 37, "text": " case Varicode::SubmodeType::JS8CallFast:" }, { "line": 38, "text": " return 'B';" }, { "line": 39, "text": " case Varicode::SubmodeType::JS8CallTurbo:" }, { "line": 40, "text": " return 'C';" }, { "line": 41, "text": " case Varicode::SubmodeType::JS8CallSlow:" }, { "line": 42, "text": " return 'E';" }, { "line": 43, "text": " case Varicode::SubmodeType::JS8CallUltra:" } ] } }, { "line": 41, "matches": [ "Varicode" ], "snippet": { "start_line": 35, "end_line": 47, "lines": [ { "line": 35, "text": " case Varicode::SubmodeType::JS8CallNormal:" }, { "line": 36, "text": " return 'A';" }, { "line": 37, "text": " case Varicode::SubmodeType::JS8CallFast:" }, { "line": 38, "text": " return 'B';" }, { "line": 39, "text": " case Varicode::SubmodeType::JS8CallTurbo:" }, { "line": 40, "text": " return 'C';" }, { "line": 41, "text": " case Varicode::SubmodeType::JS8CallSlow:" }, { "line": 42, "text": " return 'E';" }, { "line": 43, "text": " case Varicode::SubmodeType::JS8CallUltra:" }, { "line": 44, "text": " return 'I';" }, { "line": 45, "text": " default:" }, { "line": 46, "text": " return '~';" }, { "line": 47, "text": " }" } ] } }, { "line": 66, "matches": [ "unpack" ], "snippet": { "start_line": 60, "end_line": 72, "lines": [ { "line": 60, "text": "" }, { "line": 61, "text": "/******************************************************************************/" }, { "line": 62, "text": "// Private Implementation" }, { "line": 63, "text": "/******************************************************************************/" }, { "line": 64, "text": "" }, { "line": 65, "text": "// Core constructor, called by the two public constructors." }, { "line": 66, "text": "// Attempts to unpack, using the unpack strategies defined" }, { "line": 67, "text": "// in the order of the unpack strategies array, until one" }, { "line": 68, "text": "// of them works or all of them have failed." }, { "line": 69, "text": "" }, { "line": 70, "text": "/**" }, { "line": 71, "text": " * @private" }, { "line": 72, "text": " * @brief Construct a new Decoded Text:: Decoded Text object (private)" } ] } }, { "line": 72, "matches": [ "text" ], "snippet": { "start_line": 66, "end_line": 78, "lines": [ { "line": 66, "text": "// Attempts to unpack, using the unpack strategies defined" }, { "line": 67, "text": "// in the order of the unpack strategies array, until one" }, { "line": 68, "text": "// of them works or all of them have failed." }, { "line": 69, "text": "" }, { "line": 70, "text": "/**" }, { "line": 71, "text": " * @private" }, { "line": 72, "text": " * @brief Construct a new Decoded Text:: Decoded Text object (private)" }, { "line": 73, "text": " *" }, { "line": 74, "text": " * @param frame" }, { "line": 75, "text": " * @param bits" }, { "line": 76, "text": " * @param submode" }, { "line": 77, "text": " * @param isLowConfidence" }, { "line": 78, "text": " * @param time" } ] } }, { "line": 83, "matches": [ "DecodedText", "text" ], "snippet": { "start_line": 77, "end_line": 89, "lines": [ { "line": 77, "text": " * @param isLowConfidence" }, { "line": 78, "text": " * @param time" }, { "line": 79, "text": " * @param frequencyOffset" }, { "line": 80, "text": " * @param snr" }, { "line": 81, "text": " * @param dt" }, { "line": 82, "text": " */" }, { "line": 83, "text": "DecodedText::DecodedText(QString const &frame, int bits, int submode," }, { "line": 84, "text": " bool isLowConfidence, int time, int frequencyOffset," }, { "line": 85, "text": " float snr, float dt)" }, { "line": 86, "text": " : frameType_(Varicode::FrameUnknown), frame_(frame), isAlt_(false)," }, { "line": 87, "text": " isHeartbeat_(false), isLowConfidence_(isLowConfidence), message_(frame_)," }, { "line": 88, "text": " bits_(bits), submode_(submode), time_(time)," }, { "line": 89, "text": " frequencyOffset_(frequencyOffset), snr_(snr), dt_(dt) {" } ] } }, { "line": 86, "matches": [ "Varicode" ], "snippet": { "start_line": 80, "end_line": 92, "lines": [ { "line": 80, "text": " * @param snr" }, { "line": 81, "text": " * @param dt" }, { "line": 82, "text": " */" }, { "line": 83, "text": "DecodedText::DecodedText(QString const &frame, int bits, int submode," }, { "line": 84, "text": " bool isLowConfidence, int time, int frequencyOffset," }, { "line": 85, "text": " float snr, float dt)" }, { "line": 86, "text": " : frameType_(Varicode::FrameUnknown), frame_(frame), isAlt_(false)," }, { "line": 87, "text": " isHeartbeat_(false), isLowConfidence_(isLowConfidence), message_(frame_)," }, { "line": 88, "text": " bits_(bits), submode_(submode), time_(time)," }, { "line": 89, "text": " frequencyOffset_(frequencyOffset), snr_(snr), dt_(dt) {" }, { "line": 90, "text": " auto const m = message().trimmed();" }, { "line": 91, "text": "" }, { "line": 92, "text": " if (m.length() < 12 || m.contains(' '))" } ] } }, { "line": 95, "matches": [ "unpack" ], "snippet": { "start_line": 89, "end_line": 101, "lines": [ { "line": 89, "text": " frequencyOffset_(frequencyOffset), snr_(snr), dt_(dt) {" }, { "line": 90, "text": " auto const m = message().trimmed();" }, { "line": 91, "text": "" }, { "line": 92, "text": " if (m.length() < 12 || m.contains(' '))" }, { "line": 93, "text": " return;" }, { "line": 94, "text": "" }, { "line": 95, "text": " for (auto unpack : unpackStrategies) {" }, { "line": 96, "text": " if ((this->*unpack)(m))" }, { "line": 97, "text": " break;" }, { "line": 98, "text": " }" }, { "line": 99, "text": "}" }, { "line": 100, "text": "" }, { "line": 101, "text": "/**" } ] } }, { "line": 96, "matches": [ "unpack" ], "snippet": { "start_line": 90, "end_line": 102, "lines": [ { "line": 90, "text": " auto const m = message().trimmed();" }, { "line": 91, "text": "" }, { "line": 92, "text": " if (m.length() < 12 || m.contains(' '))" }, { "line": 93, "text": " return;" }, { "line": 94, "text": "" }, { "line": 95, "text": " for (auto unpack : unpackStrategies) {" }, { "line": 96, "text": " if ((this->*unpack)(m))" }, { "line": 97, "text": " break;" }, { "line": 98, "text": " }" }, { "line": 99, "text": "}" }, { "line": 100, "text": "" }, { "line": 101, "text": "/**" }, { "line": 102, "text": " * @private" } ] } }, { "line": 103, "matches": [ "message", "unpack" ], "snippet": { "start_line": 97, "end_line": 109, "lines": [ { "line": 97, "text": " break;" }, { "line": 98, "text": " }" }, { "line": 99, "text": "}" }, { "line": 100, "text": "" }, { "line": 101, "text": "/**" }, { "line": 102, "text": " * @private" }, { "line": 103, "text": " * @brief Try to unpack fast data message (private)" }, { "line": 104, "text": " *" }, { "line": 105, "text": " * @param m" }, { "line": 106, "text": " * @return true" }, { "line": 107, "text": " * @return false" }, { "line": 108, "text": " */" }, { "line": 109, "text": "bool DecodedText::tryUnpackFastData(QString const &m) {" } ] } }, { "line": 109, "matches": [ "DecodedText", "text", "unpack" ], "snippet": { "start_line": 103, "end_line": 115, "lines": [ { "line": 103, "text": " * @brief Try to unpack fast data message (private)" }, { "line": 104, "text": " *" }, { "line": 105, "text": " * @param m" }, { "line": 106, "text": " * @return true" }, { "line": 107, "text": " * @return false" }, { "line": 108, "text": " */" }, { "line": 109, "text": "bool DecodedText::tryUnpackFastData(QString const &m) {" }, { "line": 110, "text": " if ((bits_ & Varicode::JS8CallData) != Varicode::JS8CallData)" }, { "line": 111, "text": " return false;" }, { "line": 112, "text": "" }, { "line": 113, "text": " if (auto const data = Varicode::unpackFastDataMessage(m); data.isEmpty()) {" }, { "line": 114, "text": " return false;" }, { "line": 115, "text": " } else {" } ] } }, { "line": 113, "matches": [ "message", "unpack", "Varicode" ], "snippet": { "start_line": 107, "end_line": 119, "lines": [ { "line": 107, "text": " * @return false" }, { "line": 108, "text": " */" }, { "line": 109, "text": "bool DecodedText::tryUnpackFastData(QString const &m) {" }, { "line": 110, "text": " if ((bits_ & Varicode::JS8CallData) != Varicode::JS8CallData)" }, { "line": 111, "text": " return false;" }, { "line": 112, "text": "" }, { "line": 113, "text": " if (auto const data = Varicode::unpackFastDataMessage(m); data.isEmpty()) {" }, { "line": 114, "text": " return false;" }, { "line": 115, "text": " } else {" }, { "line": 116, "text": " message_ = data;" }, { "line": 117, "text": " frameType_ = Varicode::FrameData;" }, { "line": 118, "text": "" }, { "line": 119, "text": " return true;" } ] } }, { "line": 116, "matches": [ "message" ], "snippet": { "start_line": 110, "end_line": 122, "lines": [ { "line": 110, "text": " if ((bits_ & Varicode::JS8CallData) != Varicode::JS8CallData)" }, { "line": 111, "text": " return false;" }, { "line": 112, "text": "" }, { "line": 113, "text": " if (auto const data = Varicode::unpackFastDataMessage(m); data.isEmpty()) {" }, { "line": 114, "text": " return false;" }, { "line": 115, "text": " } else {" }, { "line": 116, "text": " message_ = data;" }, { "line": 117, "text": " frameType_ = Varicode::FrameData;" }, { "line": 118, "text": "" }, { "line": 119, "text": " return true;" }, { "line": 120, "text": " }" }, { "line": 121, "text": "}" }, { "line": 122, "text": "" } ] } }, { "line": 125, "matches": [ "message", "unpack" ], "snippet": { "start_line": 119, "end_line": 131, "lines": [ { "line": 119, "text": " return true;" }, { "line": 120, "text": " }" }, { "line": 121, "text": "}" }, { "line": 122, "text": "" }, { "line": 123, "text": "/**" }, { "line": 124, "text": " * @private" }, { "line": 125, "text": " * @brief Try to unpack data message (private)" }, { "line": 126, "text": " *" }, { "line": 127, "text": " * @param m" }, { "line": 128, "text": " * @return true" }, { "line": 129, "text": " * @return false" }, { "line": 130, "text": " */" }, { "line": 131, "text": "bool DecodedText::tryUnpackData(QString const &m) {" } ] } }, { "line": 131, "matches": [ "DecodedText", "text", "unpack" ], "snippet": { "start_line": 125, "end_line": 137, "lines": [ { "line": 125, "text": " * @brief Try to unpack data message (private)" }, { "line": 126, "text": " *" }, { "line": 127, "text": " * @param m" }, { "line": 128, "text": " * @return true" }, { "line": 129, "text": " * @return false" }, { "line": 130, "text": " */" }, { "line": 131, "text": "bool DecodedText::tryUnpackData(QString const &m) {" }, { "line": 132, "text": " if ((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData)" }, { "line": 133, "text": " return false;" }, { "line": 134, "text": "" }, { "line": 135, "text": " if (auto const data = Varicode::unpackDataMessage(m); data.isEmpty()) {" }, { "line": 136, "text": " return false;" }, { "line": 137, "text": " } else {" } ] } }, { "line": 138, "matches": [ "message" ], "snippet": { "start_line": 132, "end_line": 144, "lines": [ { "line": 132, "text": " if ((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData)" }, { "line": 133, "text": " return false;" }, { "line": 134, "text": "" }, { "line": 135, "text": " if (auto const data = Varicode::unpackDataMessage(m); data.isEmpty()) {" }, { "line": 136, "text": " return false;" }, { "line": 137, "text": " } else {" }, { "line": 138, "text": " message_ = data;" }, { "line": 139, "text": " frameType_ = Varicode::FrameData;" }, { "line": 140, "text": "" }, { "line": 141, "text": " return true;" }, { "line": 142, "text": " }" }, { "line": 143, "text": "}" }, { "line": 144, "text": "" } ] } }, { "line": 147, "matches": [ "message", "unpack" ], "snippet": { "start_line": 141, "end_line": 153, "lines": [ { "line": 141, "text": " return true;" }, { "line": 142, "text": " }" }, { "line": 143, "text": "}" }, { "line": 144, "text": "" }, { "line": 145, "text": "/**" }, { "line": 146, "text": " * @private" }, { "line": 147, "text": " * @brief Try to unpack heartbeat message (private)" }, { "line": 148, "text": " *" }, { "line": 149, "text": " * @param m" }, { "line": 150, "text": " * @return true" }, { "line": 151, "text": " * @return false" }, { "line": 152, "text": " */" }, { "line": 153, "text": "bool DecodedText::tryUnpackHeartbeat(QString const &m) {" } ] } }, { "line": 153, "matches": [ "DecodedText", "text", "unpack" ], "snippet": { "start_line": 147, "end_line": 159, "lines": [ { "line": 147, "text": " * @brief Try to unpack heartbeat message (private)" }, { "line": 148, "text": " *" }, { "line": 149, "text": " * @param m" }, { "line": 150, "text": " * @return true" }, { "line": 151, "text": " * @return false" }, { "line": 152, "text": " */" }, { "line": 153, "text": "bool DecodedText::tryUnpackHeartbeat(QString const &m) {" }, { "line": 154, "text": " if ((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData)" }, { "line": 155, "text": " return false;" }, { "line": 156, "text": "" }, { "line": 157, "text": " bool isAlt = false;" }, { "line": 158, "text": " quint8 type = Varicode::FrameUnknown;" }, { "line": 159, "text": " quint8 bits3 = 0;" } ] } }, { "line": 158, "matches": [ "Varicode" ], "snippet": { "start_line": 152, "end_line": 164, "lines": [ { "line": 152, "text": " */" }, { "line": 153, "text": "bool DecodedText::tryUnpackHeartbeat(QString const &m) {" }, { "line": 154, "text": " if ((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData)" }, { "line": 155, "text": " return false;" }, { "line": 156, "text": "" }, { "line": 157, "text": " bool isAlt = false;" }, { "line": 158, "text": " quint8 type = Varicode::FrameUnknown;" }, { "line": 159, "text": " quint8 bits3 = 0;" }, { "line": 160, "text": " auto const parts =" }, { "line": 161, "text": " Varicode::unpackHeartbeatMessage(m, &type, &isAlt, &bits3);" }, { "line": 162, "text": "" }, { "line": 163, "text": " if (parts.length() < 2)" }, { "line": 164, "text": " return false;" } ] } }, { "line": 161, "matches": [ "message", "unpack", "Varicode" ], "snippet": { "start_line": 155, "end_line": 167, "lines": [ { "line": 155, "text": " return false;" }, { "line": 156, "text": "" }, { "line": 157, "text": " bool isAlt = false;" }, { "line": 158, "text": " quint8 type = Varicode::FrameUnknown;" }, { "line": 159, "text": " quint8 bits3 = 0;" }, { "line": 160, "text": " auto const parts =" }, { "line": 161, "text": " Varicode::unpackHeartbeatMessage(m, &type, &isAlt, &bits3);" }, { "line": 162, "text": "" }, { "line": 163, "text": " if (parts.length() < 2)" }, { "line": 164, "text": " return false;" }, { "line": 165, "text": "" }, { "line": 166, "text": " // Heartbeat Alt Type" }, { "line": 167, "text": " // ------------------" } ] } } ] }, { "path": "JS8_Main/Varicode.cpp", "exists": true, "bytes": 72661, "sha256": "2b4a877e7dae1a3fdd9141f4dd8af422185977d2e9363ad23ef6bc1918eaf53a", "line_count": 2371, "phase_hits": { "timing_submode": 0, "symbol_to_soft_bits": 0, "bit_order_interleaver": 231, "whitening_erasure": 11, "ldpc_decode": 0, "message91_crc_text": 734 }, "function_blocks": [ { "function": "mwattsToDbm", "line": 333, "signature": "int mwattsToDbm(int mwatts) {", "snippet": { "start_line": 319, "end_line": 347, "lines": [ { "line": 319, "text": " {37, 5000}, // 5W" }, { "line": 320, "text": " {40, 10000}, // 10W" }, { "line": 321, "text": " {43, 20000}, // 20W" }, { "line": 322, "text": " {47, 50000}, // 50W" }, { "line": 323, "text": " {50, 100000}, // 100W" }, { "line": 324, "text": " {53, 200000}, // 200W" }, { "line": 325, "text": " {57, 500000}, // 500W" }, { "line": 326, "text": " {60, 1000000}, // 1000W" }, { "line": 327, "text": "};" }, { "line": 328, "text": "" }, { "line": 329, "text": "/*" }, { "line": 330, "text": " * UTILITIES" }, { "line": 331, "text": " */" }, { "line": 332, "text": "" }, { "line": 333, "text": "int mwattsToDbm(int mwatts) {" }, { "line": 334, "text": " int dbm = 0;" }, { "line": 335, "text": " auto values = dbm2mw.values();" }, { "line": 336, "text": " std::sort(values.begin(), values.end());" }, { "line": 337, "text": " foreach (auto mw, values) {" }, { "line": 338, "text": " if (mw < mwatts) {" }, { "line": 339, "text": " continue;" }, { "line": 340, "text": " }" }, { "line": 341, "text": " dbm = dbm2mw.key(mw);" }, { "line": 342, "text": " break;" }, { "line": 343, "text": " }" }, { "line": 344, "text": "" }, { "line": 345, "text": " return dbm;" }, { "line": 346, "text": "}" }, { "line": 347, "text": "" } ] } }, { "function": "dbmTomwatts", "line": 348, "signature": "int dbmTomwatts(int dbm) {", "snippet": { "start_line": 334, "end_line": 362, "lines": [ { "line": 334, "text": " int dbm = 0;" }, { "line": 335, "text": " auto values = dbm2mw.values();" }, { "line": 336, "text": " std::sort(values.begin(), values.end());" }, { "line": 337, "text": " foreach (auto mw, values) {" }, { "line": 338, "text": " if (mw < mwatts) {" }, { "line": 339, "text": " continue;" }, { "line": 340, "text": " }" }, { "line": 341, "text": " dbm = dbm2mw.key(mw);" }, { "line": 342, "text": " break;" }, { "line": 343, "text": " }" }, { "line": 344, "text": "" }, { "line": 345, "text": " return dbm;" }, { "line": 346, "text": "}" }, { "line": 347, "text": "" }, { "line": 348, "text": "int dbmTomwatts(int dbm) {" }, { "line": 349, "text": " if (dbm2mw.contains(dbm)) {" }, { "line": 350, "text": " return dbm2mw[dbm];" }, { "line": 351, "text": " }" }, { "line": 352, "text": " auto iter = dbm2mw.lowerBound(dbm);" }, { "line": 353, "text": " if (iter == dbm2mw.end()) {" }, { "line": 354, "text": " return dbm2mw.last();" }, { "line": 355, "text": " }" }, { "line": 356, "text": " return iter.value();" }, { "line": 357, "text": "}" }, { "line": 358, "text": "" }, { "line": 359, "text": "QString Varicode::extendedChars() {" }, { "line": 360, "text": " static QString c;" }, { "line": 361, "text": " if (c.size() == 0) {" }, { "line": 362, "text": " for (quint32 i = 0; i < JSC::prefixSize; i++) {" } ] } }, { "function": "Varicode::extendedChars", "line": 359, "signature": "QString Varicode::extendedChars() {", "snippet": { "start_line": 345, "end_line": 373, "lines": [ { "line": 345, "text": " return dbm;" }, { "line": 346, "text": "}" }, { "line": 347, "text": "" }, { "line": 348, "text": "int dbmTomwatts(int dbm) {" }, { "line": 349, "text": " if (dbm2mw.contains(dbm)) {" }, { "line": 350, "text": " return dbm2mw[dbm];" }, { "line": 351, "text": " }" }, { "line": 352, "text": " auto iter = dbm2mw.lowerBound(dbm);" }, { "line": 353, "text": " if (iter == dbm2mw.end()) {" }, { "line": 354, "text": " return dbm2mw.last();" }, { "line": 355, "text": " }" }, { "line": 356, "text": " return iter.value();" }, { "line": 357, "text": "}" }, { "line": 358, "text": "" }, { "line": 359, "text": "QString Varicode::extendedChars() {" }, { "line": 360, "text": " static QString c;" }, { "line": 361, "text": " if (c.size() == 0) {" }, { "line": 362, "text": " for (quint32 i = 0; i < JSC::prefixSize; i++) {" }, { "line": 363, "text": " if (JSC::prefix[i].size != 1) {" }, { "line": 364, "text": " continue;" }, { "line": 365, "text": " }" }, { "line": 366, "text": " c.append(QLatin1String(JSC::prefix[i].str, 1));" }, { "line": 367, "text": " }" }, { "line": 368, "text": " }" }, { "line": 369, "text": " return c;" }, { "line": 370, "text": "}" }, { "line": 371, "text": "" }, { "line": 372, "text": "QString Varicode::escape(const QString &text) {" }, { "line": 373, "text": " static const int size = 6;" } ] } }, { "function": "Varicode::escape", "line": 372, "signature": "QString Varicode::escape(const QString &text) {", "snippet": { "start_line": 358, "end_line": 386, "lines": [ { "line": 358, "text": "" }, { "line": 359, "text": "QString Varicode::extendedChars() {" }, { "line": 360, "text": " static QString c;" }, { "line": 361, "text": " if (c.size() == 0) {" }, { "line": 362, "text": " for (quint32 i = 0; i < JSC::prefixSize; i++) {" }, { "line": 363, "text": " if (JSC::prefix[i].size != 1) {" }, { "line": 364, "text": " continue;" }, { "line": 365, "text": " }" }, { "line": 366, "text": " c.append(QLatin1String(JSC::prefix[i].str, 1));" }, { "line": 367, "text": " }" }, { "line": 368, "text": " }" }, { "line": 369, "text": " return c;" }, { "line": 370, "text": "}" }, { "line": 371, "text": "" }, { "line": 372, "text": "QString Varicode::escape(const QString &text) {" }, { "line": 373, "text": " static const int size = 6;" }, { "line": 374, "text": " QString escaped;" }, { "line": 375, "text": " escaped.reserve(size * text.size());" }, { "line": 376, "text": " for (QString::const_iterator it = text.begin(); it != text.end(); ++it) {" }, { "line": 377, "text": " QChar ch = *it;" }, { "line": 378, "text": " ushort code = ch.unicode();" }, { "line": 379, "text": " if (code < 0x80) {" }, { "line": 380, "text": " escaped += ch;" }, { "line": 381, "text": " } else {" }, { "line": 382, "text": "#if JS8_USE_ESCAPE_SUB_CHAR" }, { "line": 383, "text": " // escaped += \"\\x1A\"; // substitute char" }, { "line": 384, "text": "#else" }, { "line": 385, "text": " escaped += \"\\\\U\"; // \"U+\"; // substitute char" }, { "line": 386, "text": "#endif" } ] } }, { "function": "Varicode::unescape", "line": 394, "signature": "QString Varicode::unescape(const QString &text) {", "snippet": { "start_line": 380, "end_line": 408, "lines": [ { "line": 380, "text": " escaped += ch;" }, { "line": 381, "text": " } else {" }, { "line": 382, "text": "#if JS8_USE_ESCAPE_SUB_CHAR" }, { "line": 383, "text": " // escaped += \"\\x1A\"; // substitute char" }, { "line": 384, "text": "#else" }, { "line": 385, "text": " escaped += \"\\\\U\"; // \"U+\"; // substitute char" }, { "line": 386, "text": "#endif" }, { "line": 387, "text": " escaped += QString::number(code, 16).rightJustified(4, '0');" }, { "line": 388, "text": " }" }, { "line": 389, "text": " }" }, { "line": 390, "text": "" }, { "line": 391, "text": " return escaped;" }, { "line": 392, "text": "}" }, { "line": 393, "text": "" }, { "line": 394, "text": "QString Varicode::unescape(const QString &text) {" }, { "line": 395, "text": " QString unescaped(text);" }, { "line": 396, "text": "#if JS8_USE_ESCAPE_SUB_CHAR" }, { "line": 397, "text": " static const int size = 5;" }, { "line": 398, "text": " QRegularExpression r(\"([\\\\x1A][0-9a-fA-F]{4})\");" }, { "line": 399, "text": "#else" }, { "line": 400, "text": " static const int size = 6;" }, { "line": 401, "text": " QRegularExpression r(\"(([uU][+]|\\\\\\\\[uU])[0-9a-fA-F]{4})\");" }, { "line": 402, "text": "#endif" }, { "line": 403, "text": " qsizetype pos = 0;" }, { "line": 404, "text": " QRegularExpressionMatch match;" }, { "line": 405, "text": " while ((pos = unescaped.indexOf(r, pos, &match)) != -1) {" }, { "line": 406, "text": " unescaped.replace(pos++, size," }, { "line": 407, "text": " QChar(match.captured(1).right(4).toUShort(0, 16)));" }, { "line": 408, "text": " }" } ] } }, { "function": "Varicode::rstrip", "line": 413, "signature": "QString Varicode::rstrip(const QString &str) {", "snippet": { "start_line": 399, "end_line": 427, "lines": [ { "line": 399, "text": "#else" }, { "line": 400, "text": " static const int size = 6;" }, { "line": 401, "text": " QRegularExpression r(\"(([uU][+]|\\\\\\\\[uU])[0-9a-fA-F]{4})\");" }, { "line": 402, "text": "#endif" }, { "line": 403, "text": " qsizetype pos = 0;" }, { "line": 404, "text": " QRegularExpressionMatch match;" }, { "line": 405, "text": " while ((pos = unescaped.indexOf(r, pos, &match)) != -1) {" }, { "line": 406, "text": " unescaped.replace(pos++, size," }, { "line": 407, "text": " QChar(match.captured(1).right(4).toUShort(0, 16)));" }, { "line": 408, "text": " }" }, { "line": 409, "text": "" }, { "line": 410, "text": " return unescaped;" }, { "line": 411, "text": "}" }, { "line": 412, "text": "" }, { "line": 413, "text": "QString Varicode::rstrip(const QString &str) {" }, { "line": 414, "text": " qsizetype n = str.size() - 1;" }, { "line": 415, "text": " for (; n >= 0; --n) {" }, { "line": 416, "text": " if (str.at(n).isSpace()) {" }, { "line": 417, "text": " continue;" }, { "line": 418, "text": " }" }, { "line": 419, "text": " return str.left(n + 1);" }, { "line": 420, "text": " }" }, { "line": 421, "text": " return \"\";" }, { "line": 422, "text": "}" }, { "line": 423, "text": "" }, { "line": 424, "text": "QString Varicode::lstrip(const QString &str) {" }, { "line": 425, "text": " qsizetype len = str.size();" }, { "line": 426, "text": " for (int n = 0; n < len; n++) {" }, { "line": 427, "text": " if (str.at(n).isSpace()) {" } ] } }, { "function": "Varicode::lstrip", "line": 424, "signature": "QString Varicode::lstrip(const QString &str) {", "snippet": { "start_line": 410, "end_line": 438, "lines": [ { "line": 410, "text": " return unescaped;" }, { "line": 411, "text": "}" }, { "line": 412, "text": "" }, { "line": 413, "text": "QString Varicode::rstrip(const QString &str) {" }, { "line": 414, "text": " qsizetype n = str.size() - 1;" }, { "line": 415, "text": " for (; n >= 0; --n) {" }, { "line": 416, "text": " if (str.at(n).isSpace()) {" }, { "line": 417, "text": " continue;" }, { "line": 418, "text": " }" }, { "line": 419, "text": " return str.left(n + 1);" }, { "line": 420, "text": " }" }, { "line": 421, "text": " return \"\";" }, { "line": 422, "text": "}" }, { "line": 423, "text": "" }, { "line": 424, "text": "QString Varicode::lstrip(const QString &str) {" }, { "line": 425, "text": " qsizetype len = str.size();" }, { "line": 426, "text": " for (int n = 0; n < len; n++) {" }, { "line": 427, "text": " if (str.at(n).isSpace()) {" }, { "line": 428, "text": " continue;" }, { "line": 429, "text": " }" }, { "line": 430, "text": " return str.mid(n);" }, { "line": 431, "text": " }" }, { "line": 432, "text": " return \"\";" }, { "line": 433, "text": "}" }, { "line": 434, "text": "" }, { "line": 435, "text": "/*" }, { "line": 436, "text": " * VARICODE" }, { "line": 437, "text": " */" }, { "line": 438, "text": "QMap Varicode::defaultHuffTable() { return hufftable; }" } ] } }, { "function": "Varicode::cqString", "line": 440, "signature": "QString Varicode::cqString(int number) {", "snippet": { "start_line": 426, "end_line": 454, "lines": [ { "line": 426, "text": " for (int n = 0; n < len; n++) {" }, { "line": 427, "text": " if (str.at(n).isSpace()) {" }, { "line": 428, "text": " continue;" }, { "line": 429, "text": " }" }, { "line": 430, "text": " return str.mid(n);" }, { "line": 431, "text": " }" }, { "line": 432, "text": " return \"\";" }, { "line": 433, "text": "}" }, { "line": 434, "text": "" }, { "line": 435, "text": "/*" }, { "line": 436, "text": " * VARICODE" }, { "line": 437, "text": " */" }, { "line": 438, "text": "QMap Varicode::defaultHuffTable() { return hufftable; }" }, { "line": 439, "text": "" }, { "line": 440, "text": "QString Varicode::cqString(int number) {" }, { "line": 441, "text": " if (!cqs.contains(number)) {" }, { "line": 442, "text": " return QString{};" }, { "line": 443, "text": " }" }, { "line": 444, "text": " return cqs[number];" }, { "line": 445, "text": "}" }, { "line": 446, "text": "" }, { "line": 447, "text": "QString Varicode::hbString(int number) {" }, { "line": 448, "text": " if (!hbs.contains(number)) {" }, { "line": 449, "text": " return QString{};" }, { "line": 450, "text": " }" }, { "line": 451, "text": " return hbs[number];" }, { "line": 452, "text": "}" }, { "line": 453, "text": "" }, { "line": 454, "text": "bool Varicode::startsWithCQ(QString text) {" } ] } }, { "function": "Varicode::hbString", "line": 447, "signature": "QString Varicode::hbString(int number) {", "snippet": { "start_line": 433, "end_line": 461, "lines": [ { "line": 433, "text": "}" }, { "line": 434, "text": "" }, { "line": 435, "text": "/*" }, { "line": 436, "text": " * VARICODE" }, { "line": 437, "text": " */" }, { "line": 438, "text": "QMap Varicode::defaultHuffTable() { return hufftable; }" }, { "line": 439, "text": "" }, { "line": 440, "text": "QString Varicode::cqString(int number) {" }, { "line": 441, "text": " if (!cqs.contains(number)) {" }, { "line": 442, "text": " return QString{};" }, { "line": 443, "text": " }" }, { "line": 444, "text": " return cqs[number];" }, { "line": 445, "text": "}" }, { "line": 446, "text": "" }, { "line": 447, "text": "QString Varicode::hbString(int number) {" }, { "line": 448, "text": " if (!hbs.contains(number)) {" }, { "line": 449, "text": " return QString{};" }, { "line": 450, "text": " }" }, { "line": 451, "text": " return hbs[number];" }, { "line": 452, "text": "}" }, { "line": 453, "text": "" }, { "line": 454, "text": "bool Varicode::startsWithCQ(QString text) {" }, { "line": 455, "text": " foreach (auto cq, cqs.values()) {" }, { "line": 456, "text": " if (text.startsWith(cq)) {" }, { "line": 457, "text": " return true;" }, { "line": 458, "text": " }" }, { "line": 459, "text": " }" }, { "line": 460, "text": " return false;" }, { "line": 461, "text": "}" } ] } }, { "function": "Varicode::startsWithCQ", "line": 454, "signature": "bool Varicode::startsWithCQ(QString text) {", "snippet": { "start_line": 440, "end_line": 468, "lines": [ { "line": 440, "text": "QString Varicode::cqString(int number) {" }, { "line": 441, "text": " if (!cqs.contains(number)) {" }, { "line": 442, "text": " return QString{};" }, { "line": 443, "text": " }" }, { "line": 444, "text": " return cqs[number];" }, { "line": 445, "text": "}" }, { "line": 446, "text": "" }, { "line": 447, "text": "QString Varicode::hbString(int number) {" }, { "line": 448, "text": " if (!hbs.contains(number)) {" }, { "line": 449, "text": " return QString{};" }, { "line": 450, "text": " }" }, { "line": 451, "text": " return hbs[number];" }, { "line": 452, "text": "}" }, { "line": 453, "text": "" }, { "line": 454, "text": "bool Varicode::startsWithCQ(QString text) {" }, { "line": 455, "text": " foreach (auto cq, cqs.values()) {" }, { "line": 456, "text": " if (text.startsWith(cq)) {" }, { "line": 457, "text": " return true;" }, { "line": 458, "text": " }" }, { "line": 459, "text": " }" }, { "line": 460, "text": " return false;" }, { "line": 461, "text": "}" }, { "line": 462, "text": "" }, { "line": 463, "text": "bool Varicode::startsWithHB(QString text) {" }, { "line": 464, "text": " foreach (auto hb, hbs.values()) {" }, { "line": 465, "text": " if (text.startsWith(hb)) {" }, { "line": 466, "text": " return true;" }, { "line": 467, "text": " }" }, { "line": 468, "text": " }" } ] } }, { "function": "Varicode::startsWithHB", "line": 463, "signature": "bool Varicode::startsWithHB(QString text) {", "snippet": { "start_line": 449, "end_line": 477, "lines": [ { "line": 449, "text": " return QString{};" }, { "line": 450, "text": " }" }, { "line": 451, "text": " return hbs[number];" }, { "line": 452, "text": "}" }, { "line": 453, "text": "" }, { "line": 454, "text": "bool Varicode::startsWithCQ(QString text) {" }, { "line": 455, "text": " foreach (auto cq, cqs.values()) {" }, { "line": 456, "text": " if (text.startsWith(cq)) {" }, { "line": 457, "text": " return true;" }, { "line": 458, "text": " }" }, { "line": 459, "text": " }" }, { "line": 460, "text": " return false;" }, { "line": 461, "text": "}" }, { "line": 462, "text": "" }, { "line": 463, "text": "bool Varicode::startsWithHB(QString text) {" }, { "line": 464, "text": " foreach (auto hb, hbs.values()) {" }, { "line": 465, "text": " if (text.startsWith(hb)) {" }, { "line": 466, "text": " return true;" }, { "line": 467, "text": " }" }, { "line": 468, "text": " }" }, { "line": 469, "text": " return false;" }, { "line": 470, "text": "}" }, { "line": 471, "text": "" }, { "line": 472, "text": "QString Varicode::formatSNR(int snr) {" }, { "line": 473, "text": " if (snr < -60 || snr > 60) {" }, { "line": 474, "text": " return QString();" }, { "line": 475, "text": " }" }, { "line": 476, "text": "" }, { "line": 477, "text": " return QString(\"%1%2\")" } ] } }, { "function": "Varicode::formatSNR", "line": 472, "signature": "QString Varicode::formatSNR(int snr) {", "snippet": { "start_line": 458, "end_line": 486, "lines": [ { "line": 458, "text": " }" }, { "line": 459, "text": " }" }, { "line": 460, "text": " return false;" }, { "line": 461, "text": "}" }, { "line": 462, "text": "" }, { "line": 463, "text": "bool Varicode::startsWithHB(QString text) {" }, { "line": 464, "text": " foreach (auto hb, hbs.values()) {" }, { "line": 465, "text": " if (text.startsWith(hb)) {" }, { "line": 466, "text": " return true;" }, { "line": 467, "text": " }" }, { "line": 468, "text": " }" }, { "line": 469, "text": " return false;" }, { "line": 470, "text": "}" }, { "line": 471, "text": "" }, { "line": 472, "text": "QString Varicode::formatSNR(int snr) {" }, { "line": 473, "text": " if (snr < -60 || snr > 60) {" }, { "line": 474, "text": " return QString();" }, { "line": 475, "text": " }" }, { "line": 476, "text": "" }, { "line": 477, "text": " return QString(\"%1%2\")" }, { "line": 478, "text": " .arg(snr >= 0 ? \"+\" : \"\")" }, { "line": 479, "text": " .arg(snr, snr < 0 ? 3 : 2, 10, QChar('0'));" }, { "line": 480, "text": "}" }, { "line": 481, "text": "" }, { "line": 482, "text": "QString Varicode::checksum16(QString const &input) {" }, { "line": 483, "text": " auto fromBytes = input.toLocal8Bit();" }, { "line": 484, "text": " auto crc = CRC::Calculate(fromBytes.data(), fromBytes.length()," }, { "line": 485, "text": " CRC::CRC_16_KERMIT());" }, { "line": 486, "text": " auto checksum = Varicode::pack16bits(crc);" } ] } } ], "keyword_snippets": [ { "line": 2, "matches": [ "Varicode" ], "snippet": { "start_line": 1, "end_line": 8, "lines": [ { "line": 1, "text": "/**" }, { "line": 2, "text": " * @file Varicode.cpp" }, { "line": 3, "text": " * @brief implementation of encoder" }, { "line": 4, "text": " * (C) 2018 Jordan Sherer - All Rights Reserved" }, { "line": 5, "text": " *" }, { "line": 6, "text": " */" }, { "line": 7, "text": "" }, { "line": 8, "text": "#include \"Varicode.h\"" } ] } }, { "line": 8, "matches": [ "Varicode" ], "snippet": { "start_line": 2, "end_line": 14, "lines": [ { "line": 2, "text": " * @file Varicode.cpp" }, { "line": 3, "text": " * @brief implementation of encoder" }, { "line": 4, "text": " * (C) 2018 Jordan Sherer - All Rights Reserved" }, { "line": 5, "text": " *" }, { "line": 6, "text": " */" }, { "line": 7, "text": "" }, { "line": 8, "text": "#include \"Varicode.h\"" }, { "line": 9, "text": "#include \"JS8_JSC/JSC.h\"" }, { "line": 10, "text": "#include \"JS8_Mode/DecodedText.h\"" }, { "line": 11, "text": "" }, { "line": 12, "text": "#include " }, { "line": 13, "text": "#include " }, { "line": 14, "text": "#include " } ] } }, { "line": 16, "matches": [ "crc" ], "snippet": { "start_line": 10, "end_line": 22, "lines": [ { "line": 10, "text": "#include \"JS8_Mode/DecodedText.h\"" }, { "line": 11, "text": "" }, { "line": 12, "text": "#include " }, { "line": 13, "text": "#include " }, { "line": 14, "text": "#include " }, { "line": 15, "text": "#include " }, { "line": 16, "text": "#include " }, { "line": 17, "text": "" }, { "line": 18, "text": "#include " }, { "line": 19, "text": "#include " }, { "line": 20, "text": "" }, { "line": 21, "text": "#define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS" }, { "line": 22, "text": "#define CRCPP_USE_CPP11" } ] } }, { "line": 21, "matches": [ "crc" ], "snippet": { "start_line": 15, "end_line": 27, "lines": [ { "line": 15, "text": "#include " }, { "line": 16, "text": "#include " }, { "line": 17, "text": "" }, { "line": 18, "text": "#include " }, { "line": 19, "text": "#include " }, { "line": 20, "text": "" }, { "line": 21, "text": "#define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS" }, { "line": 22, "text": "#define CRCPP_USE_CPP11" }, { "line": 23, "text": "" }, { "line": 24, "text": "Q_DECLARE_LOGGING_CATEGORY(varicode_js8)" }, { "line": 25, "text": "" }, { "line": 26, "text": "const int nalphabet = 41;" }, { "line": 27, "text": "QString alphabet = {" } ] } }, { "line": 43, "matches": [ "pack" ], "snippet": { "start_line": 37, "end_line": 49, "lines": [ { "line": 37, "text": "QString base_callsign_pattern = {" }, { "line": 38, "text": " R\"((?\\b(?([0-9A-Z])?([0-9A-Z])([0-9])([A-Z])?([A-Z])?([A-Z])?)(?[/][P])?\\b))\"};" }, { "line": 39, "text": "// QString compound_callsign_pattern =" }, { "line": 40, "text": "// {R\"((?\\b(?[A-Z0-9]{1,4}\\/)?(?([0-9A-Z])?([0-9A-Z])([0-9])([A-Z])?([A-Z])?([A-Z])?)(?\\/[A-Z0-9]{1,4})?)\\b)\"};" }, { "line": 41, "text": "QString compound_callsign_pattern = {" }, { "line": 42, "text": " R\"((?(?:[@]?|\\b)(?[A-Z0-9\\/@][A-Z0-9\\/]{0,2}[\\/]?[A-Z0-9\\/]{0,3}[\\/]?[A-Z0-9\\/]{0,3})\\b))\"};" }, { "line": 43, "text": "QString pack_callsign_pattern = {" }, { "line": 44, "text": " R\"(([0-9A-Z ])([0-9A-Z])([0-9])([A-Z ])([A-Z ])([A-Z ]))\"};" }, { "line": 45, "text": "QString alphanumeric = {" }, { "line": 46, "text": " \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ /@\"}; // callsign and grid alphabet" }, { "line": 47, "text": "" }, { "line": 48, "text": "QMap directed_cmds = {" }, { "line": 49, "text": " // any changes here need to be made also in the directed regular xpression" } ] } }, { "line": 62, "matches": [ "bits" ], "snippet": { "start_line": 56, "end_line": 68, "lines": [ { "line": 56, "text": " {\" CQ\", -1}, // this is my cq (unused except for faux processing of CQs as" }, { "line": 57, "text": " // directed commands)" }, { "line": 58, "text": "" }, { "line": 59, "text": " {\" SNR?\", 0}, // query snr" }, { "line": 60, "text": " {\"?\", 0}, // compat" }, { "line": 61, "text": "" }, { "line": 62, "text": " {\" DIT DIT\", 1}, // two bits" }, { "line": 63, "text": "" }, { "line": 64, "text": " {\" HEARING?\", 3}, // query station calls heard" }, { "line": 65, "text": "" }, { "line": 66, "text": " {\" GRID?\", 4}, // query grid" }, { "line": 67, "text": "" }, { "line": 68, "text": " {\">\", 5}, // relay message" } ] } }, { "line": 68, "matches": [ "message" ], "snippet": { "start_line": 62, "end_line": 74, "lines": [ { "line": 62, "text": " {\" DIT DIT\", 1}, // two bits" }, { "line": 63, "text": "" }, { "line": 64, "text": " {\" HEARING?\", 3}, // query station calls heard" }, { "line": 65, "text": "" }, { "line": 66, "text": " {\" GRID?\", 4}, // query grid" }, { "line": 67, "text": "" }, { "line": 68, "text": " {\">\", 5}, // relay message" }, { "line": 69, "text": "" }, { "line": 70, "text": " {\" STATUS?\", 6}, // query idle message" }, { "line": 71, "text": "" }, { "line": 72, "text": " {\" STATUS\", 7}, // this is my status" }, { "line": 73, "text": "" }, { "line": 74, "text": " {\" HEARING\", 8}, // these are the stations i'm hearing" } ] } }, { "line": 76, "matches": [ "message" ], "snippet": { "start_line": 70, "end_line": 82, "lines": [ { "line": 70, "text": " {\" STATUS?\", 6}, // query idle message" }, { "line": 71, "text": "" }, { "line": 72, "text": " {\" STATUS\", 7}, // this is my status" }, { "line": 73, "text": "" }, { "line": 74, "text": " {\" HEARING\", 8}, // these are the stations i'm hearing" }, { "line": 75, "text": "" }, { "line": 76, "text": " {\" MSG\", 9}, // this is a complete message" }, { "line": 77, "text": "" }, { "line": 78, "text": " {\" MSG TO:\", 10}, // store message at a station" }, { "line": 79, "text": "" }, { "line": 80, "text": " {\" QUERY\", 11}, // generic query" }, { "line": 81, "text": "" }, { "line": 82, "text": " {\" QUERY MSGS\", 12}, // do you have any stored messages?" } ] } }, { "line": 82, "matches": [ "message" ], "snippet": { "start_line": 76, "end_line": 88, "lines": [ { "line": 76, "text": " {\" MSG\", 9}, // this is a complete message" }, { "line": 77, "text": "" }, { "line": 78, "text": " {\" MSG TO:\", 10}, // store message at a station" }, { "line": 79, "text": "" }, { "line": 80, "text": " {\" QUERY\", 11}, // generic query" }, { "line": 81, "text": "" }, { "line": 82, "text": " {\" QUERY MSGS\", 12}, // do you have any stored messages?" }, { "line": 83, "text": " {\" QUERY MSGS?\", 12}, // do you have any stored messages?" }, { "line": 84, "text": "" }, { "line": 85, "text": " {\" QUERY CALL\", 13}, // can you transmit a ping to callsign?" }, { "line": 86, "text": "" }, { "line": 87, "text": " // {\" \", 14 }, // reserved" }, { "line": 88, "text": "" } ] } }, { "line": 91, "matches": [ "message" ], "snippet": { "start_line": 85, "end_line": 97, "lines": [ { "line": 85, "text": " {\" QUERY CALL\", 13}, // can you transmit a ping to callsign?" }, { "line": 86, "text": "" }, { "line": 87, "text": " // {\" \", 14 }, // reserved" }, { "line": 88, "text": "" }, { "line": 89, "text": " {\" GRID\", 15}, // this is my current grid locator" }, { "line": 90, "text": "" }, { "line": 91, "text": " {\" INFO?\", 16}, // what is your info message?" }, { "line": 92, "text": " {\" INFO\", 17}, // this is my info message" }, { "line": 93, "text": "" }, { "line": 94, "text": " {\" FB\", 18}, // fine business" }, { "line": 95, "text": " {\" HW CPY?\", 19}, // how do you copy?" }, { "line": 96, "text": " {\" SK\", 20}, // end of contact" }, { "line": 97, "text": " {\" RR\", 21}, // roger roger" } ] } }, { "line": 114, "matches": [ "message" ], "snippet": { "start_line": 108, "end_line": 120, "lines": [ { "line": 108, "text": "" }, { "line": 109, "text": " {\" NACK\", 2}, // negative acknowledge" }, { "line": 110, "text": " {\" ACK\", 14}, // acknowledge (was reserved in 2.1)" }, { "line": 111, "text": "" }, { "line": 112, "text": " {\" HEARTBEAT SNR\", 29}, // (was ACK in 2.1, now deprecated)" }, { "line": 113, "text": "" }, { "line": 114, "text": " {\" AGN?\", 30}, // repeat message" }, { "line": 115, "text": " {\" \", 31}, // send freetext (weird artifact)" }, { "line": 116, "text": " {\" \", 31}, // send freetext" }, { "line": 117, "text": "};" }, { "line": 118, "text": "" }, { "line": 119, "text": "// commands allowed to be processed" }, { "line": 120, "text": "QSet allowed_cmds = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9," } ] } }, { "line": 133, "matches": [ "crc", "checksum" ], "snippet": { "start_line": 127, "end_line": 139, "lines": [ { "line": 127, "text": "// commands that should be buffered" }, { "line": 128, "text": "QSet buffered_cmds = {5, 9, 10, 11, 12, 13, 15, 24};" }, { "line": 129, "text": "" }, { "line": 130, "text": "// commands that may include an SNR value" }, { "line": 131, "text": "QSet snr_cmds = {25, 29};" }, { "line": 132, "text": "" }, { "line": 133, "text": "// commands that are checksummed and their crc size" }, { "line": 134, "text": "QMap checksum_cmds = {{5, 16}, {9, 16}, {10, 16}, {11, 16}," }, { "line": 135, "text": " {12, 16}, {13, 16}, {15, 0}, {24, 16}};" }, { "line": 136, "text": "" }, { "line": 137, "text": "QString callsign_pattern = QString(\"(?[@]?[A-Z0-9/]+)\");" }, { "line": 138, "text": "QString optional_cmd_pattern =" }, { "line": 139, "text": " QString(\"(?\\\\s?(?:AGN[?]|QSL[?]|HW CPY[?]|MSG \"" } ] } }, { "line": 159, "matches": [ "message" ], "snippet": { "start_line": 153, "end_line": 165, "lines": [ { "line": 153, "text": "QRegularExpression heartbeat_re(" }, { "line": 154, "text": " R\"(^\\s*(?[@](?:ALLCALL|HB)\\s+)?(?CQ CQ CQ|CQ DX|CQ QRP|CQ CONTEST|CQ FIELD|CQ FD|CQ CQ|CQ|HB|HEARTBEAT(?!\\s+SNR))(?:\\s(?[A-R]{2}[0-9]{2}))?\\b)\");" }, { "line": 155, "text": "" }, { "line": 156, "text": "QRegularExpression" }, { "line": 157, "text": " compound_re(\"^\\\\s*[`]\" + callsign_pattern + \"(?\" +" }, { "line": 158, "text": " optional_grid_pattern + // there's a reason this is first (see:" }, { "line": 159, "text": " // buildMessageFrames)" }, { "line": 160, "text": " optional_cmd_pattern + optional_num_pattern + \")\");" }, { "line": 161, "text": "" }, { "line": 162, "text": "QMap hufftable = {" }, { "line": 163, "text": " // char code weight" }, { "line": 164, "text": " {\" \", \"01\"}, // 1.0" }, { "line": 165, "text": " {\"E\", \"100\"}, // 0.5" } ] } }, { "line": 292, "matches": [ "message" ], "snippet": { "start_line": 286, "end_line": 298, "lines": [ { "line": 286, "text": "" }, { "line": 287, "text": "QMap cqs = {" }, { "line": 288, "text": " {0, \"CQ CQ CQ\"}, {1, \"CQ DX\"}, {2, \"CQ QRP\"}, {3, \"CQ CONTEST\"}," }, { "line": 289, "text": " {4, \"CQ FIELD\"}, {5, \"CQ FD\"}, {6, \"CQ CQ\"}, {7, \"CQ\"}," }, { "line": 290, "text": "};" }, { "line": 291, "text": "" }, { "line": 292, "text": "// status flags in HB messages are deprecated as of 2.2, later versions will" }, { "line": 293, "text": "// likely repurpose these flags keep in mind if you change any of these to not" }, { "line": 294, "text": "// start with HB you'll have to address the packHeartbeatMessage and how the" }, { "line": 295, "text": "// function computes the isAlt flag." }, { "line": 296, "text": "QMap hbs = {" }, { "line": 297, "text": " {0, \"HB\"}, // HB" }, { "line": 298, "text": " {1, \"HB\"}, // HB AUTO" } ] } }, { "line": 359, "matches": [ "Varicode" ], "snippet": { "start_line": 353, "end_line": 365, "lines": [ { "line": 353, "text": " if (iter == dbm2mw.end()) {" }, { "line": 354, "text": " return dbm2mw.last();" }, { "line": 355, "text": " }" }, { "line": 356, "text": " return iter.value();" }, { "line": 357, "text": "}" }, { "line": 358, "text": "" }, { "line": 359, "text": "QString Varicode::extendedChars() {" }, { "line": 360, "text": " static QString c;" }, { "line": 361, "text": " if (c.size() == 0) {" }, { "line": 362, "text": " for (quint32 i = 0; i < JSC::prefixSize; i++) {" }, { "line": 363, "text": " if (JSC::prefix[i].size != 1) {" }, { "line": 364, "text": " continue;" }, { "line": 365, "text": " }" } ] } }, { "line": 362, "matches": [ "JSC" ], "snippet": { "start_line": 356, "end_line": 368, "lines": [ { "line": 356, "text": " return iter.value();" }, { "line": 357, "text": "}" }, { "line": 358, "text": "" }, { "line": 359, "text": "QString Varicode::extendedChars() {" }, { "line": 360, "text": " static QString c;" }, { "line": 361, "text": " if (c.size() == 0) {" }, { "line": 362, "text": " for (quint32 i = 0; i < JSC::prefixSize; i++) {" }, { "line": 363, "text": " if (JSC::prefix[i].size != 1) {" }, { "line": 364, "text": " continue;" }, { "line": 365, "text": " }" }, { "line": 366, "text": " c.append(QLatin1String(JSC::prefix[i].str, 1));" }, { "line": 367, "text": " }" }, { "line": 368, "text": " }" } ] } }, { "line": 366, "matches": [ "JSC" ], "snippet": { "start_line": 360, "end_line": 372, "lines": [ { "line": 360, "text": " static QString c;" }, { "line": 361, "text": " if (c.size() == 0) {" }, { "line": 362, "text": " for (quint32 i = 0; i < JSC::prefixSize; i++) {" }, { "line": 363, "text": " if (JSC::prefix[i].size != 1) {" }, { "line": 364, "text": " continue;" }, { "line": 365, "text": " }" }, { "line": 366, "text": " c.append(QLatin1String(JSC::prefix[i].str, 1));" }, { "line": 367, "text": " }" }, { "line": 368, "text": " }" }, { "line": 369, "text": " return c;" }, { "line": 370, "text": "}" }, { "line": 371, "text": "" }, { "line": 372, "text": "QString Varicode::escape(const QString &text) {" } ] } }, { "line": 372, "matches": [ "Varicode" ], "snippet": { "start_line": 366, "end_line": 378, "lines": [ { "line": 366, "text": " c.append(QLatin1String(JSC::prefix[i].str, 1));" }, { "line": 367, "text": " }" }, { "line": 368, "text": " }" }, { "line": 369, "text": " return c;" }, { "line": 370, "text": "}" }, { "line": 371, "text": "" }, { "line": 372, "text": "QString Varicode::escape(const QString &text) {" }, { "line": 373, "text": " static const int size = 6;" }, { "line": 374, "text": " QString escaped;" }, { "line": 375, "text": " escaped.reserve(size * text.size());" }, { "line": 376, "text": " for (QString::const_iterator it = text.begin(); it != text.end(); ++it) {" }, { "line": 377, "text": " QChar ch = *it;" }, { "line": 378, "text": " ushort code = ch.unicode();" } ] } }, { "line": 394, "matches": [ "Varicode" ], "snippet": { "start_line": 388, "end_line": 400, "lines": [ { "line": 388, "text": " }" }, { "line": 389, "text": " }" }, { "line": 390, "text": "" }, { "line": 391, "text": " return escaped;" }, { "line": 392, "text": "}" }, { "line": 393, "text": "" }, { "line": 394, "text": "QString Varicode::unescape(const QString &text) {" }, { "line": 395, "text": " QString unescaped(text);" }, { "line": 396, "text": "#if JS8_USE_ESCAPE_SUB_CHAR" }, { "line": 397, "text": " static const int size = 5;" }, { "line": 398, "text": " QRegularExpression r(\"([\\\\x1A][0-9a-fA-F]{4})\");" }, { "line": 399, "text": "#else" }, { "line": 400, "text": " static const int size = 6;" } ] } }, { "line": 413, "matches": [ "Varicode" ], "snippet": { "start_line": 407, "end_line": 419, "lines": [ { "line": 407, "text": " QChar(match.captured(1).right(4).toUShort(0, 16)));" }, { "line": 408, "text": " }" }, { "line": 409, "text": "" }, { "line": 410, "text": " return unescaped;" }, { "line": 411, "text": "}" }, { "line": 412, "text": "" }, { "line": 413, "text": "QString Varicode::rstrip(const QString &str) {" }, { "line": 414, "text": " qsizetype n = str.size() - 1;" }, { "line": 415, "text": " for (; n >= 0; --n) {" }, { "line": 416, "text": " if (str.at(n).isSpace()) {" }, { "line": 417, "text": " continue;" }, { "line": 418, "text": " }" }, { "line": 419, "text": " return str.left(n + 1);" } ] } }, { "line": 424, "matches": [ "Varicode" ], "snippet": { "start_line": 418, "end_line": 430, "lines": [ { "line": 418, "text": " }" }, { "line": 419, "text": " return str.left(n + 1);" }, { "line": 420, "text": " }" }, { "line": 421, "text": " return \"\";" }, { "line": 422, "text": "}" }, { "line": 423, "text": "" }, { "line": 424, "text": "QString Varicode::lstrip(const QString &str) {" }, { "line": 425, "text": " qsizetype len = str.size();" }, { "line": 426, "text": " for (int n = 0; n < len; n++) {" }, { "line": 427, "text": " if (str.at(n).isSpace()) {" }, { "line": 428, "text": " continue;" }, { "line": 429, "text": " }" }, { "line": 430, "text": " return str.mid(n);" } ] } }, { "line": 436, "matches": [ "Varicode" ], "snippet": { "start_line": 430, "end_line": 442, "lines": [ { "line": 430, "text": " return str.mid(n);" }, { "line": 431, "text": " }" }, { "line": 432, "text": " return \"\";" }, { "line": 433, "text": "}" }, { "line": 434, "text": "" }, { "line": 435, "text": "/*" }, { "line": 436, "text": " * VARICODE" }, { "line": 437, "text": " */" }, { "line": 438, "text": "QMap Varicode::defaultHuffTable() { return hufftable; }" }, { "line": 439, "text": "" }, { "line": 440, "text": "QString Varicode::cqString(int number) {" }, { "line": 441, "text": " if (!cqs.contains(number)) {" }, { "line": 442, "text": " return QString{};" } ] } } ] }, { "path": "JS8_Main/Varicode.h", "exists": true, "bytes": 8286, "sha256": "dd7b8bf50466d0d2dc42b8c9ec05a72126363b3cd02c7492c5e2dcc9c9abb99d", "line_count": 222, "phase_hits": { "timing_submode": 0, "symbol_to_soft_bits": 0, "bit_order_interleaver": 32, "whitening_erasure": 0, "ldpc_decode": 0, "message91_crc_text": 85 }, "function_blocks": [ { "function": "frameTypeString", "line": 62, "signature": "static QString frameTypeString(quint8 type) {", "snippet": { "start_line": 48, "end_line": 76, "lines": [ { "line": 48, "text": " enum FrameType {" }, { "line": 49, "text": " FrameUnknown = 255, // [11111111] <- only used as a sentinel" }, { "line": 50, "text": " FrameHeartbeat = 0, // [000]" }, { "line": 51, "text": " FrameCompound = 1, // [001]" }, { "line": 52, "text": " FrameCompoundDirected = 2, // [010]" }, { "line": 53, "text": " FrameDirected = 3, // [011]" }, { "line": 54, "text": " FrameData = 4, // [10X] // but this only encodes the first 2 msb bits" }, { "line": 55, "text": " // and drops the lsb" }, { "line": 56, "text": " FrameDataCompressed = 6, // [11X] // but this only encodes the first 2" }, { "line": 57, "text": " // msb bits and drops the lsb" }, { "line": 58, "text": " };" }, { "line": 59, "text": "" }, { "line": 60, "text": " static const quint8 FrameTypeMax = 6;" }, { "line": 61, "text": "" }, { "line": 62, "text": " static QString frameTypeString(quint8 type) {" }, { "line": 63, "text": " const char *FrameTypeStrings[] = {" }, { "line": 64, "text": " \"FrameHeartbeat\", \"FrameCompound\", \"FrameCompoundDirected\"," }, { "line": 65, "text": " \"FrameDirected\", \"FrameData\"," }, { "line": 66, "text": " \"FrameUnknown\", // 5" }, { "line": 67, "text": " \"FrameDataCompressed\"," }, { "line": 68, "text": " };" }, { "line": 69, "text": "" }, { "line": 70, "text": " if (type > FrameTypeMax) {" }, { "line": 71, "text": " return \"FrameUnknown\";" }, { "line": 72, "text": " }" }, { "line": 73, "text": " return FrameTypeStrings[type];" }, { "line": 74, "text": " }" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Varicode();" } ] } } ], "keyword_snippets": [ { "line": 1, "matches": [ "Varicode" ], "snippet": { "start_line": 1, "end_line": 7, "lines": [ { "line": 1, "text": "#ifndef VARICODE_H" }, { "line": 2, "text": "#define VARICODE_H" }, { "line": 3, "text": "" }, { "line": 4, "text": "/**" }, { "line": 5, "text": " * (C) 2018 Jordan Sherer - All Rights Reserved" }, { "line": 6, "text": " **/" }, { "line": 7, "text": "" } ] } }, { "line": 14, "matches": [ "Varicode" ], "snippet": { "start_line": 8, "end_line": 20, "lines": [ { "line": 8, "text": "#include " }, { "line": 9, "text": "#include " }, { "line": 10, "text": "#include " }, { "line": 11, "text": "#include " }, { "line": 12, "text": "#include " }, { "line": 13, "text": "" }, { "line": 14, "text": "class Varicode {" }, { "line": 15, "text": " public:" }, { "line": 16, "text": " // extra information out of buildMessageFrames" }, { "line": 17, "text": " struct MessageInfo {" }, { "line": 18, "text": " QString dirTo;" }, { "line": 19, "text": " QString dirCmd;" }, { "line": 20, "text": " QString dirNum;" } ] } }, { "line": 16, "matches": [ "message" ], "snippet": { "start_line": 10, "end_line": 22, "lines": [ { "line": 10, "text": "#include " }, { "line": 11, "text": "#include " }, { "line": 12, "text": "#include " }, { "line": 13, "text": "" }, { "line": 14, "text": "class Varicode {" }, { "line": 15, "text": " public:" }, { "line": 16, "text": " // extra information out of buildMessageFrames" }, { "line": 17, "text": " struct MessageInfo {" }, { "line": 18, "text": " QString dirTo;" }, { "line": 19, "text": " QString dirCmd;" }, { "line": 20, "text": " QString dirNum;" }, { "line": 21, "text": " };" }, { "line": 22, "text": "" } ] } }, { "line": 34, "matches": [ "message" ], "snippet": { "start_line": 28, "end_line": 40, "lines": [ { "line": 28, "text": " JS8CallSlow = 4," }, { "line": 29, "text": " JS8CallUltra = 8" }, { "line": 30, "text": " };" }, { "line": 31, "text": "" }, { "line": 32, "text": " // frame type transmitted via itype and decoded by the ft8 decoded" }, { "line": 33, "text": " enum TransmissionType {" }, { "line": 34, "text": " JS8Call = 0, // [000] <- any other frame of the message" }, { "line": 35, "text": " JS8CallFirst = 1, // [001] <- the first frame of a message" }, { "line": 36, "text": " JS8CallLast = 2, // [010] <- the last frame of a message" }, { "line": 37, "text": " JS8CallData = 4, // [100] <- flagged frame (no frame type header)" }, { "line": 38, "text": " };" }, { "line": 39, "text": "" }, { "line": 40, "text": " /*" } ] } }, { "line": 36, "matches": [ "message" ], "snippet": { "start_line": 30, "end_line": 42, "lines": [ { "line": 30, "text": " };" }, { "line": 31, "text": "" }, { "line": 32, "text": " // frame type transmitted via itype and decoded by the ft8 decoded" }, { "line": 33, "text": " enum TransmissionType {" }, { "line": 34, "text": " JS8Call = 0, // [000] <- any other frame of the message" }, { "line": 35, "text": " JS8CallFirst = 1, // [001] <- the first frame of a message" }, { "line": 36, "text": " JS8CallLast = 2, // [010] <- the last frame of a message" }, { "line": 37, "text": " JS8CallData = 4, // [100] <- flagged frame (no frame type header)" }, { "line": 38, "text": " };" }, { "line": 39, "text": "" }, { "line": 40, "text": " /*" }, { "line": 41, "text": "" }, { "line": 42, "text": " 000 = heartbeat" } ] } }, { "line": 76, "matches": [ "Varicode" ], "snippet": { "start_line": 70, "end_line": 82, "lines": [ { "line": 70, "text": " if (type > FrameTypeMax) {" }, { "line": 71, "text": " return \"FrameUnknown\";" }, { "line": 72, "text": " }" }, { "line": 73, "text": " return FrameTypeStrings[type];" }, { "line": 74, "text": " }" }, { "line": 75, "text": "" }, { "line": 76, "text": " // Varicode();" }, { "line": 77, "text": "" }, { "line": 78, "text": " static SubmodeType intToSubmode(int sm);" }, { "line": 79, "text": "" }, { "line": 80, "text": " static QString extendedChars();" }, { "line": 81, "text": "" }, { "line": 82, "text": " static QString escape(const QString &text);" } ] } }, { "line": 120, "matches": [ "pack", "unpack" ], "snippet": { "start_line": 114, "end_line": 126, "lines": [ { "line": 114, "text": "" }, { "line": 115, "text": " static QVector intToBits(quint64 value, int expected = 0);" }, { "line": 116, "text": " static quint64 bitsToInt(QVector const value);" }, { "line": 117, "text": " static quint64 bitsToInt(QVector::ConstIterator start, int n);" }, { "line": 118, "text": " static QVector bitsListToBits(QList> &list);" }, { "line": 119, "text": "" }, { "line": 120, "text": " static quint8 unpack5bits(QString const &value);" }, { "line": 121, "text": " static QString pack5bits(quint8 packed);" }, { "line": 122, "text": "" }, { "line": 123, "text": " static quint8 unpack6bits(QString const &value);" }, { "line": 124, "text": " static QString pack6bits(quint8 packed);" }, { "line": 125, "text": "" }, { "line": 126, "text": " static quint16 unpack16bits(QString const &value);" } ] } }, { "line": 121, "matches": [ "pack" ], "snippet": { "start_line": 115, "end_line": 127, "lines": [ { "line": 115, "text": " static QVector intToBits(quint64 value, int expected = 0);" }, { "line": 116, "text": " static quint64 bitsToInt(QVector const value);" }, { "line": 117, "text": " static quint64 bitsToInt(QVector::ConstIterator start, int n);" }, { "line": 118, "text": " static QVector bitsListToBits(QList> &list);" }, { "line": 119, "text": "" }, { "line": 120, "text": " static quint8 unpack5bits(QString const &value);" }, { "line": 121, "text": " static QString pack5bits(quint8 packed);" }, { "line": 122, "text": "" }, { "line": 123, "text": " static quint8 unpack6bits(QString const &value);" }, { "line": 124, "text": " static QString pack6bits(quint8 packed);" }, { "line": 125, "text": "" }, { "line": 126, "text": " static quint16 unpack16bits(QString const &value);" }, { "line": 127, "text": " static QString pack16bits(quint16 packed);" } ] } }, { "line": 126, "matches": [ "pack", "unpack" ], "snippet": { "start_line": 120, "end_line": 132, "lines": [ { "line": 120, "text": " static quint8 unpack5bits(QString const &value);" }, { "line": 121, "text": " static QString pack5bits(quint8 packed);" }, { "line": 122, "text": "" }, { "line": 123, "text": " static quint8 unpack6bits(QString const &value);" }, { "line": 124, "text": " static QString pack6bits(quint8 packed);" }, { "line": 125, "text": "" }, { "line": 126, "text": " static quint16 unpack16bits(QString const &value);" }, { "line": 127, "text": " static QString pack16bits(quint16 packed);" }, { "line": 128, "text": "" }, { "line": 129, "text": " static quint32 unpack32bits(QString const &value);" }, { "line": 130, "text": " static QString pack32bits(quint32 packed);" }, { "line": 131, "text": "" }, { "line": 132, "text": " static quint64 unpack64bits(QString const &value);" } ] } }, { "line": 132, "matches": [ "pack", "unpack" ], "snippet": { "start_line": 126, "end_line": 138, "lines": [ { "line": 126, "text": " static quint16 unpack16bits(QString const &value);" }, { "line": 127, "text": " static QString pack16bits(quint16 packed);" }, { "line": 128, "text": "" }, { "line": 129, "text": " static quint32 unpack32bits(QString const &value);" }, { "line": 130, "text": " static QString pack32bits(quint32 packed);" }, { "line": 131, "text": "" }, { "line": 132, "text": " static quint64 unpack64bits(QString const &value);" }, { "line": 133, "text": " static QString pack64bits(quint64 packed);" }, { "line": 134, "text": "" }, { "line": 135, "text": " static quint64 unpack72bits(QString const &value, quint8 *pRem);" }, { "line": 136, "text": " static QString pack72bits(quint64 value, quint8 rem);" }, { "line": 137, "text": "" }, { "line": 138, "text": " static quint32 packAlphaNumeric22(QString const &value, bool isFlag);" } ] } }, { "line": 136, "matches": [ "pack" ], "snippet": { "start_line": 130, "end_line": 142, "lines": [ { "line": 130, "text": " static QString pack32bits(quint32 packed);" }, { "line": 131, "text": "" }, { "line": 132, "text": " static quint64 unpack64bits(QString const &value);" }, { "line": 133, "text": " static QString pack64bits(quint64 packed);" }, { "line": 134, "text": "" }, { "line": 135, "text": " static quint64 unpack72bits(QString const &value, quint8 *pRem);" }, { "line": 136, "text": " static QString pack72bits(quint64 value, quint8 rem);" }, { "line": 137, "text": "" }, { "line": 138, "text": " static quint32 packAlphaNumeric22(QString const &value, bool isFlag);" }, { "line": 139, "text": " static QString unpackAlphaNumeric22(quint32 packed, bool *isFlag);" }, { "line": 140, "text": "" }, { "line": 141, "text": " static quint64 packAlphaNumeric50(QString const &value);" }, { "line": 142, "text": " static QString unpackAlphaNumeric50(quint64 packed);" } ] } }, { "line": 141, "matches": [ "pack" ], "snippet": { "start_line": 135, "end_line": 147, "lines": [ { "line": 135, "text": " static quint64 unpack72bits(QString const &value, quint8 *pRem);" }, { "line": 136, "text": " static QString pack72bits(quint64 value, quint8 rem);" }, { "line": 137, "text": "" }, { "line": 138, "text": " static quint32 packAlphaNumeric22(QString const &value, bool isFlag);" }, { "line": 139, "text": " static QString unpackAlphaNumeric22(quint32 packed, bool *isFlag);" }, { "line": 140, "text": "" }, { "line": 141, "text": " static quint64 packAlphaNumeric50(QString const &value);" }, { "line": 142, "text": " static QString unpackAlphaNumeric50(quint64 packed);" }, { "line": 143, "text": "" }, { "line": 144, "text": " static quint32 packCallsign(QString const &value, bool *pPortable);" }, { "line": 145, "text": " static QString unpackCallsign(quint32 value, bool portable);" }, { "line": 146, "text": "" }, { "line": 147, "text": " static QString deg2grid(float dlong, float dlat);" } ] } }, { "line": 149, "matches": [ "pack" ], "snippet": { "start_line": 143, "end_line": 155, "lines": [ { "line": 143, "text": "" }, { "line": 144, "text": " static quint32 packCallsign(QString const &value, bool *pPortable);" }, { "line": 145, "text": " static QString unpackCallsign(quint32 value, bool portable);" }, { "line": 146, "text": "" }, { "line": 147, "text": " static QString deg2grid(float dlong, float dlat);" }, { "line": 148, "text": " static QPair grid2deg(QString const &grid);" }, { "line": 149, "text": " static quint16 packGrid(QString const &value);" }, { "line": 150, "text": " static QString unpackGrid(quint16 value);" }, { "line": 151, "text": "" }, { "line": 152, "text": " static quint8 packNum(QString const &num, bool *ok);" }, { "line": 153, "text": " static quint8 packPwr(QString const &pwr, bool *ok);" }, { "line": 154, "text": " static quint8 packCmd(quint8 cmd, quint8 num, bool *pPackedNum);" }, { "line": 155, "text": " static quint8 unpackCmd(quint8 value, quint8 *pNum);" } ] } }, { "line": 152, "matches": [ "pack" ], "snippet": { "start_line": 146, "end_line": 158, "lines": [ { "line": 146, "text": "" }, { "line": 147, "text": " static QString deg2grid(float dlong, float dlat);" }, { "line": 148, "text": " static QPair grid2deg(QString const &grid);" }, { "line": 149, "text": " static quint16 packGrid(QString const &value);" }, { "line": 150, "text": " static QString unpackGrid(quint16 value);" }, { "line": 151, "text": "" }, { "line": 152, "text": " static quint8 packNum(QString const &num, bool *ok);" }, { "line": 153, "text": " static quint8 packPwr(QString const &pwr, bool *ok);" }, { "line": 154, "text": " static quint8 packCmd(quint8 cmd, quint8 num, bool *pPackedNum);" }, { "line": 155, "text": " static quint8 unpackCmd(quint8 value, quint8 *pNum);" }, { "line": 156, "text": "" }, { "line": 157, "text": " static bool isSNRCommand(const QString &cmd);" }, { "line": 158, "text": " static bool isCommandAllowed(const QString &cmd);" } ] } }, { "line": 166, "matches": [ "pack", "message" ], "snippet": { "start_line": 160, "end_line": 172, "lines": [ { "line": 160, "text": " static int isCommandChecksumed(const QString &cmd);" }, { "line": 161, "text": " static bool isCommandAutoreply(const QString &cmd);" }, { "line": 162, "text": " static bool isValidCallsign(const QString &callsign, bool *pIsCompound);" }, { "line": 163, "text": " static bool isCompoundCallsign(const QString &callsign);" }, { "line": 164, "text": " static bool isGroupAllowed(const QString &group);" }, { "line": 165, "text": "" }, { "line": 166, "text": " static QString packHeartbeatMessage(QString const &text," }, { "line": 167, "text": " QString const &callsign, int *n);" }, { "line": 168, "text": " static QStringList unpackHeartbeatMessage(const QString &text," }, { "line": 169, "text": " quint8 *pType, bool *isAlt," }, { "line": 170, "text": " quint8 *pBits3);" }, { "line": 171, "text": "" }, { "line": 172, "text": " static QString packCompoundMessage(QString const &text, int *n);" } ] } }, { "line": 172, "matches": [ "pack", "message" ], "snippet": { "start_line": 166, "end_line": 178, "lines": [ { "line": 166, "text": " static QString packHeartbeatMessage(QString const &text," }, { "line": 167, "text": " QString const &callsign, int *n);" }, { "line": 168, "text": " static QStringList unpackHeartbeatMessage(const QString &text," }, { "line": 169, "text": " quint8 *pType, bool *isAlt," }, { "line": 170, "text": " quint8 *pBits3);" }, { "line": 171, "text": "" }, { "line": 172, "text": " static QString packCompoundMessage(QString const &text, int *n);" }, { "line": 173, "text": " static QStringList unpackCompoundMessage(const QString &text, quint8 *pType," }, { "line": 174, "text": " quint8 *pBits3);" }, { "line": 175, "text": "" }, { "line": 176, "text": " static QString packCompoundFrame(const QString &callsign, quint8 type," }, { "line": 177, "text": " quint16 num, quint8 bits3);" }, { "line": 178, "text": " static QStringList unpackCompoundFrame(const QString &text, quint8 *pType," } ] } }, { "line": 176, "matches": [ "pack" ], "snippet": { "start_line": 170, "end_line": 182, "lines": [ { "line": 170, "text": " quint8 *pBits3);" }, { "line": 171, "text": "" }, { "line": 172, "text": " static QString packCompoundMessage(QString const &text, int *n);" }, { "line": 173, "text": " static QStringList unpackCompoundMessage(const QString &text, quint8 *pType," }, { "line": 174, "text": " quint8 *pBits3);" }, { "line": 175, "text": "" }, { "line": 176, "text": " static QString packCompoundFrame(const QString &callsign, quint8 type," }, { "line": 177, "text": " quint16 num, quint8 bits3);" }, { "line": 178, "text": " static QStringList unpackCompoundFrame(const QString &text, quint8 *pType," }, { "line": 179, "text": " quint16 *pNum, quint8 *pBits3);" }, { "line": 180, "text": "" }, { "line": 181, "text": " static QString packDirectedMessage(QString const &text," }, { "line": 182, "text": " QString const &mycall, QString *pTo," } ] } }, { "line": 181, "matches": [ "pack", "message" ], "snippet": { "start_line": 175, "end_line": 187, "lines": [ { "line": 175, "text": "" }, { "line": 176, "text": " static QString packCompoundFrame(const QString &callsign, quint8 type," }, { "line": 177, "text": " quint16 num, quint8 bits3);" }, { "line": 178, "text": " static QStringList unpackCompoundFrame(const QString &text, quint8 *pType," }, { "line": 179, "text": " quint16 *pNum, quint8 *pBits3);" }, { "line": 180, "text": "" }, { "line": 181, "text": " static QString packDirectedMessage(QString const &text," }, { "line": 182, "text": " QString const &mycall, QString *pTo," }, { "line": 183, "text": " bool *pToCompound, QString *pCmd," }, { "line": 184, "text": " QString *pNum, int *n);" }, { "line": 185, "text": " static QStringList unpackDirectedMessage(QString const &text," }, { "line": 186, "text": " quint8 *pType);" }, { "line": 187, "text": "" } ] } }, { "line": 188, "matches": [ "pack", "message" ], "snippet": { "start_line": 182, "end_line": 194, "lines": [ { "line": 182, "text": " QString const &mycall, QString *pTo," }, { "line": 183, "text": " bool *pToCompound, QString *pCmd," }, { "line": 184, "text": " QString *pNum, int *n);" }, { "line": 185, "text": " static QStringList unpackDirectedMessage(QString const &text," }, { "line": 186, "text": " quint8 *pType);" }, { "line": 187, "text": "" }, { "line": 188, "text": " static QString packDataMessage(QString const &text, int *n);" }, { "line": 189, "text": " static QString unpackDataMessage(QString const &text);" }, { "line": 190, "text": "" }, { "line": 191, "text": " static QString packFastDataMessage(QString const &text, int *n);" }, { "line": 192, "text": " static QString unpackFastDataMessage(QString const &text);" }, { "line": 193, "text": "" }, { "line": 194, "text": " static QList>" } ] } }, { "line": 191, "matches": [ "pack", "message" ], "snippet": { "start_line": 185, "end_line": 197, "lines": [ { "line": 185, "text": " static QStringList unpackDirectedMessage(QString const &text," }, { "line": 186, "text": " quint8 *pType);" }, { "line": 187, "text": "" }, { "line": 188, "text": " static QString packDataMessage(QString const &text, int *n);" }, { "line": 189, "text": " static QString unpackDataMessage(QString const &text);" }, { "line": 190, "text": "" }, { "line": 191, "text": " static QString packFastDataMessage(QString const &text, int *n);" }, { "line": 192, "text": " static QString unpackFastDataMessage(QString const &text);" }, { "line": 193, "text": "" }, { "line": 194, "text": " static QList>" }, { "line": 195, "text": " buildMessageFrames(QString const &mycall, QString const &mygrid," }, { "line": 196, "text": " QString const &selectedCall, QString const &text," }, { "line": 197, "text": " bool forceIdentify, bool forceData, int submode," } ] } }, { "line": 198, "matches": [ "message" ], "snippet": { "start_line": 192, "end_line": 204, "lines": [ { "line": 192, "text": " static QString unpackFastDataMessage(QString const &text);" }, { "line": 193, "text": "" }, { "line": 194, "text": " static QList>" }, { "line": 195, "text": " buildMessageFrames(QString const &mycall, QString const &mygrid," }, { "line": 196, "text": " QString const &selectedCall, QString const &text," }, { "line": 197, "text": " bool forceIdentify, bool forceData, int submode," }, { "line": 198, "text": " MessageInfo *pInfo = nullptr);" }, { "line": 199, "text": "};" }, { "line": 200, "text": "" }, { "line": 201, "text": "class BuildMessageFramesThread : public QThread {" }, { "line": 202, "text": " Q_OBJECT" }, { "line": 203, "text": " public:" }, { "line": 204, "text": " BuildMessageFramesThread(QString const &mycall, QString const &mygrid," } ] } }, { "line": 201, "matches": [ "message" ], "snippet": { "start_line": 195, "end_line": 207, "lines": [ { "line": 195, "text": " buildMessageFrames(QString const &mycall, QString const &mygrid," }, { "line": 196, "text": " QString const &selectedCall, QString const &text," }, { "line": 197, "text": " bool forceIdentify, bool forceData, int submode," }, { "line": 198, "text": " MessageInfo *pInfo = nullptr);" }, { "line": 199, "text": "};" }, { "line": 200, "text": "" }, { "line": 201, "text": "class BuildMessageFramesThread : public QThread {" }, { "line": 202, "text": " Q_OBJECT" }, { "line": 203, "text": " public:" }, { "line": 204, "text": " BuildMessageFramesThread(QString const &mycall, QString const &mygrid," }, { "line": 205, "text": " QString const &selectedCall, QString const &text," }, { "line": 206, "text": " bool forceIdentify, bool forceData, int submode," }, { "line": 207, "text": " QObject *parent = nullptr);" } ] } } ] }, { "path": "JS8_JSC/JSC_map.cpp", "exists": true, "bytes": 7082880, "sha256": "ab2bd62ef594f4629a2c93b6de43f5469b1fd6fe67ebf4d24f915bd11ccef813", "line_count": 262172, "phase_hits": { "timing_submode": 0, "symbol_to_soft_bits": 590, "bit_order_interleaver": 398, "whitening_erasure": 119, "ldpc_decode": 6, "message91_crc_text": 152 }, "function_blocks": [], "keyword_snippets": [ { "line": 2, "matches": [ "map", "JSC" ], "snippet": { "start_line": 1, "end_line": 8, "lines": [ { "line": 1, "text": "/**" }, { "line": 2, "text": " * @file JSC_map.cpp" }, { "line": 3, "text": " * @brief Implementation of JSC character map" }, { "line": 4, "text": " *" }, { "line": 5, "text": " * This file is part of JS8Call." }, { "line": 6, "text": " *" }, { "line": 7, "text": " * This program is free software: you can redistribute it and/or modify" }, { "line": 8, "text": " * it under the terms of the GNU General Public License as published by" } ] } }, { "line": 23, "matches": [ "JSC" ], "snippet": { "start_line": 17, "end_line": 29, "lines": [ { "line": 17, "text": " * You should have received a copy of the GNU General Public License" }, { "line": 18, "text": " * along with this program. If not, see ." }, { "line": 19, "text": " *" }, { "line": 20, "text": " * (C) 2018 Jordan Sherer - All Rights Reserved" }, { "line": 21, "text": " */" }, { "line": 22, "text": "" }, { "line": 23, "text": "#include \"JSC.h\"" }, { "line": 24, "text": "" }, { "line": 25, "text": "const Tuple JSC::map[262144] = {" }, { "line": 26, "text": " // str, len, index" }, { "line": 27, "text": " {\"E\", 1, 0}," }, { "line": 28, "text": " {\"T\", 1, 1}," }, { "line": 29, "text": " {\"A\", 1, 2}," } ] } }, { "line": 2142, "matches": [ "map" ], "snippet": { "start_line": 2136, "end_line": 2148, "lines": [ { "line": 2136, "text": " {\"PER\", 3, 2108}," }, { "line": 2137, "text": " {\"FIRE\", 4, 2109}," }, { "line": 2138, "text": " {\"YKO\", 3, 2110}," }, { "line": 2139, "text": " {\"CAMERAS\", 7, 2111}," }, { "line": 2140, "text": " {\"HEFA\", 4, 2112}," }, { "line": 2141, "text": " {\"OGW\", 3, 2113}," }, { "line": 2142, "text": " {\"MAPS\", 4, 2114}," }, { "line": 2143, "text": " {\"NGWI\", 4, 2115}," }, { "line": 2144, "text": " {\"SPORT\", 5, 2116}," }, { "line": 2145, "text": " {\"UXI\", 3, 2117}," }, { "line": 2146, "text": " {\"BANK\", 4, 2118}," }, { "line": 2147, "text": " {\"RATINGS\", 7, 2119}," }, { "line": 2148, "text": " {\"WRONG\", 5, 2120}," } ] } }, { "line": 3552, "matches": [ "map" ], "snippet": { "start_line": 3546, "end_line": 3558, "lines": [ { "line": 3546, "text": " {\"YLY\", 3, 3518}," }, { "line": 3547, "text": " {\"WASB\", 4, 3519}," }, { "line": 3548, "text": " {\"LYBE\", 4, 3520}," }, { "line": 3549, "text": " {\"IMMEDIATELY\", 11, 3521}," }, { "line": 3550, "text": " {\"ELEMENT\", 7, 3522}," }, { "line": 3551, "text": " {\"CONVERSATION\", 12, 3523}," }, { "line": 3552, "text": " {\"SITEMAP\", 7, 3524}," }, { "line": 3553, "text": " {\"RECOMMENDATIONS\", 15, 3525}," }, { "line": 3554, "text": " {\"ECHN\", 4, 3526}," }, { "line": 3555, "text": " {\"MOVED\", 5, 3527}," }, { "line": 3556, "text": " {\"HOUSTON\", 7, 3528}," }, { "line": 3557, "text": " {\"PMEN\", 4, 3529}," }, { "line": 3558, "text": " {\"IONP\", 4, 3530}," } ] } }, { "line": 3673, "matches": [ "code" ], "snippet": { "start_line": 3667, "end_line": 3679, "lines": [ { "line": 3667, "text": " {\"UALI\", 4, 3639}," }, { "line": 3668, "text": " {\"ATTEMPT\", 7, 3640}," }, { "line": 3669, "text": " {\"RUSSIA\", 6, 3641}," }, { "line": 3670, "text": " {\"VATI\", 4, 3642}," }, { "line": 3671, "text": " {\"ITAN\", 4, 3643}," }, { "line": 3672, "text": " {\"GONE\", 4, 3644}," }, { "line": 3673, "text": " {\"CODES\", 5, 3645}," }, { "line": 3674, "text": " {\"KINDS\", 5, 3646}," }, { "line": 3675, "text": " {\"BEGINNING\", 9, 3647}," }, { "line": 3676, "text": " {\"SEATTLE\", 7, 3648}," }, { "line": 3677, "text": " {\"ARDT\", 4, 3649}," }, { "line": 3678, "text": " {\"LCON\", 4, 3650}," }, { "line": 3679, "text": " {\"RESIDENT\", 8, 3651}," } ] } }, { "line": 4835, "matches": [ "map" ], "snippet": { "start_line": 4829, "end_line": 4841, "lines": [ { "line": 4829, "text": " {\"OBJECTIVES\", 10, 4801}," }, { "line": 4830, "text": " {\"NTWA\", 4, 4802}," }, { "line": 4831, "text": " {\"SCIENTIFIC\", 10, 4803}," }, { "line": 4832, "text": " {\"STATIONS\", 8, 4804}," }, { "line": 4833, "text": " {\"EOPE\", 4, 4805}," }, { "line": 4834, "text": " {\"EMOC\", 4, 4806}," }, { "line": 4835, "text": " {\"MAP\", 3, 4807}," }, { "line": 4836, "text": " {\"ERIG\", 4, 4808}," }, { "line": 4837, "text": " {\"SUGGESTED\", 9, 4809}," }, { "line": 4838, "text": " {\"GPS\", 3, 4810}," }, { "line": 4839, "text": " {\"OKV\", 3, 4811}," }, { "line": 4840, "text": " {\"MENTAL\", 6, 4812}," }, { "line": 4841, "text": " {\"REMAINS\", 7, 4813}," } ] } }, { "line": 5154, "matches": [ "code" ], "snippet": { "start_line": 5148, "end_line": 5160, "lines": [ { "line": 5148, "text": " {\"IONM\", 4, 5120}," }, { "line": 5149, "text": " {\"DWOR\", 4, 5121}," }, { "line": 5150, "text": " {\"SIGNIFICANTLY\", 13, 5122}," }, { "line": 5151, "text": " {\"SPEAKING\", 8, 5123}," }, { "line": 5152, "text": " {\"INTERNAL\", 8, 5124}," }, { "line": 5153, "text": " {\"PHOTOGRAPH\", 10, 5125}," }, { "line": 5154, "text": " {\"CODE\", 4, 5126}," }, { "line": 5155, "text": " {\"SPONSORS\", 8, 5127}," }, { "line": 5156, "text": " {\"FOX\", 3, 5128}," }, { "line": 5157, "text": " {\"UNLIMITED\", 9, 5129}," }, { "line": 5158, "text": " {\"NLYT\", 4, 5130}," }, { "line": 5159, "text": " {\"SETTING\", 7, 5131}," }, { "line": 5160, "text": " {\"NGDO\", 4, 5132}," } ] } }, { "line": 6012, "matches": [ "bits" ], "snippet": { "start_line": 6006, "end_line": 6018, "lines": [ { "line": 6006, "text": " {\"GPRO\", 4, 5978}," }, { "line": 6007, "text": " {\"WNTH\", 4, 5979}," }, { "line": 6008, "text": " {\"STOG\", 4, 5980}," }, { "line": 6009, "text": " {\"FLOW\", 4, 5981}," }, { "line": 6010, "text": " {\"WTHA\", 4, 5982}," }, { "line": 6011, "text": " {\"BEACH\", 5, 5983}," }, { "line": 6012, "text": " {\"BITS\", 4, 5984}," }, { "line": 6013, "text": " {\"HOUSEHOLD\", 9, 5985}," }, { "line": 6014, "text": " {\"NDMI\", 4, 5986}," }, { "line": 6015, "text": " {\"ATWI\", 4, 5987}," }, { "line": 6016, "text": " {\"CREAM\", 5, 5988}," }, { "line": 6017, "text": " {\"EXPERIMENT\", 10, 5989}," }, { "line": 6018, "text": " {\"OUHA\", 4, 5990}," } ] } }, { "line": 6084, "matches": [ "map" ], "snippet": { "start_line": 6078, "end_line": 6090, "lines": [ { "line": 6078, "text": " {\"COPY\", 4, 6050}," }, { "line": 6079, "text": " {\"LOVED\", 5, 6051}," }, { "line": 6080, "text": " {\"ALLB\", 4, 6052}," }, { "line": 6081, "text": " {\"NGRO\", 4, 6053}," }, { "line": 6082, "text": " {\"FAVOURITES\", 10, 6054}," }, { "line": 6083, "text": " {\"ERPO\", 4, 6055}," }, { "line": 6084, "text": " {\"MAPPING\", 7, 6056}," }, { "line": 6085, "text": " {\"LIBERAL\", 7, 6057}," }, { "line": 6086, "text": " {\"FEWER\", 5, 6058}," }, { "line": 6087, "text": " {\"OWHE\", 4, 6059}," }, { "line": 6088, "text": " {\"BIRDS\", 5, 6060}," }, { "line": 6089, "text": " {\"DEFINITELY\", 10, 6061}," }, { "line": 6090, "text": " {\"REPRESENTS\", 10, 6062}," } ] } }, { "line": 29018, "matches": [ "map" ], "snippet": { "start_line": 29012, "end_line": 29024, "lines": [ { "line": 29012, "text": " {\"YSOM\", 4, 28984}," }, { "line": 29013, "text": " {\"MIRACLE\", 7, 28985}," }, { "line": 29014, "text": " {\"TALT\", 4, 28986}," }, { "line": 29015, "text": " {\"CHASE\", 5, 28987}," }, { "line": 29016, "text": " {\"STYLISH\", 7, 28988}," }, { "line": 29017, "text": " {\"SLIM\", 4, 28989}," }, { "line": 29018, "text": " {\"MAPLE\", 5, 28990}," }, { "line": 29019, "text": " {\"LUKE\", 4, 28991}," }, { "line": 29020, "text": " {\"ARCHITECT\", 9, 28992}," }, { "line": 29021, "text": " {\"GWHI\", 4, 28993}," }, { "line": 29022, "text": " {\"LTOT\", 4, 28994}," }, { "line": 29023, "text": " {\"SQB\", 3, 28995}," }, { "line": 29024, "text": " {\"PIANO\", 5, 28996}," } ] } }, { "line": 31660, "matches": [ "bits" ], "snippet": { "start_line": 31654, "end_line": 31666, "lines": [ { "line": 31654, "text": " {\"KELKOO\", 6, 31626}," }, { "line": 31655, "text": " {\"STEEP\", 5, 31627}," }, { "line": 31656, "text": " {\"O'CLOCK\", 7, 31628}," }, { "line": 31657, "text": " {\"ADOU\", 4, 31629}," }, { "line": 31658, "text": " {\"YPOL\", 4, 31630}," }, { "line": 31659, "text": " {\"RETRIEVED\", 9, 31631}," }, { "line": 31660, "text": " {\"EXHIBITS\", 8, 31632}," }, { "line": 31661, "text": " {\"OLOS\", 4, 31633}," }, { "line": 31662, "text": " {\"CONSORTIUM\", 10, 31634}," }, { "line": 31663, "text": " {\"DIES\", 4, 31635}," }, { "line": 31664, "text": " {\"UWAN\", 4, 31636}," }, { "line": 31665, "text": " {\"TERRACE\", 7, 31637}," }, { "line": 31666, "text": " {\"SHARPLY\", 7, 31638}," } ] } }, { "line": 34407, "matches": [ "bits" ], "snippet": { "start_line": 34401, "end_line": 34413, "lines": [ { "line": 34401, "text": " {\"EKSA\", 4, 34373}," }, { "line": 34402, "text": " {\"GUED\", 4, 34374}," }, { "line": 34403, "text": " {\"SOWH\", 4, 34375}," }, { "line": 34404, "text": " {\"ASGI\", 4, 34376}," }, { "line": 34405, "text": " {\"COMPARABLE\", 10, 34377}," }, { "line": 34406, "text": " {\"ONOV\", 4, 34378}," }, { "line": 34407, "text": " {\"HABITS\", 6, 34379}," }, { "line": 34408, "text": " {\"YOFL\", 4, 34380}," }, { "line": 34409, "text": " {\"SAFR\", 4, 34381}," }, { "line": 34410, "text": " {\"INFECTIOUS\", 10, 34382}," }, { "line": 34411, "text": " {\"PODCASTS\", 8, 34383}," }, { "line": 34412, "text": " {\"STEAK\", 5, 34384}," }, { "line": 34413, "text": " {\"GEDB\", 4, 34385}," } ] } }, { "line": 37431, "matches": [ "code" ], "snippet": { "start_line": 37425, "end_line": 37437, "lines": [ { "line": 37425, "text": " {\"ATFR\", 4, 37397}," }, { "line": 37426, "text": " {\"LDFI\", 4, 37398}," }, { "line": 37427, "text": " {\"SHIFTS\", 6, 37399}," }, { "line": 37428, "text": " {\"INACTIVE\", 8, 37400}," }, { "line": 37429, "text": " {\"LANSING\", 7, 37401}," }, { "line": 37430, "text": " {\"TRAVELED\", 8, 37402}," }, { "line": 37431, "text": " {\"BARCODE\", 7, 37403}," }, { "line": 37432, "text": " {\"WINC\", 4, 37404}," }, { "line": 37433, "text": " {\"TSBY\", 4, 37405}," }, { "line": 37434, "text": " {\"PECU\", 4, 37406}," }, { "line": 37435, "text": " {\"EXTRACTED\", 9, 37407}," }, { "line": 37436, "text": " {\"URTR\", 4, 37408}," }, { "line": 37437, "text": " {\"ACCESSION\", 9, 37409}," } ] } }, { "line": 37459, "matches": [ "code" ], "snippet": { "start_line": 37453, "end_line": 37465, "lines": [ { "line": 37453, "text": " {\"HIPB\", 4, 37425}," }, { "line": 37454, "text": " {\"FUELS\", 5, 37426}," }, { "line": 37455, "text": " {\"UTBY\", 4, 37427}," }, { "line": 37456, "text": " {\"ELFW\", 4, 37428}," }, { "line": 37457, "text": " {\"GERF\", 4, 37429}," }, { "line": 37458, "text": " {\"ELYL\", 4, 37430}," }, { "line": 37459, "text": " {\"POSTCODE\", 8, 37431}," }, { "line": 37460, "text": " {\"DATR\", 4, 37432}," }, { "line": 37461, "text": " {\"SFRA\", 4, 37433}," }, { "line": 37462, "text": " {\"BRETT\", 5, 37434}," }, { "line": 37463, "text": " {\"EJAP\", 4, 37435}," }, { "line": 37464, "text": " {\"MAKEFILE\", 8, 37436}," }, { "line": 37465, "text": " {\"ULOU\", 4, 37437}," } ] } }, { "line": 38181, "matches": [ "code" ], "snippet": { "start_line": 38175, "end_line": 38187, "lines": [ { "line": 38175, "text": " {\"RECOGNIZES\", 10, 38147}," }, { "line": 38176, "text": " {\"PLUGS\", 5, 38148}," }, { "line": 38177, "text": " {\"DOFO\", 4, 38149}," }, { "line": 38178, "text": " {\"GUPA\", 4, 38150}," }, { "line": 38179, "text": " {\"RESPONSIVE\", 10, 38151}," }, { "line": 38180, "text": " {\"DFAI\", 4, 38152}," }, { "line": 38181, "text": " {\"CODED\", 5, 38153}," }, { "line": 38182, "text": " {\"SUPRA\", 5, 38154}," }, { "line": 38183, "text": " {\"OMITTED\", 7, 38155}," }, { "line": 38184, "text": " {\"NFIV\", 4, 38156}," }, { "line": 38185, "text": " {\"MOLLY\", 5, 38157}," }, { "line": 38186, "text": " {\"PROXIMITY\", 9, 38158}," }, { "line": 38187, "text": " {\"WWHE\", 4, 38159}," } ] } }, { "line": 40590, "matches": [ "code" ], "snippet": { "start_line": 40584, "end_line": 40596, "lines": [ { "line": 40584, "text": " {\"SWINGING\", 8, 40556}," }, { "line": 40585, "text": " {\"ACCOUNTABLE\", 11, 40557}," }, { "line": 40586, "text": " {\"THRUST\", 6, 40558}," }, { "line": 40587, "text": " {\"PROVING\", 7, 40559}," }, { "line": 40588, "text": " {\"ZWR\", 3, 40560}," }, { "line": 40589, "text": " {\"QUEA\", 4, 40561}," }, { "line": 40590, "text": " {\"UNICODE\", 7, 40562}," }, { "line": 40591, "text": " {\"OPPOSING\", 8, 40563}," }, { "line": 40592, "text": " {\"PROD\", 4, 40564}," }, { "line": 40593, "text": " {\"OCOV\", 4, 40565}," }, { "line": 40594, "text": " {\"NOVICE\", 6, 40566}," }, { "line": 40595, "text": " {\"NLYN\", 4, 40567}," }, { "line": 40596, "text": " {\"LEQU\", 4, 40568}," } ] } }, { "line": 40615, "matches": [ "code" ], "snippet": { "start_line": 40609, "end_line": 40621, "lines": [ { "line": 40609, "text": " {\"CRUISING\", 8, 40581}," }, { "line": 40610, "text": " {\"AFIL\", 4, 40582}," }, { "line": 40611, "text": " {\"FURY\", 4, 40583}," }, { "line": 40612, "text": " {\"PERSONALITIES\", 13, 40584}," }, { "line": 40613, "text": " {\"DISCOGRAPHY\", 11, 40585}," }, { "line": 40614, "text": " {\"ECAB\", 4, 40586}," }, { "line": 40615, "text": " {\"ENCODED\", 7, 40587}," }, { "line": 40616, "text": " {\"LSUR\", 4, 40588}," }, { "line": 40617, "text": " {\"ABAM\", 4, 40589}," }, { "line": 40618, "text": " {\"RESEARCHING\", 11, 40590}," }, { "line": 40619, "text": " {\"WORE\", 4, 40591}," }, { "line": 40620, "text": " {\"CHRISTCHURCH\", 12, 40592}," }, { "line": 40621, "text": " {\"LZM\", 3, 40593}," } ] } }, { "line": 40648, "matches": [ "map" ], "snippet": { "start_line": 40642, "end_line": 40654, "lines": [ { "line": 40642, "text": " {\"SCATTERING\", 10, 40614}," }, { "line": 40643, "text": " {\"RGUA\", 4, 40615}," }, { "line": 40644, "text": " {\"DIDY\", 4, 40616}," }, { "line": 40645, "text": " {\"SECRETARIES\", 11, 40617}," }, { "line": 40646, "text": " {\"ONSITE\", 6, 40618}," }, { "line": 40647, "text": " {\"RUNW\", 4, 40619}," }, { "line": 40648, "text": " {\"MAPQUEST\", 8, 40620}," }, { "line": 40649, "text": " {\"CONTRACTED\", 10, 40621}," }, { "line": 40650, "text": " {\"MGOI\", 4, 40622}," }, { "line": 40651, "text": " {\"DEIG\", 4, 40623}," }, { "line": 40652, "text": " {\"FIGHTS\", 6, 40624}," }, { "line": 40653, "text": " {\"DELETING\", 8, 40625}," }, { "line": 40654, "text": " {\"ECTB\", 4, 40626}," } ] } }, { "line": 41342, "matches": [ "map" ], "snippet": { "start_line": 41336, "end_line": 41348, "lines": [ { "line": 41336, "text": " {\"LUED\", 4, 41308}," }, { "line": 41337, "text": " {\"REVEALING\", 9, 41309}," }, { "line": 41338, "text": " {\"DATM\", 4, 41310}," }, { "line": 41339, "text": " {\"FGAM\", 4, 41311}," }, { "line": 41340, "text": " {\"REPRINTED\", 9, 41312}," }, { "line": 41341, "text": " {\"FERNANDO\", 8, 41313}," }, { "line": 41342, "text": " {\"MAPPED\", 6, 41314}," }, { "line": 41343, "text": " {\"SORW\", 4, 41315}," }, { "line": 41344, "text": " {\"IERW\", 4, 41316}," }, { "line": 41345, "text": " {\"RESURRECTION\", 12, 41317}," }, { "line": 41346, "text": " {\"LIEU\", 4, 41318}," }, { "line": 41347, "text": " {\"DECREE\", 6, 41319}," }, { "line": 41348, "text": " {\"YUNT\", 4, 41320}," } ] } }, { "line": 42365, "matches": [ "code" ], "snippet": { "start_line": 42359, "end_line": 42371, "lines": [ { "line": 42359, "text": " {\"DECKER\", 6, 42331}," }, { "line": 42360, "text": " {\"EXTERN\", 6, 42332}," }, { "line": 42361, "text": " {\"SORF\", 4, 42333}," }, { "line": 42362, "text": " {\"BADGES\", 6, 42334}," }, { "line": 42363, "text": " {\"ENRON\", 5, 42335}," }, { "line": 42364, "text": " {\"KITTEN\", 6, 42336}," }, { "line": 42365, "text": " {\"CODEC\", 5, 42337}," }, { "line": 42366, "text": " {\"FBUT\", 4, 42338}," }, { "line": 42367, "text": " {\"BROADCASTS\", 10, 42339}," }, { "line": 42368, "text": " {\"BRIDES\", 6, 42340}," }, { "line": 42369, "text": " {\"IXTU\", 4, 42341}," }, { "line": 42370, "text": " {\"CHECKSUM\", 8, 42342}," }, { "line": 42371, "text": " {\"STEALING\", 8, 42343}," } ] } }, { "line": 42614, "matches": [ "bits" ], "snippet": { "start_line": 42608, "end_line": 42620, "lines": [ { "line": 42608, "text": " {\"OQUA\", 4, 42580}," }, { "line": 42609, "text": " {\"MALAYSIAN\", 9, 42581}," }, { "line": 42610, "text": " {\"EAUC\", 4, 42582}," }, { "line": 42611, "text": " {\"CLUES\", 5, 42583}," }, { "line": 42612, "text": " {\"INFLAMMATION\", 12, 42584}," }, { "line": 42613, "text": " {\"QUEB\", 4, 42585}," }, { "line": 42614, "text": " {\"RABBITS\", 7, 42586}," }, { "line": 42615, "text": " {\"PSFO\", 4, 42587}," }, { "line": 42616, "text": " {\"ORAV\", 4, 42588}," }, { "line": 42617, "text": " {\"TRANSPORTED\", 11, 42589}," }, { "line": 42618, "text": " {\"CREWS\", 5, 42590}," }, { "line": 42619, "text": " {\"TOFY\", 4, 42591}," }, { "line": 42620, "text": " {\"EASTON\", 6, 42592}," } ] } }, { "line": 43476, "matches": [ "code" ], "snippet": { "start_line": 43470, "end_line": 43482, "lines": [ { "line": 43470, "text": " {\"BLASTER\", 7, 43442}," }, { "line": 43471, "text": " {\"YORD\", 4, 43443}," }, { "line": 43472, "text": " {\"DDAT\", 4, 43444}," }, { "line": 43473, "text": " {\"TVIR\", 4, 43445}," }, { "line": 43474, "text": " {\"REMEDIATION\", 11, 43446}," }, { "line": 43475, "text": " {\"WASTING\", 7, 43447}," }, { "line": 43476, "text": " {\"DECODER\", 7, 43448}," }, { "line": 43477, "text": " {\"FELO\", 4, 43449}," }, { "line": 43478, "text": " {\"GENOCIDE\", 8, 43450}," }, { "line": 43479, "text": " {\"ACCLAIMED\", 9, 43451}," }, { "line": 43480, "text": " {\"HEATHROW\", 8, 43452}," }, { "line": 43481, "text": " {\"INDY\", 4, 43453}," }, { "line": 43482, "text": " {\"URWI\", 4, 43454}," } ] } } ] }, { "path": "JS8_JSC/JSC_list.cpp", "exists": true, "bytes": 7085560, "sha256": "993811813f1cd6e00e399f25352a34ae477b7e1b50745204c32d3df0058a0491", "line_count": 262278, "phase_hits": { "timing_submode": 0, "symbol_to_soft_bits": 590, "bit_order_interleaver": 398, "whitening_erasure": 119, "ldpc_decode": 6, "message91_crc_text": 153 }, "function_blocks": [], "keyword_snippets": [ { "line": 2, "matches": [ "list", "JSC" ], "snippet": { "start_line": 1, "end_line": 8, "lines": [ { "line": 1, "text": "/**" }, { "line": 2, "text": " * @file JSC_list.cpp" }, { "line": 3, "text": " * @brief Tuple list for JSC callsigns" }, { "line": 4, "text": " *" }, { "line": 5, "text": " * This file is part of JS8Call." }, { "line": 6, "text": " *" }, { "line": 7, "text": " * This program is free software: you can redistribute it and/or modify" }, { "line": 8, "text": " * it under the terms of the GNU General Public License as published by" } ] } }, { "line": 23, "matches": [ "JSC" ], "snippet": { "start_line": 17, "end_line": 29, "lines": [ { "line": 17, "text": " * You should have received a copy of the GNU General Public License" }, { "line": 18, "text": " * along with this program. If not, see ." }, { "line": 19, "text": " *" }, { "line": 20, "text": " * (C) 2018 Jordan Sherer - All Rights Reserved" }, { "line": 21, "text": " */" }, { "line": 22, "text": "" }, { "line": 23, "text": "#include \"JSC.h\"" }, { "line": 24, "text": "" }, { "line": 25, "text": "const Tuple JSC::list[262144] = {" }, { "line": 26, "text": " // str, len, index" }, { "line": 27, "text": " {\"~\", 1, 66}," }, { "line": 28, "text": " {\"}\", 1, 61}," }, { "line": 29, "text": " {\"|\", 1, 62}," } ] } }, { "line": 1142, "matches": [ "code" ], "snippet": { "start_line": 1136, "end_line": 1148, "lines": [ { "line": 1136, "text": " {\"ZIPING\", 6, 205320}," }, { "line": 1137, "text": " {\"ZIPI\", 4, 178964}," }, { "line": 1138, "text": " {\"ZIPFILE\", 7, 197461}," }, { "line": 1139, "text": " {\"ZIPF\", 4, 181942}," }, { "line": 1140, "text": " {\"ZIPE\", 4, 218162}," }, { "line": 1141, "text": " {\"ZIPDATA\", 7, 195897}," }, { "line": 1142, "text": " {\"ZIPCODES\", 8, 134542}," }, { "line": 1143, "text": " {\"ZIPCODE\", 7, 55313}," }, { "line": 1144, "text": " {\"ZIPC\", 4, 92212}," }, { "line": 1145, "text": " {\"ZIPA\", 4, 103112}," }, { "line": 1146, "text": " {\"ZIP\", 3, 284}," }, { "line": 1147, "text": " {\"ZIOW\", 4, 201565}," }, { "line": 1148, "text": " {\"ZIOR\", 4, 179771}," } ] } }, { "line": 1206, "matches": [ "list" ], "snippet": { "start_line": 1200, "end_line": 1212, "lines": [ { "line": 1200, "text": " {\"ZIMMERLI\", 8, 223980}," }, { "line": 1201, "text": " {\"ZIMMER\", 6, 56556}," }, { "line": 1202, "text": " {\"ZIMM\", 4, 233412}," }, { "line": 1203, "text": " {\"ZIMI\", 4, 128387}," }, { "line": 1204, "text": " {\"ZIME\", 4, 216448}," }, { "line": 1205, "text": " {\"ZIMBRA\", 6, 140743}," }, { "line": 1206, "text": " {\"ZIMBALIST\", 9, 209838}," }, { "line": 1207, "text": " {\"ZIMBABWEANS\", 11, 139393}," }, { "line": 1208, "text": " {\"ZIMBABWEAN\", 10, 92913}," }, { "line": 1209, "text": " {\"ZIMBABWE\", 8, 28311}," }, { "line": 1210, "text": " {\"ZIMBABAWE\", 9, 228606}," }, { "line": 1211, "text": " {\"ZIMB\", 4, 53822}," }, { "line": 1212, "text": " {\"ZIMAGE\", 6, 230394}," } ] } }, { "line": 8185, "matches": [ "code" ], "snippet": { "start_line": 8179, "end_line": 8191, "lines": [ { "line": 8179, "text": " {\"XCOP\", 4, 208111}," }, { "line": 8180, "text": " {\"XCOO\", 4, 254220}," }, { "line": 8181, "text": " {\"XCONQ\", 5, 169112}," }, { "line": 8182, "text": " {\"XCONFIG\", 7, 209763}," }, { "line": 8183, "text": " {\"XCOM\", 4, 204470}," }, { "line": 8184, "text": " {\"XCOL\", 4, 81498}," }, { "line": 8185, "text": " {\"XCODE\", 5, 101097}," }, { "line": 8186, "text": " {\"XCOD\", 4, 118995}," }, { "line": 8187, "text": " {\"XCOA\", 4, 174454}," }, { "line": 8188, "text": " {\"XCO\", 3, 1141}," }, { "line": 8189, "text": " {\"XCLUSIVE\", 8, 246585}," }, { "line": 8190, "text": " {\"XCLU\", 4, 32546}," }, { "line": 8191, "text": " {\"XCLO\", 4, 117585}," } ] } }, { "line": 8878, "matches": [ "list" ], "snippet": { "start_line": 8872, "end_line": 8884, "lines": [ { "line": 8872, "text": " {\"WWWDRAGONBALL\", 13, 233935}," }, { "line": 8873, "text": " {\"WWWDOWNLOAD\", 11, 233591}," }, { "line": 8874, "text": " {\"WWWDOGPILECOM\", 13, 233831}," }, { "line": 8875, "text": " {\"WWWDOCS\", 7, 213725}," }, { "line": 8876, "text": " {\"WWWDMVGOV\", 9, 234103}," }, { "line": 8877, "text": " {\"WWWDMVCAGOV\", 11, 234071}," }, { "line": 8878, "text": " {\"WWWDLISTATEPAUS\", 15, 234104}," }, { "line": 8879, "text": " {\"WWWDISNEY\", 9, 232637}," }, { "line": 8880, "text": " {\"WWWDISCOVERY\", 12, 234005}," }, { "line": 8881, "text": " {\"WWWDIGIMON\", 10, 234050}," }, { "line": 8882, "text": " {\"WWWDELLCOM\", 10, 233038}," }, { "line": 8883, "text": " {\"WWWDELL\", 7, 232526}," }, { "line": 8884, "text": " {\"WWWDAUMNET\", 10, 233936}," } ] } }, { "line": 10115, "matches": [ "list" ], "snippet": { "start_line": 10109, "end_line": 10121, "lines": [ { "line": 10109, "text": " {\"WORKMANS\", 8, 252910}," }, { "line": 10110, "text": " {\"WORKMANLIKE\", 11, 193541}," }, { "line": 10111, "text": " {\"WORKMAN\", 7, 64785}," }, { "line": 10112, "text": " {\"WORKLOG\", 7, 249332}," }, { "line": 10113, "text": " {\"WORKLOADS\", 9, 78358}," }, { "line": 10114, "text": " {\"WORKLOAD\", 8, 43287}," }, { "line": 10115, "text": " {\"WORKLIST\", 8, 160843}," }, { "line": 10116, "text": " {\"WORKLIFE\", 8, 135827}," }, { "line": 10117, "text": " {\"WORKKEYS\", 8, 223452}," }, { "line": 10118, "text": " {\"WORKINGTON\", 10, 113628}," }, { "line": 10119, "text": " {\"WORKINGS\", 8, 56310}," }, { "line": 10120, "text": " {\"WORKINGMEN\", 10, 247479}," }, { "line": 10121, "text": " {\"WORKINGMAN\", 10, 230516}," } ] } }, { "line": 10194, "matches": [ "list" ], "snippet": { "start_line": 10188, "end_line": 10200, "lines": [ { "line": 10188, "text": " {\"WORDPERFECT\", 11, 55951}," }, { "line": 10189, "text": " {\"WORDPAD\", 7, 131842}," }, { "line": 10190, "text": " {\"WORDNET\", 7, 64406}," }, { "line": 10191, "text": " {\"WORDMARK\", 8, 109529}," }, { "line": 10192, "text": " {\"WORDMAP\", 7, 186165}," }, { "line": 10193, "text": " {\"WORDLY\", 6, 217014}," }, { "line": 10194, "text": " {\"WORDLISTS\", 9, 249284}," }, { "line": 10195, "text": " {\"WORDLIST\", 8, 140035}," }, { "line": 10196, "text": " {\"WORDLET\", 7, 62465}," }, { "line": 10197, "text": " {\"WORDLESS\", 8, 139918}," }, { "line": 10198, "text": " {\"WORDINGS\", 8, 167281}," }, { "line": 10199, "text": " {\"WORDING\", 7, 44892}," }, { "line": 10200, "text": " {\"WORDINDEX\", 9, 203561}," } ] } }, { "line": 11469, "matches": [ "list" ], "snippet": { "start_line": 11463, "end_line": 11475, "lines": [ { "line": 11463, "text": " {\"WISL\", 4, 86239}," }, { "line": 11464, "text": " {\"WISKUNDE\", 8, 191467}," }, { "line": 11465, "text": " {\"WISK\", 4, 256565}," }, { "line": 11466, "text": " {\"WISJ\", 4, 140617}," }, { "line": 11467, "text": " {\"WISHY\", 5, 146582}," }, { "line": 11468, "text": " {\"WISHMASTER\", 10, 203883}," }, { "line": 11469, "text": " {\"WISHLISTS\", 9, 105588}," }, { "line": 11470, "text": " {\"WISHLIST\", 8, 8077}," }, { "line": 11471, "text": " {\"WISHING\", 7, 623}," }, { "line": 11472, "text": " {\"WISHIN\", 6, 215031}," }, { "line": 11473, "text": " {\"WISHFUL\", 7, 80801}," }, { "line": 11474, "text": " {\"WISHES\", 6, 622}," }, { "line": 11475, "text": " {\"WISHERS\", 7, 153242}," } ] } }, { "line": 11992, "matches": [ "list" ], "snippet": { "start_line": 11986, "end_line": 11998, "lines": [ { "line": 11986, "text": " {\"WILLMAR\", 7, 122914}," }, { "line": 11987, "text": " {\"WILLMAN\", 7, 212055}," }, { "line": 11988, "text": " {\"WILLL\", 5, 200439}," }, { "line": 11989, "text": " {\"WILLKOMMEN\", 10, 113187}," }, { "line": 11990, "text": " {\"WILLKIE\", 7, 236293}," }, { "line": 11991, "text": " {\"WILLITS\", 7, 102873}," }, { "line": 11992, "text": " {\"WILLISTON\", 9, 72274}," }, { "line": 11993, "text": " {\"WILLISON\", 8, 132171}," }, { "line": 11994, "text": " {\"WILLISMS\", 8, 246254}," }, { "line": 11995, "text": " {\"WILLIS\", 6, 38331}," }, { "line": 11996, "text": " {\"WILLIRAYE\", 9, 216928}," }, { "line": 11997, "text": " {\"WILLINGTON\", 10, 140698}," }, { "line": 11998, "text": " {\"WILLINGNESS\", 11, 32551}," } ] } }, { "line": 12170, "matches": [ "list" ], "snippet": { "start_line": 12164, "end_line": 12176, "lines": [ { "line": 12164, "text": " {\"WIKKA\", 5, 151396}," }, { "line": 12165, "text": " {\"WIKIWORDS\", 9, 126343}," }, { "line": 12166, "text": " {\"WIKIWORD\", 8, 106717}," }, { "line": 12167, "text": " {\"WIKIWIKIWEB\", 11, 185766}," }, { "line": 12168, "text": " {\"WIKIWIKI\", 8, 194318}," }, { "line": 12169, "text": " {\"WIKIWEBMASTER\", 13, 126029}," }, { "line": 12170, "text": " {\"WIKIWEBLIST\", 11, 212771}," }, { "line": 12171, "text": " {\"WIKIVERSITY\", 11, 237228}," }, { "line": 12172, "text": " {\"WIKIVERSION\", 11, 131922}," }, { "line": 12173, "text": " {\"WIKIUSERSTOPIC\", 14, 145174}," }, { "line": 12174, "text": " {\"WIKIUSERNAME\", 12, 89012}," }, { "line": 12175, "text": " {\"WIKITRAVEL\", 10, 175249}," }, { "line": 12176, "text": " {\"WIKITOOLNAME\", 12, 111221}," } ] } }, { "line": 12522, "matches": [ "list" ], "snippet": { "start_line": 12516, "end_line": 12528, "lines": [ { "line": 12516, "text": " {\"WHOMSOEVER\", 10, 118297}," }, { "line": 12517, "text": " {\"WHOMEVER\", 8, 69165}," }, { "line": 12518, "text": " {\"WHOME\", 5, 164401}," }, { "line": 12519, "text": " {\"WHOM\", 4, 3131}," }, { "line": 12520, "text": " {\"WHOLSALE\", 8, 238016}," }, { "line": 12521, "text": " {\"WHOLLY\", 6, 37797}," }, { "line": 12522, "text": " {\"WHOLISTIC\", 9, 157282}," }, { "line": 12523, "text": " {\"WHOLEVIEW\", 9, 234660}," }, { "line": 12524, "text": " {\"WHOLESOMENESS\", 13, 207416}," }, { "line": 12525, "text": " {\"WHOLESOME\", 9, 67095}," }, { "line": 12526, "text": " {\"WHOLESALING\", 11, 106014}," }, { "line": 12527, "text": " {\"WHOLESALES\", 10, 139335}," }, { "line": 12528, "text": " {\"WHOLESALERS\", 11, 40130}," } ] } }, { "line": 12652, "matches": [ "list" ], "snippet": { "start_line": 12646, "end_line": 12658, "lines": [ { "line": 12646, "text": " {\"WHITENER\", 8, 135371}," }, { "line": 12647, "text": " {\"WHITENED\", 8, 205059}," }, { "line": 12648, "text": " {\"WHITEN\", 6, 156305}," }, { "line": 12649, "text": " {\"WHITEMARSH\", 10, 261845}," }, { "line": 12650, "text": " {\"WHITEMAN\", 8, 98792}," }, { "line": 12651, "text": " {\"WHITELY\", 7, 240962}," }, { "line": 12652, "text": " {\"WHITELIST\", 9, 116997}," }, { "line": 12653, "text": " {\"WHITELEY\", 8, 106899}," }, { "line": 12654, "text": " {\"WHITELAW\", 8, 134868}," }, { "line": 12655, "text": " {\"WHITELAND\", 9, 197173}," }, { "line": 12656, "text": " {\"WHITEHURST\", 10, 134802}," }, { "line": 12657, "text": " {\"WHITEHOUSE\", 10, 69013}," }, { "line": 12658, "text": " {\"WHITEHORSE\", 10, 79659}," } ] } }, { "line": 13618, "matches": [ "list" ], "snippet": { "start_line": 13612, "end_line": 13624, "lines": [ { "line": 13612, "text": " {\"WELB\", 4, 133953}," }, { "line": 13613, "text": " {\"WELA\", 4, 72086}," }, { "line": 13614, "text": " {\"WEKN\", 4, 38136}," }, { "line": 13615, "text": " {\"WEKIVA\", 6, 227426}," }, { "line": 13616, "text": " {\"WEKI\", 4, 105251}," }, { "line": 13617, "text": " {\"WEKE\", 4, 76422}," }, { "line": 13618, "text": " {\"WEKALIST\", 8, 181789}," }, { "line": 13619, "text": " {\"WEKA\", 4, 152147}," }, { "line": 13620, "text": " {\"WEJU\", 4, 44620}," }, { "line": 13621, "text": " {\"WEJO\", 4, 165574}," }, { "line": 13622, "text": " {\"WEJ\", 3, 1628}," }, { "line": 13623, "text": " {\"WEIZMANN\", 8, 106634}," }, { "line": 13624, "text": " {\"WEIZ\", 4, 140425}," } ] } }, { "line": 13917, "matches": [ "list" ], "snippet": { "start_line": 13911, "end_line": 13923, "lines": [ { "line": 13911, "text": " {\"WEBUI\", 5, 167008}," }, { "line": 13912, "text": " {\"WEBTV\", 5, 88636}," }, { "line": 13913, "text": " {\"WEBTRENDS\", 9, 61423}," }, { "line": 13914, "text": " {\"WEBTRADE\", 8, 211022}," }, { "line": 13915, "text": " {\"WEBTOURIST\", 10, 121680}," }, { "line": 13916, "text": " {\"WEBTOPICVIEWTEMPLATE\", 20, 189992}," }, { "line": 13917, "text": " {\"WEBTOPICLIST\", 12, 86217}," }, { "line": 13918, "text": " {\"WEBTOPICEDITTEMPLATE\", 20, 139106}," }, { "line": 13919, "text": " {\"WEBTOP\", 6, 208855}," }, { "line": 13920, "text": " {\"WEBTOOLS\", 8, 135354}," }, { "line": 13921, "text": " {\"WEBTEST\", 7, 132472}," }, { "line": 13922, "text": " {\"WEBTENDER\", 9, 191217}," }, { "line": 13923, "text": " {\"WEBTECH\", 7, 174945}," } ] } }, { "line": 14019, "matches": [ "list" ], "snippet": { "start_line": 14013, "end_line": 14025, "lines": [ { "line": 14013, "text": " {\"WEBLOGIC\", 8, 50073}," }, { "line": 14014, "text": " {\"WEBLOGGING\", 10, 86727}," }, { "line": 14015, "text": " {\"WEBLOGGERS\", 10, 156420}," }, { "line": 14016, "text": " {\"WEBLOGGER\", 9, 146225}," }, { "line": 14017, "text": " {\"WEBLOGG\", 7, 128727}," }, { "line": 14018, "text": " {\"WEBLOG\", 6, 5292}," }, { "line": 14019, "text": " {\"WEBLISTS\", 8, 156425}," }, { "line": 14020, "text": " {\"WEBLIST\", 7, 88692}," }, { "line": 14021, "text": " {\"WEBLIOGRAPHY\", 12, 253671}," }, { "line": 14022, "text": " {\"WEBLINKS\", 8, 61668}," }, { "line": 14023, "text": " {\"WEBLINK\", 7, 96415}," }, { "line": 14024, "text": " {\"WEBLEY\", 6, 192822}," }, { "line": 14025, "text": " {\"WEBLEFTBAR\", 10, 123981}," } ] } }, { "line": 14919, "matches": [ "list" ], "snippet": { "start_line": 14913, "end_line": 14925, "lines": [ { "line": 14913, "text": " {\"WATCHTOWER\", 10, 84655}," }, { "line": 14914, "text": " {\"WATCHMEN\", 8, 109980}," }, { "line": 14915, "text": " {\"WATCHMAN\", 8, 83983}," }, { "line": 14916, "text": " {\"WATCHMAKING\", 11, 136059}," }, { "line": 14917, "text": " {\"WATCHMAKERS\", 11, 174423}," }, { "line": 14918, "text": " {\"WATCHMAKER\", 10, 110330}," }, { "line": 14919, "text": " {\"WATCHLISTS\", 10, 227853}," }, { "line": 14920, "text": " {\"WATCHLIST\", 9, 51304}," }, { "line": 14921, "text": " {\"WATCHING\", 8, 5606}," }, { "line": 14922, "text": " {\"WATCHIN\", 7, 120196}," }, { "line": 14923, "text": " {\"WATCHGUARD\", 10, 89761}," }, { "line": 14924, "text": " {\"WATCHFULNESS\", 12, 217558}," }, { "line": 14925, "text": " {\"WATCHFUL\", 8, 77748}," } ] } }, { "line": 15298, "matches": [ "list" ], "snippet": { "start_line": 15292, "end_line": 15304, "lines": [ { "line": 15292, "text": " {\"WANU\", 4, 97631}," }, { "line": 15293, "text": " {\"WANTS\", 5, 3845}," }, { "line": 15294, "text": " {\"WANTONNESSE\", 11, 203886}," }, { "line": 15295, "text": " {\"WANTONNESS\", 10, 256868}," }, { "line": 15296, "text": " {\"WANTONLY\", 8, 177252}," }, { "line": 15297, "text": " {\"WANTON\", 6, 80104}," }, { "line": 15298, "text": " {\"WANTLIST\", 8, 164558}," }, { "line": 15299, "text": " {\"WANTIRNA\", 8, 190980}," }, { "line": 15300, "text": " {\"WANTING\", 7, 31750}," }, { "line": 15301, "text": " {\"WANTIN\", 6, 250740}," }, { "line": 15302, "text": " {\"WANTED\", 6, 2130}," }, { "line": 15303, "text": " {\"WANTAGH\", 7, 140140}," }, { "line": 15304, "text": " {\"WANTAGE\", 7, 118376}," } ] } }, { "line": 15633, "matches": [ "list" ], "snippet": { "start_line": 15627, "end_line": 15639, "lines": [ { "line": 15627, "text": " {\"WAITS\", 5, 45852}," }, { "line": 15628, "text": " {\"WAITROSE\", 8, 130711}," }, { "line": 15629, "text": " {\"WAITRESSES\", 10, 103821}," }, { "line": 15630, "text": " {\"WAITRESS\", 8, 59450}," }, { "line": 15631, "text": " {\"WAITPID\", 7, 196529}," }, { "line": 15632, "text": " {\"WAITOMO\", 7, 160380}," }, { "line": 15633, "text": " {\"WAITLISTED\", 10, 209143}," }, { "line": 15634, "text": " {\"WAITLIST\", 8, 114442}," }, { "line": 15635, "text": " {\"WAITLEY\", 7, 247186}," }, { "line": 15636, "text": " {\"WAITING\", 7, 4139}," }, { "line": 15637, "text": " {\"WAITIN\", 6, 102497}," }, { "line": 15638, "text": " {\"WAITH\", 5, 140827}," }, { "line": 15639, "text": " {\"WAITES\", 6, 201362}," } ] } }, { "line": 16974, "matches": [ "code" ], "snippet": { "start_line": 16968, "end_line": 16980, "lines": [ { "line": 16968, "text": " {\"VODACOM\", 7, 98811}," }, { "line": 16969, "text": " {\"VODA\", 4, 132943}," }, { "line": 16970, "text": " {\"VOCW\", 4, 173146}," }, { "line": 16971, "text": " {\"VOCT\", 4, 212409}," }, { "line": 16972, "text": " {\"VOCS\", 4, 84855}," }, { "line": 16973, "text": " {\"VOCOPRO\", 7, 119430}," }, { "line": 16974, "text": " {\"VOCODER\", 7, 153702}," }, { "line": 16975, "text": " {\"VOCO\", 4, 100538}," }, { "line": 16976, "text": " {\"VOCIFEROUSLY\", 12, 199931}," }, { "line": 16977, "text": " {\"VOCIFEROUS\", 10, 151910}," }, { "line": 16978, "text": " {\"VOCI\", 4, 209014}," }, { "line": 16979, "text": " {\"VOCH\", 4, 180874}," }, { "line": 16980, "text": " {\"VOCES\", 5, 183965}," } ] } }, { "line": 16994, "matches": [ "list" ], "snippet": { "start_line": 16988, "end_line": 17000, "lines": [ { "line": 16988, "text": " {\"VOCALS\", 6, 32620}," }, { "line": 16989, "text": " {\"VOCALLY\", 7, 129889}," }, { "line": 16990, "text": " {\"VOCALIZING\", 10, 253385}," }, { "line": 16991, "text": " {\"VOCALIZE\", 8, 235123}," }, { "line": 16992, "text": " {\"VOCALIZATIONS\", 13, 153203}," }, { "line": 16993, "text": " {\"VOCALIZATION\", 12, 169961}," }, { "line": 16994, "text": " {\"VOCALISTS\", 9, 74043}," }, { "line": 16995, "text": " {\"VOCALIST\", 8, 54952}," }, { "line": 16996, "text": " {\"VOCALISE\", 8, 230150}," }, { "line": 16997, "text": " {\"VOCALIC\", 7, 231299}," }, { "line": 16998, "text": " {\"VOCALE\", 6, 255077}," }, { "line": 16999, "text": " {\"VOCAL\", 5, 34063}," }, { "line": 17000, "text": " {\"VOCABULARY\", 10, 33411}," } ] } }, { "line": 17104, "matches": [ "list" ], "snippet": { "start_line": 17098, "end_line": 17110, "lines": [ { "line": 17098, "text": " {\"VLOER\", 5, 188207}," }, { "line": 17099, "text": " {\"VLOCK\", 5, 254807}," }, { "line": 17100, "text": " {\"VLM\", 3, 167766}," }, { "line": 17101, "text": " {\"VLJ\", 3, 51042}," }, { "line": 17102, "text": " {\"VLIW\", 4, 176611}," }, { "line": 17103, "text": " {\"VLIV\", 4, 231829}," }, { "line": 17104, "text": " {\"VLIST\", 5, 189773}," }, { "line": 17105, "text": " {\"VLISSINGEN\", 10, 253975}," }, { "line": 17106, "text": " {\"VLIS\", 4, 200912}," }, { "line": 17107, "text": " {\"VLIPART\", 7, 235880}," }, { "line": 17108, "text": " {\"VLINK\", 5, 252048}," }, { "line": 17109, "text": " {\"VLIN\", 4, 88553}," }, { "line": 17110, "text": " {\"VLIK\", 4, 114645}," } ] } } ] }, { "path": "JS8_Include/commons.h", "exists": true, "bytes": 3525, "sha256": "d7abc3090fcf5516b64435f78dfbd08dff9b01a56905afbe4d69fa4eb9c16048", "line_count": 106, "phase_hits": { "timing_submode": 3, "symbol_to_soft_bits": 6, "bit_order_interleaver": 0, "whitening_erasure": 0, "ldpc_decode": 0, "message91_crc_text": 0 }, "function_blocks": [], "keyword_snippets": [ { "line": 11, "matches": [ "JS8_NSPS" ], "snippet": { "start_line": 5, "end_line": 17, "lines": [ { "line": 5, "text": "#include " }, { "line": 6, "text": "" }, { "line": 7, "text": "// NSPS, the number of samples per second (at a sample rate of 12000" }, { "line": 8, "text": "// samples per second) is a constant, chosen so as to be a number" }, { "line": 9, "text": "// with no prime factor greater than 7." }, { "line": 10, "text": "" }, { "line": 11, "text": "#define JS8_NSPS 6192" }, { "line": 12, "text": "#define JS8_NSMAX 6827" }, { "line": 13, "text": "#define JS8_NTMAX 60" }, { "line": 14, "text": "#define JS8_RX_SAMPLE_RATE 12000" }, { "line": 15, "text": "#define JS8_RX_SAMPLE_SIZE (JS8_NTMAX * JS8_RX_SAMPLE_RATE)" }, { "line": 16, "text": "" }, { "line": 17, "text": "#define JS8_RING_BUFFER 1 // use a ring buffer instead of clearing the decode frames" } ] } } ] } ], "source_derived_next_patch_plan": [ { "step": 1, "name": "Implement exact Costas/submode/timing constants from JS8Submode/commons", "why": "Step51 confirmed JS8_NSPS=6192 but still prefers tone-spacing offset -0.03; source snippets must show whether additional submode correction is applied." }, { "step": 2, "name": "Replace lab FT8-style symbol-to-bit hypothesis with source-derived soft/LLR bitpath", "why": "Syndrome remains 22; exact pre-LDPC bit ordering is more likely than wider timing now." }, { "step": 3, "name": "Apply source whitening/erasure/mask path before LDPC/message91 validation", "why": "CRC validation and guided repair do not validate current Message91 candidates." }, { "step": 4, "name": "Only after source bitpath patch: rerun a bounded LDPC/CRC probe", "why": "Avoid another expensive blind repair run before the source path is reflected in JS8Lab." } ], "recommended_next_step": "Step55 should implement the first source-derived bitpath patch in JS8Lab, using these extracted snippets as evidence; do not start JS8Call GUI." } [webftr-js8-lab] OK [webftr-js8-lab] log file: /decoders/js8_decoder/logs/20260527T124745Z_source-bitpath-extract.log [webftr-js8-lab] manifest: /decoders/js8_decoder/logs/20260527T124745Z_source-bitpath-extract_manifest.json