{
  "ok": true,
  "tool": "webftr-js8-source-bitpath-audit",
  "tool_version": "step53-focused-source-bitpath-audit-timeout-fix",
  "source_dir": "/decoders/js8_decoder/runtime/src/JS8Call-improved",
  "rx_only_guard": {
    "tx": false,
    "ptt": false,
    "tune": false,
    "send": false,
    "js8call_runtime_control": false
  },
  "timeout_fix": {
    "step52_problem": "full deep scan timed out after 180s",
    "step53_change": "deep scan only focused RX-core files; optional bounded cheap discovery",
    "focused_only": true,
    "max_discovered": 30
  },
  "scanned_focused_files": 16,
  "missing_focused_files": [],
  "focused_files": [
    {
      "path": "JS8_JSC/JSC_list.cpp",
      "exists": true,
      "bytes": 7085560,
      "lines": 262278,
      "score": 1105,
      "keyword_hits": {
        "interleave": 3,
        "gray": 27,
        "Gray": 27,
        "whiten": 5,
        "mask": 24,
        "xor": 38,
        "scrambl": 9,
        "ldpc": 1,
        "LDPC": 1,
        "decode": 6,
        "Decode": 6,
        "message": 22,
        "Message": 22,
        "crc": 10,
        "CRC": 10,
        "pack": 96,
        "unpack": 5,
        "JSC": 10,
        "symbol": 21,
        "tone": 267,
        "Costas": 1,
        "soft": 168,
        "llr": 40,
        "LLR": 40,
        "hard": 192,
        "candidates": 1,
        "nap": 157,
        "ordered": 7
      },
      "phase_scores": {
        "symbol_to_bits": 837,
        "bit_order_interleaver": 10,
        "whitening_mask": 76,
        "ldpc_fec": 5,
        "message91_crc": 121,
        "timing_constants": 0
      },
      "candidate_functions": [],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 2,
          "match": "* @file JSC_list.cpp",
          "context": [
            {
              "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": 3,
          "match": "* @brief Tuple list for JSC callsigns",
          "context": [
            {
              "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,
          "match": "* This program is free software: you can redistribute it and/or modify",
          "context": [
            {
              "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": 9,
              "text": " * the Free Software Foundation, either version 3 of the License, or"
            },
            {
              "line": 10,
              "text": " * (at your option) any later version."
            }
          ]
        },
        {
          "line": 9,
          "match": "* the Free Software Foundation, either version 3 of the License, or",
          "context": [
            {
              "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": 9,
              "text": " * the Free Software Foundation, either version 3 of the License, or"
            },
            {
              "line": 10,
              "text": " * (at your option) any later version."
            },
            {
              "line": 11,
              "text": " *"
            },
            {
              "line": 12,
              "text": " * This program is distributed in the hope that it will be useful,"
            }
          ]
        },
        {
          "line": 23,
          "match": "#include \"JSC.h\"",
          "context": [
            {
              "line": 20,
              "text": " * (C) 2018 Jordan Sherer <kn4crd@gmail.com> - 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": 25,
          "match": "const Tuple JSC::list[262144] = {",
          "context": [
            {
              "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": 4127,
          "match": "{\"YNAP\", 4, 81346},",
          "context": [
            {
              "line": 4124,
              "text": "    {\"YNAV\", 4, 80285},"
            },
            {
              "line": 4125,
              "text": "    {\"YNAU\", 4, 135869},"
            },
            {
              "line": 4126,
              "text": "    {\"YNAR\", 4, 59904},"
            },
            {
              "line": 4127,
              "text": "    {\"YNAP\", 4, 81346},"
            },
            {
              "line": 4128,
              "text": "    {\"YNAM\", 4, 29701},"
            },
            {
              "line": 4129,
              "text": "    {\"YNAL\", 4, 121066},"
            },
            {
              "line": 4130,
              "text": "    {\"YNAK\", 4, 135832},"
            }
          ]
        },
        {
          "line": 4456,
          "match": "{\"YLLR\", 4, 138917},",
          "context": [
            {
              "line": 4453,
              "text": "    {\"YLLU\", 4, 167238},"
            },
            {
              "line": 4454,
              "text": "    {\"YLLT\", 4, 111253},"
            },
            {
              "line": 4455,
              "text": "    {\"YLLS\", 4, 84681},"
            },
            {
              "line": 4456,
              "text": "    {\"YLLR\", 4, 138917},"
            },
            {
              "line": 4457,
              "text": "    {\"YLLP\", 4, 109684},"
            },
            {
              "line": 4458,
              "text": "    {\"YLLOW\", 5, 257559},"
            },
            {
              "line": 4459,
              "text": "    {\"YLLO\", 4, 101564},"
            }
          ]
        },
        {
          "line": 5470,
          "match": "{\"YELLOWSTONE\", 11, 47569},",
          "context": [
            {
              "line": 5467,
              "text": "    {\"YELLS\", 5, 87261},"
            },
            {
              "line": 5468,
              "text": "    {\"YELLOWTHROAT\", 12, 239211},"
            },
            {
              "line": 5469,
              "text": "    {\"YELLOWTAIL\", 10, 132068},"
            },
            {
              "line": 5470,
              "text": "    {\"YELLOWSTONE\", 11, 47569},"
            },
            {
              "line": 5471,
              "text": "    {\"YELLOWS\", 7, 98669},"
            },
            {
              "line": 5472,
              "text": "    {\"YELLOWPAGES\", 11, 73270},"
            },
            {
              "line": 5473,
              "text": "    {\"YELLOWMAN\", 9, 206002},"
            }
          ]
        },
        {
          "line": 6949,
          "match": "{\"XTREMETONES\", 11, 207969},",
          "context": [
            {
              "line": 6946,
              "text": "    {\"XTRU\", 4, 111625},"
            },
            {
              "line": 6947,
              "text": "    {\"XTRO\", 4, 70552},"
            },
            {
              "line": 6948,
              "text": "    {\"XTRI\", 4, 83290},"
            },
            {
              "line": 6949,
              "text": "    {\"XTREMETONES\", 11, 207969},"
            },
            {
              "line": 6950,
              "text": "    {\"XTREMEMUSIC\", 11, 238986},"
            },
            {
              "line": 6951,
              "text": "    {\"XTREMEMAC\", 9, 104106},"
            },
            {
              "line": 6952,
              "text": "    {\"XTREME\", 6, 43080},"
            }
          ]
        },
        {
          "line": 7359,
          "match": "{\"XOSOFT\", 6, 135268},",
          "context": [
            {
              "line": 7356,
              "text": "    {\"XOV\", 3, 29846},"
            },
            {
              "line": 7357,
              "text": "    {\"XOUR\", 4, 181696},"
            },
            {
              "line": 7358,
              "text": "    {\"XOU\", 3, 8584},"
            },
            {
              "line": 7359,
              "text": "    {\"XOSOFT\", 6, 135268},"
            },
            {
              "line": 7360,
              "text": "    {\"XOSM\", 4, 180559},"
            },
            {
              "line": 7361,
              "text": "    {\"XOSK\", 4, 200551},"
            },
            {
              "line": 7362,
              "text": "    {\"XORW\", 4, 219730},"
            }
          ]
        },
        {
          "line": 7362,
          "match": "{\"XORW\", 4, 219730},",
          "context": [
            {
              "line": 7359,
              "text": "    {\"XOSOFT\", 6, 135268},"
            },
            {
              "line": 7360,
              "text": "    {\"XOSM\", 4, 180559},"
            },
            {
              "line": 7361,
              "text": "    {\"XOSK\", 4, 200551},"
            },
            {
              "line": 7362,
              "text": "    {\"XORW\", 4, 219730},"
            },
            {
              "line": 7363,
              "text": "    {\"XORT\", 4, 140158},"
            },
            {
              "line": 7364,
              "text": "    {\"XORS\", 4, 94482},"
            },
            {
              "line": 7365,
              "text": "    {\"XORR\", 4, 246326},"
            }
          ]
        },
        {
          "line": 7363,
          "match": "{\"XORT\", 4, 140158},",
          "context": [
            {
              "line": 7360,
              "text": "    {\"XOSM\", 4, 180559},"
            },
            {
              "line": 7361,
              "text": "    {\"XOSK\", 4, 200551},"
            },
            {
              "line": 7362,
              "text": "    {\"XORW\", 4, 219730},"
            },
            {
              "line": 7363,
              "text": "    {\"XORT\", 4, 140158},"
            },
            {
              "line": 7364,
              "text": "    {\"XORS\", 4, 94482},"
            },
            {
              "line": 7365,
              "text": "    {\"XORR\", 4, 246326},"
            },
            {
              "line": 7366,
              "text": "    {\"XORP\", 4, 184675},"
            }
          ]
        },
        {
          "line": 7364,
          "match": "{\"XORS\", 4, 94482},",
          "context": [
            {
              "line": 7361,
              "text": "    {\"XOSK\", 4, 200551},"
            },
            {
              "line": 7362,
              "text": "    {\"XORW\", 4, 219730},"
            },
            {
              "line": 7363,
              "text": "    {\"XORT\", 4, 140158},"
            },
            {
              "line": 7364,
              "text": "    {\"XORS\", 4, 94482},"
            },
            {
              "line": 7365,
              "text": "    {\"XORR\", 4, 246326},"
            },
            {
              "line": 7366,
              "text": "    {\"XORP\", 4, 184675},"
            },
            {
              "line": 7367,
              "text": "    {\"XORO\", 4, 176933},"
            }
          ]
        },
        {
          "line": 7365,
          "match": "{\"XORR\", 4, 246326},",
          "context": [
            {
              "line": 7362,
              "text": "    {\"XORW\", 4, 219730},"
            },
            {
              "line": 7363,
              "text": "    {\"XORT\", 4, 140158},"
            },
            {
              "line": 7364,
              "text": "    {\"XORS\", 4, 94482},"
            },
            {
              "line": 7365,
              "text": "    {\"XORR\", 4, 246326},"
            },
            {
              "line": 7366,
              "text": "    {\"XORP\", 4, 184675},"
            },
            {
              "line": 7367,
              "text": "    {\"XORO\", 4, 176933},"
            },
            {
              "line": 7368,
              "text": "    {\"XORN\", 4, 214601},"
            }
          ]
        },
        {
          "line": 7366,
          "match": "{\"XORP\", 4, 184675},",
          "context": [
            {
              "line": 7363,
              "text": "    {\"XORT\", 4, 140158},"
            },
            {
              "line": 7364,
              "text": "    {\"XORS\", 4, 94482},"
            },
            {
              "line": 7365,
              "text": "    {\"XORR\", 4, 246326},"
            },
            {
              "line": 7366,
              "text": "    {\"XORP\", 4, 184675},"
            },
            {
              "line": 7367,
              "text": "    {\"XORO\", 4, 176933},"
            },
            {
              "line": 7368,
              "text": "    {\"XORN\", 4, 214601},"
            },
            {
              "line": 7369,
              "text": "    {\"XORM\", 4, 159713},"
            }
          ]
        },
        {
          "line": 7367,
          "match": "{\"XORO\", 4, 176933},",
          "context": [
            {
              "line": 7364,
              "text": "    {\"XORS\", 4, 94482},"
            },
            {
              "line": 7365,
              "text": "    {\"XORR\", 4, 246326},"
            },
            {
              "line": 7366,
              "text": "    {\"XORP\", 4, 184675},"
            },
            {
              "line": 7367,
              "text": "    {\"XORO\", 4, 176933},"
            },
            {
              "line": 7368,
              "text": "    {\"XORN\", 4, 214601},"
            },
            {
              "line": 7369,
              "text": "    {\"XORM\", 4, 159713},"
            },
            {
              "line": 7370,
              "text": "    {\"XORI\", 4, 140318},"
            }
          ]
        },
        {
          "line": 7368,
          "match": "{\"XORN\", 4, 214601},",
          "context": [
            {
              "line": 7365,
              "text": "    {\"XORR\", 4, 246326},"
            },
            {
              "line": 7366,
              "text": "    {\"XORP\", 4, 184675},"
            },
            {
              "line": 7367,
              "text": "    {\"XORO\", 4, 176933},"
            },
            {
              "line": 7368,
              "text": "    {\"XORN\", 4, 214601},"
            },
            {
              "line": 7369,
              "text": "    {\"XORM\", 4, 159713},"
            },
            {
              "line": 7370,
              "text": "    {\"XORI\", 4, 140318},"
            },
            {
              "line": 7371,
              "text": "    {\"XORH\", 4, 253174},"
            }
          ]
        },
        {
          "line": 7369,
          "match": "{\"XORM\", 4, 159713},",
          "context": [
            {
              "line": 7366,
              "text": "    {\"XORP\", 4, 184675},"
            },
            {
              "line": 7367,
              "text": "    {\"XORO\", 4, 176933},"
            },
            {
              "line": 7368,
              "text": "    {\"XORN\", 4, 214601},"
            },
            {
              "line": 7369,
              "text": "    {\"XORM\", 4, 159713},"
            },
            {
              "line": 7370,
              "text": "    {\"XORI\", 4, 140318},"
            },
            {
              "line": 7371,
              "text": "    {\"XORH\", 4, 253174},"
            },
            {
              "line": 7372,
              "text": "    {\"XORG\", 4, 60144},"
            }
          ]
        },
        {
          "line": 7370,
          "match": "{\"XORI\", 4, 140318},",
          "context": [
            {
              "line": 7367,
              "text": "    {\"XORO\", 4, 176933},"
            },
            {
              "line": 7368,
              "text": "    {\"XORN\", 4, 214601},"
            },
            {
              "line": 7369,
              "text": "    {\"XORM\", 4, 159713},"
            },
            {
              "line": 7370,
              "text": "    {\"XORI\", 4, 140318},"
            },
            {
              "line": 7371,
              "text": "    {\"XORH\", 4, 253174},"
            },
            {
              "line": 7372,
              "text": "    {\"XORG\", 4, 60144},"
            },
            {
              "line": 7373,
              "text": "    {\"XORF\", 4, 252137},"
            }
          ]
        },
        {
          "line": 7371,
          "match": "{\"XORH\", 4, 253174},",
          "context": [
            {
              "line": 7368,
              "text": "    {\"XORN\", 4, 214601},"
            },
            {
              "line": 7369,
              "text": "    {\"XORM\", 4, 159713},"
            },
            {
              "line": 7370,
              "text": "    {\"XORI\", 4, 140318},"
            },
            {
              "line": 7371,
              "text": "    {\"XORH\", 4, 253174},"
            },
            {
              "line": 7372,
              "text": "    {\"XORG\", 4, 60144},"
            },
            {
              "line": 7373,
              "text": "    {\"XORF\", 4, 252137},"
            },
            {
              "line": 7374,
              "text": "    {\"XORE\", 4, 147870},"
            }
          ]
        },
        {
          "line": 7372,
          "match": "{\"XORG\", 4, 60144},",
          "context": [
            {
              "line": 7369,
              "text": "    {\"XORM\", 4, 159713},"
            },
            {
              "line": 7370,
              "text": "    {\"XORI\", 4, 140318},"
            },
            {
              "line": 7371,
              "text": "    {\"XORH\", 4, 253174},"
            },
            {
              "line": 7372,
              "text": "    {\"XORG\", 4, 60144},"
            },
            {
              "line": 7373,
              "text": "    {\"XORF\", 4, 252137},"
            },
            {
              "line": 7374,
              "text": "    {\"XORE\", 4, 147870},"
            },
            {
              "line": 7375,
              "text": "    {\"XORD\", 4, 177824},"
            }
          ]
        },
        {
          "line": 7373,
          "match": "{\"XORF\", 4, 252137},",
          "context": [
            {
              "line": 7370,
              "text": "    {\"XORI\", 4, 140318},"
            },
            {
              "line": 7371,
              "text": "    {\"XORH\", 4, 253174},"
            },
            {
              "line": 7372,
              "text": "    {\"XORG\", 4, 60144},"
            },
            {
              "line": 7373,
              "text": "    {\"XORF\", 4, 252137},"
            },
            {
              "line": 7374,
              "text": "    {\"XORE\", 4, 147870},"
            },
            {
              "line": 7375,
              "text": "    {\"XORD\", 4, 177824},"
            },
            {
              "line": 7376,
              "text": "    {\"XORC\", 4, 96449},"
            }
          ]
        },
        {
          "line": 7374,
          "match": "{\"XORE\", 4, 147870},",
          "context": [
            {
              "line": 7371,
              "text": "    {\"XORH\", 4, 253174},"
            },
            {
              "line": 7372,
              "text": "    {\"XORG\", 4, 60144},"
            },
            {
              "line": 7373,
              "text": "    {\"XORF\", 4, 252137},"
            },
            {
              "line": 7374,
              "text": "    {\"XORE\", 4, 147870},"
            },
            {
              "line": 7375,
              "text": "    {\"XORD\", 4, 177824},"
            },
            {
              "line": 7376,
              "text": "    {\"XORC\", 4, 96449},"
            },
            {
              "line": 7377,
              "text": "    {\"XORB\", 4, 117391},"
            }
          ]
        },
        {
          "line": 7375,
          "match": "{\"XORD\", 4, 177824},",
          "context": [
            {
              "line": 7372,
              "text": "    {\"XORG\", 4, 60144},"
            },
            {
              "line": 7373,
              "text": "    {\"XORF\", 4, 252137},"
            },
            {
              "line": 7374,
              "text": "    {\"XORE\", 4, 147870},"
            },
            {
              "line": 7375,
              "text": "    {\"XORD\", 4, 177824},"
            },
            {
              "line": 7376,
              "text": "    {\"XORC\", 4, 96449},"
            },
            {
              "line": 7377,
              "text": "    {\"XORB\", 4, 117391},"
            },
            {
              "line": 7378,
              "text": "    {\"XORA\", 4, 104171},"
            }
          ]
        },
        {
          "line": 7376,
          "match": "{\"XORC\", 4, 96449},",
          "context": [
            {
              "line": 7373,
              "text": "    {\"XORF\", 4, 252137},"
            },
            {
              "line": 7374,
              "text": "    {\"XORE\", 4, 147870},"
            },
            {
              "line": 7375,
              "text": "    {\"XORD\", 4, 177824},"
            },
            {
              "line": 7376,
              "text": "    {\"XORC\", 4, 96449},"
            },
            {
              "line": 7377,
              "text": "    {\"XORB\", 4, 117391},"
            },
            {
              "line": 7378,
              "text": "    {\"XORA\", 4, 104171},"
            },
            {
              "line": 7379,
              "text": "    {\"XOPL\", 4, 240729},"
            }
          ]
        },
        {
          "line": 7377,
          "match": "{\"XORB\", 4, 117391},",
          "context": [
            {
              "line": 7374,
              "text": "    {\"XORE\", 4, 147870},"
            },
            {
              "line": 7375,
              "text": "    {\"XORD\", 4, 177824},"
            },
            {
              "line": 7376,
              "text": "    {\"XORC\", 4, 96449},"
            },
            {
              "line": 7377,
              "text": "    {\"XORB\", 4, 117391},"
            },
            {
              "line": 7378,
              "text": "    {\"XORA\", 4, 104171},"
            },
            {
              "line": 7379,
              "text": "    {\"XOPL\", 4, 240729},"
            },
            {
              "line": 7380,
              "text": "    {\"XOPH\", 4, 79712},"
            }
          ]
        },
        {
          "line": 7378,
          "match": "{\"XORA\", 4, 104171},",
          "context": [
            {
              "line": 7375,
              "text": "    {\"XORD\", 4, 177824},"
            },
            {
              "line": 7376,
              "text": "    {\"XORC\", 4, 96449},"
            },
            {
              "line": 7377,
              "text": "    {\"XORB\", 4, 117391},"
            },
            {
              "line": 7378,
              "text": "    {\"XORA\", 4, 104171},"
            },
            {
              "line": 7379,
              "text": "    {\"XOPL\", 4, 240729},"
            },
            {
              "line": 7380,
              "text": "    {\"XOPH\", 4, 79712},"
            },
            {
              "line": 7381,
              "text": "    {\"XOPE\", 4, 104597},"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_JSC/JSC_map.cpp",
      "exists": true,
      "bytes": 7082880,
      "lines": 262172,
      "score": 1104,
      "keyword_hits": {
        "interleave": 3,
        "gray": 27,
        "Gray": 27,
        "whiten": 5,
        "mask": 24,
        "xor": 38,
        "scrambl": 9,
        "ldpc": 1,
        "LDPC": 1,
        "decode": 6,
        "Decode": 6,
        "message": 22,
        "Message": 22,
        "crc": 10,
        "CRC": 10,
        "pack": 96,
        "unpack": 5,
        "JSC": 9,
        "symbol": 21,
        "tone": 267,
        "Costas": 1,
        "soft": 168,
        "llr": 40,
        "LLR": 40,
        "hard": 192,
        "candidates": 1,
        "nap": 157,
        "ordered": 7
      },
      "phase_scores": {
        "symbol_to_bits": 837,
        "bit_order_interleaver": 10,
        "whitening_mask": 76,
        "ldpc_fec": 5,
        "message91_crc": 120,
        "timing_constants": 0
      },
      "candidate_functions": [],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 2,
          "match": "* @file JSC_map.cpp",
          "context": [
            {
              "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": 3,
          "match": "* @brief Implementation of JSC character map",
          "context": [
            {
              "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,
          "match": "* This program is free software: you can redistribute it and/or modify",
          "context": [
            {
              "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": 9,
              "text": " * the Free Software Foundation, either version 3 of the License, or"
            },
            {
              "line": 10,
              "text": " * (at your option) any later version."
            }
          ]
        },
        {
          "line": 9,
          "match": "* the Free Software Foundation, either version 3 of the License, or",
          "context": [
            {
              "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": 9,
              "text": " * the Free Software Foundation, either version 3 of the License, or"
            },
            {
              "line": 10,
              "text": " * (at your option) any later version."
            },
            {
              "line": 11,
              "text": " *"
            },
            {
              "line": 12,
              "text": " * This program is distributed in the hope that it will be useful,"
            }
          ]
        },
        {
          "line": 23,
          "match": "#include \"JSC.h\"",
          "context": [
            {
              "line": 20,
              "text": " * (C) 2018 Jordan Sherer <kn4crd@gmail.com> - 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": 25,
          "match": "const Tuple JSC::map[262144] = {",
          "context": [
            {
              "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": 552,
          "match": "{\"MESSAGE\", 7, 524},",
          "context": [
            {
              "line": 549,
              "text": "    {\"MEDICAL\", 7, 521},"
            },
            {
              "line": 550,
              "text": "    {\"MEET\", 4, 522},"
            },
            {
              "line": 551,
              "text": "    {\"MERRY\", 5, 523},"
            },
            {
              "line": 552,
              "text": "    {\"MESSAGE\", 7, 524},"
            },
            {
              "line": 553,
              "text": "    {\"MOBILE\", 6, 525},"
            },
            {
              "line": 554,
              "text": "    {\"MORE\", 4, 526},"
            },
            {
              "line": 555,
              "text": "    {\"MOST\", 4, 527},"
            }
          ]
        },
        {
          "line": 1477,
          "match": "{\"MESSAGES\", 8, 1449},",
          "context": [
            {
              "line": 1474,
              "text": "    {\"EFIR\", 4, 1446},"
            },
            {
              "line": 1475,
              "text": "    {\"GVO\", 3, 1447},"
            },
            {
              "line": 1476,
              "text": "    {\"CARS\", 4, 1448},"
            },
            {
              "line": 1477,
              "text": "    {\"MESSAGES\", 8, 1449},"
            },
            {
              "line": 1478,
              "text": "    {\"EWIT\", 4, 1450},"
            },
            {
              "line": 1479,
              "text": "    {\"UPDATED\", 7, 1451},"
            },
            {
              "line": 1480,
              "text": "    {\"HUMAN\", 5, 1452},"
            }
          ]
        },
        {
          "line": 1540,
          "match": "{\"MICROSOFT\", 9, 1512},",
          "context": [
            {
              "line": 1537,
              "text": "    {\"BEHIND\", 6, 1509},"
            },
            {
              "line": 1538,
              "text": "    {\"FRANCE\", 6, 1510},"
            },
            {
              "line": 1539,
              "text": "    {\"HOUG\", 4, 1511},"
            },
            {
              "line": 1540,
              "text": "    {\"MICROSOFT\", 9, 1512},"
            },
            {
              "line": 1541,
              "text": "    {\"HEWO\", 4, 1513},"
            },
            {
              "line": 1542,
              "text": "    {\"EDFO\", 4, 1514},"
            },
            {
              "line": 1543,
              "text": "    {\"RECORDS\", 7, 1515},"
            }
          ]
        },
        {
          "line": 1623,
          "match": "{\"HARD\", 4, 1595},",
          "context": [
            {
              "line": 1620,
              "text": "    {\"RAISE\", 5, 1592},"
            },
            {
              "line": 1621,
              "text": "    {\"VIDEOS\", 6, 1593},"
            },
            {
              "line": 1622,
              "text": "    {\"PERCENT\", 7, 1594},"
            },
            {
              "line": 1623,
              "text": "    {\"HARD\", 4, 1595},"
            },
            {
              "line": 1624,
              "text": "    {\"ENTT\", 4, 1596},"
            },
            {
              "line": 1625,
              "text": "    {\"ERVI\", 4, 1597},"
            },
            {
              "line": 1626,
              "text": "    {\"NEOF\", 4, 1598},"
            }
          ]
        },
        {
          "line": 2559,
          "match": "{\"RICHARD\", 7, 2531},",
          "context": [
            {
              "line": 2556,
              "text": "    {\"HISM\", 4, 2528},"
            },
            {
              "line": 2557,
              "text": "    {\"ANBE\", 4, 2529},"
            },
            {
              "line": 2558,
              "text": "    {\"HEPL\", 4, 2530},"
            },
            {
              "line": 2559,
              "text": "    {\"RICHARD\", 7, 2531},"
            },
            {
              "line": 2560,
              "text": "    {\"NCRE\", 4, 2532},"
            },
            {
              "line": 2561,
              "text": "    {\"ASRE\", 4, 2533},"
            },
            {
              "line": 2562,
              "text": "    {\"RYQ\", 3, 2534},"
            }
          ]
        },
        {
          "line": 2864,
          "match": "{\"PACKAGES\", 8, 2836},",
          "context": [
            {
              "line": 2861,
              "text": "    {\"MAGAZINES\", 9, 2833},"
            },
            {
              "line": 2862,
              "text": "    {\"INSTITUTION\", 11, 2834},"
            },
            {
              "line": 2863,
              "text": "    {\"RESPOND\", 7, 2835},"
            },
            {
              "line": 2864,
              "text": "    {\"PACKAGES\", 8, 2836},"
            },
            {
              "line": 2865,
              "text": "    {\"ZBE\", 3, 2837},"
            },
            {
              "line": 2866,
              "text": "    {\"IONC\", 4, 2838},"
            },
            {
              "line": 2867,
              "text": "    {\"FRANCISCO\", 9, 2839},"
            }
          ]
        },
        {
          "line": 3050,
          "match": "{\"RINGTONES\", 9, 3022},",
          "context": [
            {
              "line": 3047,
              "text": "    {\"BOB\", 3, 3019},"
            },
            {
              "line": 3048,
              "text": "    {\"SCORE\", 5, 3020},"
            },
            {
              "line": 3049,
              "text": "    {\"COMMERCE\", 8, 3021},"
            },
            {
              "line": 3050,
              "text": "    {\"RINGTONES\", 9, 3022},"
            },
            {
              "line": 3051,
              "text": "    {\"STARE\", 5, 3023},"
            },
            {
              "line": 3052,
              "text": "    {\"PAINTING\", 8, 3024},"
            },
            {
              "line": 3053,
              "text": "    {\"WASR\", 4, 3025},"
            }
          ]
        },
        {
          "line": 3600,
          "match": "{\"STONE\", 5, 3572},",
          "context": [
            {
              "line": 3597,
              "text": "    {\"MINNESOTA\", 9, 3569},"
            },
            {
              "line": 3598,
              "text": "    {\"FILMS\", 5, 3570},"
            },
            {
              "line": 3599,
              "text": "    {\"COMPLETELY\", 10, 3571},"
            },
            {
              "line": 3600,
              "text": "    {\"STONE\", 5, 3572},"
            },
            {
              "line": 3601,
              "text": "    {\"EWAR\", 4, 3573},"
            },
            {
              "line": 3602,
              "text": "    {\"TZH\", 3, 3574},"
            },
            {
              "line": 3603,
              "text": "    {\"RYOF\", 4, 3575},"
            }
          ]
        },
        {
          "line": 4157,
          "match": "{\"SOFT\", 4, 4129},",
          "context": [
            {
              "line": 4154,
              "text": "    {\"RSTT\", 4, 4126},"
            },
            {
              "line": 4155,
              "text": "    {\"DRIVERS\", 7, 4127},"
            },
            {
              "line": 4156,
              "text": "    {\"EOFH\", 4, 4128},"
            },
            {
              "line": 4157,
              "text": "    {\"SOFT\", 4, 4129},"
            },
            {
              "line": 4158,
              "text": "    {\"FIGURES\", 7, 4130},"
            },
            {
              "line": 4159,
              "text": "    {\"FEMALE\", 6, 4131},"
            },
            {
              "line": 4160,
              "text": "    {\"MMEN\", 4, 4132},"
            }
          ]
        },
        {
          "line": 4771,
          "match": "{\"SOFTWARE\", 8, 4743},",
          "context": [
            {
              "line": 4768,
              "text": "    {\"UNCI\", 4, 4740},"
            },
            {
              "line": 4769,
              "text": "    {\"NBUT\", 4, 4741},"
            },
            {
              "line": 4770,
              "text": "    {\"DBEC\", 4, 4742},"
            },
            {
              "line": 4771,
              "text": "    {\"SOFTWARE\", 8, 4743},"
            },
            {
              "line": 4772,
              "text": "    {\"NGSE\", 4, 4744},"
            },
            {
              "line": 4773,
              "text": "    {\"RUNS\", 4, 4745},"
            },
            {
              "line": 4774,
              "text": "    {\"TRENDS\", 6, 4746},"
            }
          ]
        },
        {
          "line": 5199,
          "match": "{\"HARDCOVER\", 9, 5171},",
          "context": [
            {
              "line": 5196,
              "text": "    {\"LOCATE\", 6, 5168},"
            },
            {
              "line": 5197,
              "text": "    {\"LLYW\", 4, 5169},"
            },
            {
              "line": 5198,
              "text": "    {\"NGAG\", 4, 5170},"
            },
            {
              "line": 5199,
              "text": "    {\"HARDCOVER\", 9, 5171},"
            },
            {
              "line": 5200,
              "text": "    {\"OBSERVED\", 8, 5172},"
            },
            {
              "line": 5201,
              "text": "    {\"CONTENT\", 7, 5173},"
            },
            {
              "line": 5202,
              "text": "    {\"DEAN\", 4, 5174},"
            }
          ]
        },
        {
          "line": 5231,
          "match": "{\"PACKAGE\", 7, 5203},",
          "context": [
            {
              "line": 5228,
              "text": "    {\"ETOC\", 4, 5200},"
            },
            {
              "line": 5229,
              "text": "    {\"ANOF\", 4, 5201},"
            },
            {
              "line": 5230,
              "text": "    {\"CHANNELS\", 8, 5202},"
            },
            {
              "line": 5231,
              "text": "    {\"PACKAGE\", 7, 5203},"
            },
            {
              "line": 5232,
              "text": "    {\"THINKING\", 8, 5204},"
            },
            {
              "line": 5233,
              "text": "    {\"ERICSSON\", 8, 5205},"
            },
            {
              "line": 5234,
              "text": "    {\"TLAN\", 4, 5206},"
            }
          ]
        },
        {
          "line": 5436,
          "match": "{\"HARDLY\", 6, 5408},",
          "context": [
            {
              "line": 5433,
              "text": "    {\"TONL\", 4, 5405},"
            },
            {
              "line": 5434,
              "text": "    {\"LAUNCH\", 6, 5406},"
            },
            {
              "line": 5435,
              "text": "    {\"CIFI\", 4, 5407},"
            },
            {
              "line": 5436,
              "text": "    {\"HARDLY\", 6, 5408},"
            },
            {
              "line": 5437,
              "text": "    {\"LEDB\", 4, 5409},"
            },
            {
              "line": 5438,
              "text": "    {\"OMBI\", 4, 5410},"
            },
            {
              "line": 5439,
              "text": "    {\"LEGS\", 4, 5411},"
            }
          ]
        },
        {
          "line": 5735,
          "match": "{\"LLRE\", 4, 5707},",
          "context": [
            {
              "line": 5732,
              "text": "    {\"GOURMET\", 7, 5704},"
            },
            {
              "line": 5733,
              "text": "    {\"APPEAL\", 6, 5705},"
            },
            {
              "line": 5734,
              "text": "    {\"ERBU\", 4, 5706},"
            },
            {
              "line": 5735,
              "text": "    {\"LLRE\", 4, 5707},"
            },
            {
              "line": 5736,
              "text": "    {\"RABL\", 4, 5708},"
            },
            {
              "line": 5737,
              "text": "    {\"NGUA\", 4, 5709},"
            },
            {
              "line": 5738,
              "text": "    {\"ORLEANS\", 7, 5710},"
            }
          ]
        },
        {
          "line": 5774,
          "match": "{\"GRAY\", 4, 5746},",
          "context": [
            {
              "line": 5771,
              "text": "    {\"OCEAN\", 5, 5743},"
            },
            {
              "line": 5772,
              "text": "    {\"PREMIER\", 7, 5744},"
            },
            {
              "line": 5773,
              "text": "    {\"INDUSTRIAL\", 10, 5745},"
            },
            {
              "line": 5774,
              "text": "    {\"GRAY\", 4, 5746},"
            },
            {
              "line": 5775,
              "text": "    {\"DBEA\", 4, 5747},"
            },
            {
              "line": 5776,
              "text": "    {\"NEXP\", 4, 5748},"
            },
            {
              "line": 5777,
              "text": "    {\"EFFO\", 4, 5749},"
            }
          ]
        },
        {
          "line": 5909,
          "match": "{\"PACKAGING\", 9, 5881},",
          "context": [
            {
              "line": 5906,
              "text": "    {\"GNY\", 3, 5878},"
            },
            {
              "line": 5907,
              "text": "    {\"EMPLOY\", 6, 5879},"
            },
            {
              "line": 5908,
              "text": "    {\"SPYWARE\", 7, 5880},"
            },
            {
              "line": 5909,
              "text": "    {\"PACKAGING\", 9, 5881},"
            },
            {
              "line": 5910,
              "text": "    {\"INDT\", 4, 5882},"
            },
            {
              "line": 5911,
              "text": "    {\"JOSE\", 4, 5883},"
            },
            {
              "line": 5912,
              "text": "    {\"DISH\", 4, 5884},"
            }
          ]
        },
        {
          "line": 5982,
          "match": "{\"CANDIDATES\", 10, 5954},",
          "context": [
            {
              "line": 5979,
              "text": "    {\"OURP\", 4, 5951},"
            },
            {
              "line": 5980,
              "text": "    {\"RUSH\", 4, 5952},"
            },
            {
              "line": 5981,
              "text": "    {\"AYZ\", 3, 5953},"
            },
            {
              "line": 5982,
              "text": "    {\"CANDIDATES\", 10, 5954},"
            },
            {
              "line": 5983,
              "text": "    {\"CHARLOTTE\", 9, 5955},"
            },
            {
              "line": 5984,
              "text": "    {\"ORDERED\", 7, 5956},"
            },
            {
              "line": 5985,
              "text": "    {\"DOUBT\", 5, 5957},"
            }
          ]
        },
        {
          "line": 5984,
          "match": "{\"ORDERED\", 7, 5956},",
          "context": [
            {
              "line": 5981,
              "text": "    {\"AYZ\", 3, 5953},"
            },
            {
              "line": 5982,
              "text": "    {\"CANDIDATES\", 10, 5954},"
            },
            {
              "line": 5983,
              "text": "    {\"CHARLOTTE\", 9, 5955},"
            },
            {
              "line": 5984,
              "text": "    {\"ORDERED\", 7, 5956},"
            },
            {
              "line": 5985,
              "text": "    {\"DOUBT\", 5, 5957},"
            },
            {
              "line": 5986,
              "text": "    {\"BABL\", 4, 5958},"
            },
            {
              "line": 5987,
              "text": "    {\"BARELY\", 6, 5959},"
            }
          ]
        },
        {
          "line": 6882,
          "match": "{\"NAPR\", 4, 6854},",
          "context": [
            {
              "line": 6879,
              "text": "    {\"KNIFE\", 5, 6851},"
            },
            {
              "line": 6880,
              "text": "    {\"USPE\", 4, 6852},"
            },
            {
              "line": 6881,
              "text": "    {\"SEATS\", 5, 6853},"
            },
            {
              "line": 6882,
              "text": "    {\"NAPR\", 4, 6854},"
            },
            {
              "line": 6883,
              "text": "    {\"APPROACHES\", 10, 6855},"
            },
            {
              "line": 6884,
              "text": "    {\"BIZ\", 3, 6856},"
            },
            {
              "line": 6885,
              "text": "    {\"RECOVER\", 7, 6857},"
            }
          ]
        },
        {
          "line": 6973,
          "match": "{\"RINGTONE\", 8, 6945},",
          "context": [
            {
              "line": 6970,
              "text": "    {\"LPLA\", 4, 6942},"
            },
            {
              "line": 6971,
              "text": "    {\"ATTACHMENT\", 10, 6943},"
            },
            {
              "line": 6972,
              "text": "    {\"POTATO\", 6, 6944},"
            },
            {
              "line": 6973,
              "text": "    {\"RINGTONE\", 8, 6945},"
            },
            {
              "line": 6974,
              "text": "    {\"HEAG\", 4, 6946},"
            },
            {
              "line": 6975,
              "text": "    {\"UZM\", 3, 6947},"
            },
            {
              "line": 6976,
              "text": "    {\"OPPOSITE\", 8, 6948},"
            }
          ]
        },
        {
          "line": 7032,
          "match": "{\"ILLR\", 4, 7004},",
          "context": [
            {
              "line": 7029,
              "text": "    {\"CROWN\", 5, 7001},"
            },
            {
              "line": 7030,
              "text": "    {\"STREAM\", 6, 7002},"
            },
            {
              "line": 7031,
              "text": "    {\"PAR\", 3, 7003},"
            },
            {
              "line": 7032,
              "text": "    {\"ILLR\", 4, 7004},"
            },
            {
              "line": 7033,
              "text": "    {\"AZIN\", 4, 7005},"
            },
            {
              "line": 7034,
              "text": "    {\"UNDERGROUND\", 11, 7006},"
            },
            {
              "line": 7035,
              "text": "    {\"ENHANCE\", 7, 7007},"
            }
          ]
        },
        {
          "line": 7122,
          "match": "{\"PACK\", 4, 7094},",
          "context": [
            {
              "line": 7119,
              "text": "    {\"NALY\", 4, 7091},"
            },
            {
              "line": 7120,
              "text": "    {\"PROTEINS\", 8, 7092},"
            },
            {
              "line": 7121,
              "text": "    {\"APPROXIMATELY\", 13, 7093},"
            },
            {
              "line": 7122,
              "text": "    {\"PACK\", 4, 7094},"
            },
            {
              "line": 7123,
              "text": "    {\"REYO\", 4, 7095},"
            },
            {
              "line": 7124,
              "text": "    {\"SAGR\", 4, 7096},"
            },
            {
              "line": 7125,
              "text": "    {\"EXP\", 3, 7097},"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Main/Varicode.cpp",
      "exists": true,
      "bytes": 72661,
      "lines": 2371,
      "score": 1011,
      "keyword_hits": {
        "mask": 11,
        "decode": 8,
        "Decode": 8,
        "message": 67,
        "Message": 67,
        "crc": 26,
        "CRC": 26,
        "pack": 304,
        "unpack": 76,
        "Varicode": 226,
        "JSC": 9
      },
      "phase_scores": {
        "symbol_to_bits": 231,
        "bit_order_interleaver": 0,
        "whitening_mask": 11,
        "ldpc_fec": 0,
        "message91_crc": 641,
        "timing_constants": 0
      },
      "candidate_functions": [
        {
          "line": 359,
          "name": "Varicode::extendedChars",
          "signature": "QString Varicode::extendedChars() {"
        },
        {
          "line": 372,
          "name": "Varicode::escape",
          "signature": "QString Varicode::escape(const QString &text) {"
        },
        {
          "line": 394,
          "name": "Varicode::unescape",
          "signature": "QString Varicode::unescape(const QString &text) {"
        },
        {
          "line": 413,
          "name": "Varicode::rstrip",
          "signature": "QString Varicode::rstrip(const QString &str) {"
        },
        {
          "line": 424,
          "name": "Varicode::lstrip",
          "signature": "QString Varicode::lstrip(const QString &str) {"
        },
        {
          "line": 438,
          "name": "Varicode::defaultHuffTable",
          "signature": "QMap<QString, QString> Varicode::defaultHuffTable() { return hufftable; }"
        },
        {
          "line": 440,
          "name": "Varicode::cqString",
          "signature": "QString Varicode::cqString(int number) {"
        },
        {
          "line": 447,
          "name": "Varicode::hbString",
          "signature": "QString Varicode::hbString(int number) {"
        },
        {
          "line": 454,
          "name": "Varicode::startsWithCQ",
          "signature": "bool Varicode::startsWithCQ(QString text) {"
        },
        {
          "line": 463,
          "name": "Varicode::startsWithHB",
          "signature": "bool Varicode::startsWithHB(QString text) {"
        },
        {
          "line": 472,
          "name": "Varicode::formatSNR",
          "signature": "QString Varicode::formatSNR(int snr) {"
        },
        {
          "line": 482,
          "name": "Varicode::checksum16",
          "signature": "QString Varicode::checksum16(QString const &input) {"
        },
        {
          "line": 493,
          "name": "Varicode::checksum16Valid",
          "signature": "bool Varicode::checksum16Valid(QString const &checksum, QString const &input) {"
        },
        {
          "line": 500,
          "name": "Varicode::checksum32",
          "signature": "QString Varicode::checksum32(QString const &input) {"
        },
        {
          "line": 511,
          "name": "Varicode::checksum32Valid",
          "signature": "bool Varicode::checksum32Valid(QString const &checksum, QString const &input) {"
        },
        {
          "line": 518,
          "name": "Varicode::parseCallsigns",
          "signature": "QStringList Varicode::parseCallsigns(QString const &input) {"
        },
        {
          "line": 540,
          "name": "Varicode::parseGrids",
          "signature": "QStringList Varicode::parseGrids(const QString &input) {"
        },
        {
          "line": 626,
          "name": "Varicode::huffValidChars",
          "signature": "QSet<QString> Varicode::huffValidChars(const QMap<QString, QString> &huff) {"
        },
        {
          "line": 632,
          "name": "Varicode::bytesToBits",
          "signature": "QVector<bool> Varicode::bytesToBits(char *bitvec, int n) {"
        },
        {
          "line": 641,
          "name": "Varicode::strToBits",
          "signature": "QVector<bool> Varicode::strToBits(QString const &bitvec) {"
        },
        {
          "line": 649,
          "name": "Varicode::bitsToStr",
          "signature": "QString Varicode::bitsToStr(QVector<bool> const &bitvec) {"
        },
        {
          "line": 657,
          "name": "Varicode::intToBits",
          "signature": "QVector<bool> Varicode::intToBits(quint64 value, int expected) {"
        },
        {
          "line": 674,
          "name": "Varicode::bitsToInt",
          "signature": "quint64 Varicode::bitsToInt(QVector<bool> const value) {"
        },
        {
          "line": 682,
          "name": "Varicode::bitsToInt",
          "signature": "quint64 Varicode::bitsToInt(QVector<bool>::ConstIterator start, int n) {"
        }
      ],
      "candidate_arrays": [],
      "candidate_defines": [
        {
          "line": 1947,
          "name": "JS8_FAST_DATA_CAN_USE_HUFF",
          "value": "0"
        }
      ],
      "snippets": [
        {
          "line": 2,
          "match": "* @file Varicode.cpp",
          "context": [
            {
              "line": 1,
              "text": "/**"
            },
            {
              "line": 2,
              "text": " * @file Varicode.cpp"
            },
            {
              "line": 3,
              "text": " * @brief implementation of encoder"
            },
            {
              "line": 4,
              "text": " * (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved"
            },
            {
              "line": 5,
              "text": " *"
            }
          ]
        },
        {
          "line": 8,
          "match": "#include \"Varicode.h\"",
          "context": [
            {
              "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": 9,
          "match": "#include \"JS8_JSC/JSC.h\"",
          "context": [
            {
              "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 <QLoggingCategory>"
            }
          ]
        },
        {
          "line": 10,
          "match": "#include \"JS8_Mode/DecodedText.h\"",
          "context": [
            {
              "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 <QLoggingCategory>"
            },
            {
              "line": 13,
              "text": "#include <QMap>"
            }
          ]
        },
        {
          "line": 16,
          "match": "#include <vendor/CRCpp/CRC.h>",
          "context": [
            {
              "line": 13,
              "text": "#include <QMap>"
            },
            {
              "line": 14,
              "text": "#include <QSet>"
            },
            {
              "line": 15,
              "text": "#include <boost/format.hpp>"
            },
            {
              "line": 16,
              "text": "#include <vendor/CRCpp/CRC.h>"
            },
            {
              "line": 17,
              "text": ""
            },
            {
              "line": 18,
              "text": "#include <cmath>"
            },
            {
              "line": 19,
              "text": "#include <stdexcept>"
            }
          ]
        },
        {
          "line": 21,
          "match": "#define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS",
          "context": [
            {
              "line": 18,
              "text": "#include <cmath>"
            },
            {
              "line": 19,
              "text": "#include <stdexcept>"
            },
            {
              "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": 22,
          "match": "#define CRCPP_USE_CPP11",
          "context": [
            {
              "line": 19,
              "text": "#include <stdexcept>"
            },
            {
              "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": 24,
          "match": "Q_DECLARE_LOGGING_CATEGORY(varicode_js8)",
          "context": [
            {
              "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,
          "match": "QString pack_callsign_pattern = {",
          "context": [
            {
              "line": 40,
              "text": "// {R\"((?<callsign>\\b(?<prefix>[A-Z0-9]{1,4}\\/)?(?<base>([0-9A-Z])?([0-9A-Z])([0-9])([A-Z])?([A-Z])?([A-Z])?)(?<suffix>\\/[A-Z0-9]{1,4})?)\\b)\"};"
            },
            {
              "line": 41,
              "text": "QString compound_callsign_pattern = {"
            },
            {
              "line": 42,
              "text": "    R\"((?<callsign>(?:[@]?|\\b)(?<extended>[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": 68,
          "match": "{\">\", 5}, // relay message",
          "context": [
            {
              "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": 70,
          "match": "{\" STATUS?\", 6}, // query idle message",
          "context": [
            {
              "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": 76,
          "match": "{\" MSG\", 9}, // this is a complete message",
          "context": [
            {
              "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": 78,
          "match": "{\" MSG TO:\", 10}, // store message at a station",
          "context": [
            {
              "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,
          "match": "{\" QUERY MSGS\", 12},  // do you have any stored messages?",
          "context": [
            {
              "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": 83,
          "match": "{\" QUERY MSGS?\", 12}, // do you have any stored messages?",
          "context": [
            {
              "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": 91,
          "match": "{\" INFO?\", 16}, // what is your info message?",
          "context": [
            {
              "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": 92,
          "match": "{\" INFO\", 17},  // this is my info message",
          "context": [
            {
              "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": 114,
          "match": "{\" AGN?\", 30}, // repeat message",
          "context": [
            {
              "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": 133,
          "match": "// commands that are checksummed and their crc size",
          "context": [
            {
              "line": 130,
              "text": "// commands that may include an SNR value"
            },
            {
              "line": 131,
              "text": "QSet<int> snr_cmds = {25, 29};"
            },
            {
              "line": 132,
              "text": ""
            },
            {
              "line": 133,
              "text": "// commands that are checksummed and their crc size"
            },
            {
              "line": 134,
              "text": "QMap<int, int> 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": 159,
          "match": "// buildMessageFrames)",
          "context": [
            {
              "line": 156,
              "text": "QRegularExpression"
            },
            {
              "line": 157,
              "text": "    compound_re(\"^\\\\s*[`]\" + callsign_pattern + \"(?<extra>\" +"
            },
            {
              "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<QString, QString> hufftable = {"
            }
          ]
        },
        {
          "line": 292,
          "match": "// status flags in HB messages are deprecated as of 2.2, later versions will",
          "context": [
            {
              "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": 294,
          "match": "// start with HB you'll have to address the packHeartbeatMessage and how the",
          "context": [
            {
              "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<quint32, QString> hbs = {"
            },
            {
              "line": 297,
              "text": "    {0, \"HB\"}, // HB"
            }
          ]
        },
        {
          "line": 359,
          "match": "QString Varicode::extendedChars() {",
          "context": [
            {
              "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": 362,
          "match": "for (quint32 i = 0; i < JSC::prefixSize; i++) {",
          "context": [
            {
              "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": 363,
          "match": "if (JSC::prefix[i].size != 1) {",
          "context": [
            {
              "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": 366,
          "match": "c.append(QLatin1String(JSC::prefix[i].str, 1));",
          "context": [
            {
              "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": 372,
          "match": "QString Varicode::escape(const QString &text) {",
          "context": [
            {
              "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": 394,
          "match": "QString Varicode::unescape(const QString &text) {",
          "context": [
            {
              "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;"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/JS8.cpp",
      "exists": true,
      "bytes": 113531,
      "lines": 2913,
      "score": 387,
      "keyword_hits": {
        "whiten": 7,
        "mask": 14,
        "ldpc": 23,
        "LDPC": 23,
        "decode": 142,
        "Decode": 142,
        "message": 41,
        "Message": 41,
        "crc": 23,
        "CRC": 23,
        "pack": 1,
        "symbol": 37,
        "tone": 37,
        "Costas": 61,
        "soft": 8,
        "llr": 51,
        "LLR": 51,
        "hard": 11,
        "candidates": 15,
        "ordered": 6,
        "JS8_RX_SAMPLE_RATE": 5
      },
      "phase_scores": {
        "symbol_to_bits": 224,
        "bit_order_interleaver": 6,
        "whitening_mask": 21,
        "ldpc_fec": 30,
        "message91_crc": 24,
        "timing_constants": 5
      },
      "candidate_functions": [
        {
          "line": 891,
          "name": "CRC12",
          "signature": "template <typename T> std::uint16_t CRC12(T const &range) {"
        },
        {
          "line": 895,
          "name": "checkCRC12",
          "signature": "bool checkCRC12(std::array<std::int8_t, KK> const &decoded) {"
        },
        {
          "line": 918,
          "name": "extractmessage174",
          "signature": "std::string extractmessage174(std::array<int8_t, KK> const &decoded) {"
        },
        {
          "line": 2615,
          "name": "makeDecodeEntry",
          "signature": "DecodeEntry makeDecodeEntry(int shift, int &kpos, int &ksz) {"
        },
        {
          "line": 2750,
          "name": "JS8::Decoder::start",
          "signature": "void JS8::Decoder::start(QThread::Priority priority) {"
        },
        {
          "line": 2754,
          "name": "JS8::Decoder::quit",
          "signature": "void JS8::Decoder::quit() {"
        },
        {
          "line": 2761,
          "name": "JS8::Decoder::decode",
          "signature": "void JS8::Decoder::decode() {"
        }
      ],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 11,
          "match": "#include \"JS8_Mode/whitening_processor.h\"",
          "context": [
            {
              "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": 12,
          "match": "#include \"ldpc_feedback.h\"",
          "context": [
            {
              "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 <QDebug>"
            }
          ]
        },
        {
          "line": 13,
          "match": "#include \"soft_combiner.h\"",
          "context": [
            {
              "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 <QDebug>"
            },
            {
              "line": 16,
              "text": "#include <QLoggingCategory>"
            }
          ]
        },
        {
          "line": 21,
          "match": "#include <boost/crc.hpp>",
          "context": [
            {
              "line": 18,
              "text": ""
            },
            {
              "line": 19,
              "text": "#include <algorithm>"
            },
            {
              "line": 20,
              "text": "#include <atomic>"
            },
            {
              "line": 21,
              "text": "#include <boost/crc.hpp>"
            },
            {
              "line": 22,
              "text": "#include <boost/math/ccmath/round.hpp>"
            },
            {
              "line": 23,
              "text": "#include <boost/multi_index/key.hpp>"
            },
            {
              "line": 24,
              "text": "#include <boost/multi_index/ordered_index.hpp>"
            }
          ]
        },
        {
          "line": 24,
          "match": "#include <boost/multi_index/ordered_index.hpp>",
          "context": [
            {
              "line": 21,
              "text": "#include <boost/crc.hpp>"
            },
            {
              "line": 22,
              "text": "#include <boost/math/ccmath/round.hpp>"
            },
            {
              "line": 23,
              "text": "#include <boost/multi_index/key.hpp>"
            },
            {
              "line": 24,
              "text": "#include <boost/multi_index/ordered_index.hpp>"
            },
            {
              "line": 25,
              "text": "#include <boost/multi_index/ranked_index.hpp>"
            },
            {
              "line": 26,
              "text": "#include <boost/multi_index_container.hpp>"
            },
            {
              "line": 27,
              "text": "#include <chrono>"
            }
          ]
        },
        {
          "line": 45,
          "match": "#include <unordered_map>",
          "context": [
            {
              "line": 42,
              "text": "#include <sstream>"
            },
            {
              "line": 43,
              "text": "#include <stdexcept>"
            },
            {
              "line": 44,
              "text": "#include <string_view>"
            },
            {
              "line": 45,
              "text": "#include <unordered_map>"
            },
            {
              "line": 46,
              "text": "#include <utility>"
            },
            {
              "line": 47,
              "text": "#include <vector>"
            },
            {
              "line": 48,
              "text": "#include <vendor/Eigen/Dense>"
            }
          ]
        },
        {
          "line": 50,
          "match": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);",
          "context": [
            {
              "line": 47,
              "text": "#include <vector>"
            },
            {
              "line": 48,
              "text": "#include <vendor/Eigen/Dense>"
            },
            {
              "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": 52,
          "match": "// A C++ conversion of the Fortran JS8 encoding and decoder function.",
          "context": [
            {
              "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": 61,
          "match": "//   2. The BP decoder should be a faithful reproduction of the Fortran",
          "context": [
            {
              "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,
          "match": "//   3. The OSD decoder is no longer used, and the depth is now fixed at",
          "context": [
            {
              "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": 68,
              "text": "//   4. The Fortran version didn't compute the 40% rank consistently in"
            }
          ]
        },
        {
          "line": 83,
          "match": "//      to contribute to decoder yield, so it's been removed.",
          "context": [
            {
              "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": 164,
          "match": "// parameter (KK=87)                     !Information bits (75 + CRC12)",
          "context": [
            {
              "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": 165,
          "match": "// parameter (ND=58)                     !Data symbols",
          "context": [
            {
              "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": 166,
          "match": "// parameter (NS=21)                     !Sync symbols (3 @ Costas 7x7)",
          "context": [
            {
              "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": 167,
          "match": "// parameter (NN=NS+ND)                  !Total channel symbols (79)",
          "context": [
            {
              "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": 174,
          "match": "// KK\t87\tNumber of information bits (75 message bits + 12 CRC bits).",
          "context": [
            {
              "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": 175,
          "match": "// ND\t58\tNumber of data symbols in the JS8 transmission.",
          "context": [
            {
              "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": 176,
          "match": "// NS\t21\tNumber of synchronization symbols (3 Costas arrays of size 7).",
          "context": [
            {
              "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": 177,
          "match": "// NN\t79\tTotal number of channel symbols (NN = NS + ND).",
          "context": [
            {
              "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": 183,
          "match": "constexpr int K = 87;            // Message bits",
          "context": [
            {
              "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": 185,
          "match": "constexpr int KK = 87;           // Information bits (75 + CRC12)",
          "context": [
            {
              "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": 186,
          "match": "constexpr int ND = 58;           // Data symbols",
          "context": [
            {
              "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": 187,
          "match": "constexpr int NS = 21;           // Sync symbols (3 @ Costas 7x7)",
          "context": [
            {
              "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": 188,
          "match": "constexpr int NN = NS + ND;      // Total channel symbols (79)",
          "context": [
            {
              "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": 204,
          "match": "//   NCOSTAS  - Which JS8 Costas Arrays to use",
          "context": [
            {
              "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": 207,
          "match": "//   NDOWNSPS - Number of samples per symbol after downsampling.",
          "context": [
            {
              "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": 209,
          "match": "//   XXX JZ       - Range of symbol offsets considered during decoding. ASTART",
          "context": [
            {
              "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": 211,
          "match": "//   input wave NSTEP    - Rough time-sync step size NHSYM    - Number of symbol",
          "context": [
            {
              "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": ""
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/DecodedText.cpp",
      "exists": true,
      "bytes": 10173,
      "lines": 344,
      "score": 176,
      "keyword_hits": {
        "decode": 42,
        "Decode": 42,
        "message": 32,
        "Message": 32,
        "pack": 22,
        "unpack": 22,
        "Varicode": 32
      },
      "phase_scores": {
        "symbol_to_bits": 23,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 76,
        "timing_constants": 0
      },
      "candidate_functions": [
        {
          "line": 109,
          "name": "DecodedText::tryUnpackFastData",
          "signature": "bool DecodedText::tryUnpackFastData(QString const &m) {"
        },
        {
          "line": 131,
          "name": "DecodedText::tryUnpackData",
          "signature": "bool DecodedText::tryUnpackData(QString const &m) {"
        },
        {
          "line": 153,
          "name": "DecodedText::tryUnpackHeartbeat",
          "signature": "bool DecodedText::tryUnpackHeartbeat(QString const &m) {"
        },
        {
          "line": 198,
          "name": "DecodedText::tryUnpackCompound",
          "signature": "bool DecodedText::tryUnpackCompound(QString const &m) {"
        },
        {
          "line": 232,
          "name": "DecodedText::tryUnpackDirected",
          "signature": "bool DecodedText::tryUnpackDirected(QString const &m) {"
        },
        {
          "line": 305,
          "name": "DecodedText::messageWords",
          "signature": "QStringList DecodedText::messageWords() const {"
        },
        {
          "line": 323,
          "name": "DecodedText::string",
          "signature": "QString DecodedText::string() const {"
        }
      ],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 2,
          "match": "* @file DecodedText.cpp",
          "context": [
            {
              "line": 1,
              "text": "/**"
            },
            {
              "line": 2,
              "text": " * @file DecodedText.cpp"
            },
            {
              "line": 3,
              "text": " * @brief Implementation of DecodedText class"
            },
            {
              "line": 4,
              "text": " */"
            },
            {
              "line": 5,
              "text": ""
            }
          ]
        },
        {
          "line": 3,
          "match": "* @brief Implementation of DecodedText class",
          "context": [
            {
              "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": 6,
          "match": "#include \"DecodedText.h\"",
          "context": [
            {
              "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 <JS8_Main/Varicode.h>"
            },
            {
              "line": 9,
              "text": ""
            }
          ]
        },
        {
          "line": 8,
          "match": "#include <JS8_Main/Varicode.h>",
          "context": [
            {
              "line": 5,
              "text": ""
            },
            {
              "line": 6,
              "text": "#include \"DecodedText.h\""
            },
            {
              "line": 7,
              "text": "#include \"JS8_Include/commons.h\""
            },
            {
              "line": 8,
              "text": "#include <JS8_Main/Varicode.h>"
            },
            {
              "line": 9,
              "text": ""
            },
            {
              "line": 10,
              "text": "#include <QStringBuilder>"
            },
            {
              "line": 11,
              "text": ""
            }
          ]
        },
        {
          "line": 17,
          "match": "// Quality level below which we'll consider a decode to be suspect;",
          "context": [
            {
              "line": 14,
              "text": "/******************************************************************************/"
            },
            {
              "line": 15,
              "text": ""
            },
            {
              "line": 16,
              "text": "namespace {"
            },
            {
              "line": 17,
              "text": "// Quality level below which we'll consider a decode to be suspect;"
            },
            {
              "line": 18,
              "text": "// the UI will generally enclose the decode within [] characters to"
            },
            {
              "line": 19,
              "text": "// denote it as being sketchy."
            },
            {
              "line": 20,
              "text": ""
            }
          ]
        },
        {
          "line": 18,
          "match": "// the UI will generally enclose the decode within [] characters to",
          "context": [
            {
              "line": 15,
              "text": ""
            },
            {
              "line": 16,
              "text": "namespace {"
            },
            {
              "line": 17,
              "text": "// Quality level below which we'll consider a decode to be suspect;"
            },
            {
              "line": 18,
              "text": "// the UI will generally enclose the decode within [] characters to"
            },
            {
              "line": 19,
              "text": "// denote it as being sketchy."
            },
            {
              "line": 20,
              "text": ""
            },
            {
              "line": 21,
              "text": "constexpr auto QUALITY_THRESHOLD = 0.17f;"
            }
          ]
        },
        {
          "line": 31,
          "match": "// here, but arguably it should be part of JS8::Submode or Varicode.",
          "context": [
            {
              "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,
          "match": "case Varicode::SubmodeType::JS8CallNormal:",
          "context": [
            {
              "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": 37,
          "match": "case Varicode::SubmodeType::JS8CallFast:",
          "context": [
            {
              "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": 39,
          "match": "case Varicode::SubmodeType::JS8CallTurbo:",
          "context": [
            {
              "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": 41,
          "match": "case Varicode::SubmodeType::JS8CallSlow:",
          "context": [
            {
              "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": 43,
          "match": "case Varicode::SubmodeType::JS8CallUltra:",
          "context": [
            {
              "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": 66,
          "match": "// Attempts to unpack, using the unpack strategies defined",
          "context": [
            {
              "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": 67,
          "match": "// in the order of the unpack strategies array, until one",
          "context": [
            {
              "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": 72,
          "match": "* @brief Construct a new Decoded Text:: Decoded Text object (private)",
          "context": [
            {
              "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": 83,
          "match": "DecodedText::DecodedText(QString const &frame, int bits, int submode,",
          "context": [
            {
              "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": 86,
          "match": ": frameType_(Varicode::FrameUnknown), frame_(frame), isAlt_(false),",
          "context": [
            {
              "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": 87,
          "match": "isHeartbeat_(false), isLowConfidence_(isLowConfidence), message_(frame_),",
          "context": [
            {
              "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": 90,
          "match": "auto const m = message().trimmed();",
          "context": [
            {
              "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": 93,
              "text": "        return;"
            }
          ]
        },
        {
          "line": 95,
          "match": "for (auto unpack : unpackStrategies) {",
          "context": [
            {
              "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": 96,
          "match": "if ((this->*unpack)(m))",
          "context": [
            {
              "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": 103,
          "match": "* @brief Try to unpack fast data message (private)",
          "context": [
            {
              "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": 109,
          "match": "bool DecodedText::tryUnpackFastData(QString const &m) {",
          "context": [
            {
              "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": 110,
          "match": "if ((bits_ & Varicode::JS8CallData) != Varicode::JS8CallData)",
          "context": [
            {
              "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": 113,
          "match": "if (auto const data = Varicode::unpackFastDataMessage(m); data.isEmpty()) {",
          "context": [
            {
              "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": 116,
          "match": "message_ = data;",
          "context": [
            {
              "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": 117,
          "match": "frameType_ = Varicode::FrameData;",
          "context": [
            {
              "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": 125,
          "match": "* @brief Try to unpack data message (private)",
          "context": [
            {
              "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"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/JS8Submode.cpp",
      "exists": true,
      "bytes": 13093,
      "lines": 399,
      "score": 157,
      "keyword_hits": {
        "decode": 6,
        "Decode": 6,
        "Varicode": 7,
        "symbol": 32,
        "tone": 9,
        "Costas": 25,
        "samplesForOneSymbol": 13,
        "toneSpacing": 8,
        "JS8_RX_SAMPLE_RATE": 5
      },
      "phase_scores": {
        "symbol_to_bits": 41,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 7,
        "timing_constants": 26
      },
      "candidate_functions": [
        {
          "line": 79,
          "name": "samplesForOneSymbol",
          "signature": "constexpr unsigned int samplesForOneSymbol() const {"
        },
        {
          "line": 84,
          "name": "costas",
          "signature": "constexpr Costas::Type costas() const { return m_costas; }"
        },
        {
          "line": 87,
          "name": "samplesForSymbols",
          "signature": "constexpr int samplesForSymbols() const { return m_samplesForSymbols; }"
        },
        {
          "line": 92,
          "name": "toneSpacing",
          "signature": "constexpr double toneSpacing() const { return m_toneSpacing; }"
        },
        {
          "line": 258,
          "name": "costas",
          "signature": "Costas::Type costas(int const submode) { return data(submode).costas(); }"
        },
        {
          "line": 274,
          "name": "samplesForSymbols",
          "signature": "unsigned int samplesForSymbols(int const submode) {"
        },
        {
          "line": 322,
          "name": "samplesForOneSymbol",
          "signature": "unsigned int samplesForOneSymbol(int const submode) {"
        },
        {
          "line": 331,
          "name": "toneSpacing",
          "signature": "double toneSpacing(int const submode) { return data(submode).toneSpacing(); }"
        },
        {
          "line": 357,
          "name": "computeCycleForDecode",
          "signature": "int computeCycleForDecode(int const submode, int const k) {"
        }
      ],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 7,
          "match": "#include \"JS8_Main/Varicode.h\"",
          "context": [
            {
              "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": 9,
              "text": "#include <QLoggingCategory>"
            },
            {
              "line": 10,
              "text": ""
            }
          ]
        },
        {
          "line": 55,
          "match": "// JS8_NUM_SYMBOLS and RX_SAMPLE_RATE definitions, and therefore can",
          "context": [
            {
              "line": 52,
              "text": "    // Constructor; in addition to the basics provided by the constructor"
            },
            {
              "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,
          "match": "unsigned int const samplesForOneSymbol,",
          "context": [
            {
              "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": 61,
          "match": "Costas::Type const costas, int const rxSNRThreshold,",
          "context": [
            {
              "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": 63,
          "match": ": m_name(name), m_samplesForOneSymbol(samplesForOneSymbol),",
          "context": [
            {
              "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": 64,
          "match": "m_startDelayMS(startDelayMS), m_period(period), m_costas(costas),",
          "context": [
            {
              "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": 66,
          "match": "m_samplesForSymbols(JS8_NUM_SYMBOLS * samplesForOneSymbol),",
          "context": [
            {
              "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": 67,
          "match": "m_bandwidth(8 * JS8_RX_SAMPLE_RATE / samplesForOneSymbol),",
          "context": [
            {
              "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": 68,
          "match": "m_samplesPerPeriod(JS8_RX_SAMPLE_RATE * period),",
          "context": [
            {
              "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": 69,
          "match": "m_toneSpacing(JS8_RX_SAMPLE_RATE / (double)samplesForOneSymbol),",
          "context": [
            {
              "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": 71,
          "match": "floor(m_samplesForSymbols +",
          "context": [
            {
              "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": 72,
          "match": "(0.5 + startDelayMS / 1000.0) * JS8_RX_SAMPLE_RATE)),",
          "context": [
            {
              "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": 73,
          "match": "m_dataDuration(m_samplesForSymbols / (double)JS8_RX_SAMPLE_RATE),",
          "context": [
            {
              "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": 79,
          "match": "constexpr unsigned int samplesForOneSymbol() const {",
          "context": [
            {
              "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": 80,
          "match": "return m_samplesForOneSymbol;",
          "context": [
            {
              "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,
          "match": "constexpr Costas::Type costas() const { return m_costas; }",
          "context": [
            {
              "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": 87,
          "match": "constexpr int samplesForSymbols() const { return m_samplesForSymbols; }",
          "context": [
            {
              "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": 92,
          "match": "constexpr double toneSpacing() const { return m_toneSpacing; }",
          "context": [
            {
              "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": 99,
          "match": "unsigned int m_samplesForOneSymbol;",
          "context": [
            {
              "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": 102,
          "match": "Costas::Type m_costas;",
          "context": [
            {
              "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": 105,
          "match": "int m_samplesForSymbols;",
          "context": [
            {
              "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": 108,
          "match": "double m_toneSpacing;",
          "context": [
            {
              "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": 114,
          "match": "// Data for known submodes. Normal mode uses the old Costas Array",
          "context": [
            {
              "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,
          "match": "JS8A_SYMBOL_SAMPLES,",
          "context": [
            {
              "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": 121,
              "text": "                         Costas::Type::ORIGINAL,"
            }
          ]
        },
        {
          "line": 121,
          "match": "Costas::Type::ORIGINAL,",
          "context": [
            {
              "line": 118,
              "text": "                         JS8A_SYMBOL_SAMPLES,"
            },
            {
              "line": 119,
              "text": "                         JS8A_START_DELAY_MS,"
            },
            {
              "line": 120,
              "text": "                         JS8A_TX_SECONDS,"
            },
            {
              "line": 121,
              "text": "                         Costas::Type::ORIGINAL,"
            },
            {
              "line": 122,
              "text": "                         -24};"
            },
            {
              "line": 123,
              "text": ""
            },
            {
              "line": 124,
              "text": "constexpr Data Fast =   {\"FAST\","
            }
          ]
        },
        {
          "line": 125,
          "match": "JS8B_SYMBOL_SAMPLES,",
          "context": [
            {
              "line": 122,
              "text": "                         -24};"
            },
            {
              "line": 123,
              "text": ""
            },
            {
              "line": 124,
              "text": "constexpr Data Fast =   {\"FAST\","
            },
            {
              "line": 125,
              "text": "                         JS8B_SYMBOL_SAMPLES,"
            },
            {
              "line": 126,
              "text": "                         JS8B_START_DELAY_MS,"
            },
            {
              "line": 127,
              "text": "                         JS8B_TX_SECONDS,"
            },
            {
              "line": 128,
              "text": "                         Costas::Type::MODIFIED,"
            }
          ]
        },
        {
          "line": 128,
          "match": "Costas::Type::MODIFIED,",
          "context": [
            {
              "line": 125,
              "text": "                         JS8B_SYMBOL_SAMPLES,"
            },
            {
              "line": 126,
              "text": "                         JS8B_START_DELAY_MS,"
            },
            {
              "line": 127,
              "text": "                         JS8B_TX_SECONDS,"
            },
            {
              "line": 128,
              "text": "                         Costas::Type::MODIFIED,"
            },
            {
              "line": 129,
              "text": "                         -22,"
            },
            {
              "line": 130,
              "text": "                         16};"
            },
            {
              "line": 131,
              "text": ""
            }
          ]
        },
        {
          "line": 133,
          "match": "JS8C_SYMBOL_SAMPLES,",
          "context": [
            {
              "line": 130,
              "text": "                         16};"
            },
            {
              "line": 131,
              "text": ""
            },
            {
              "line": 132,
              "text": "constexpr Data Turbo =  {\"JS8 40\","
            },
            {
              "line": 133,
              "text": "                         JS8C_SYMBOL_SAMPLES,"
            },
            {
              "line": 134,
              "text": "                         JS8C_START_DELAY_MS,"
            },
            {
              "line": 135,
              "text": "                         JS8C_TX_SECONDS,"
            },
            {
              "line": 136,
              "text": "                         Costas::Type::MODIFIED,"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Main/Varicode.h",
      "exists": true,
      "bytes": 8286,
      "lines": 222,
      "score": 154,
      "keyword_hits": {
        "decode": 3,
        "Decode": 3,
        "message": 19,
        "Message": 19,
        "pack": 44,
        "unpack": 17,
        "Varicode": 5
      },
      "phase_scores": {
        "symbol_to_bits": 32,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 66,
        "timing_constants": 0
      },
      "candidate_functions": [],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 1,
          "match": "#ifndef VARICODE_H",
          "context": [
            {
              "line": 1,
              "text": "#ifndef VARICODE_H"
            },
            {
              "line": 2,
              "text": "#define VARICODE_H"
            },
            {
              "line": 3,
              "text": ""
            },
            {
              "line": 4,
              "text": "/**"
            }
          ]
        },
        {
          "line": 2,
          "match": "#define VARICODE_H",
          "context": [
            {
              "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 <kn4crd@gmail.com> - All Rights Reserved"
            }
          ]
        },
        {
          "line": 14,
          "match": "class Varicode {",
          "context": [
            {
              "line": 11,
              "text": "#include <QThread>"
            },
            {
              "line": 12,
              "text": "#include <QVector>"
            },
            {
              "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": 16,
          "match": "// extra information out of buildMessageFrames",
          "context": [
            {
              "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": 17,
          "match": "struct MessageInfo {",
          "context": [
            {
              "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": 32,
          "match": "// frame type transmitted via itype and decoded by the ft8 decoded",
          "context": [
            {
              "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": 34,
          "match": "JS8Call = 0,      // [000] <- any other frame of the message",
          "context": [
            {
              "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": 35,
          "match": "JS8CallFirst = 1, // [001] <- the first frame of a message",
          "context": [
            {
              "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": 36,
          "match": "JS8CallLast = 2,  // [010] <- the last frame of a message",
          "context": [
            {
              "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": 76,
          "match": "// Varicode();",
          "context": [
            {
              "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": 107,
          "match": "static QString huffDecode(const QMap<QString, QString> &huff,",
          "context": [
            {
              "line": 104,
              "text": ""
            },
            {
              "line": 105,
              "text": "    static QList<QPair<int, QVector<bool>>>"
            },
            {
              "line": 106,
              "text": "    huffEncode(const QMap<QString, QString> &huff, QString const &text);"
            },
            {
              "line": 107,
              "text": "    static QString huffDecode(const QMap<QString, QString> &huff,"
            },
            {
              "line": 108,
              "text": "                              QVector<bool> const &bitvec);"
            },
            {
              "line": 109,
              "text": "    static QSet<QString> huffValidChars(const QMap<QString, QString> &huff);"
            },
            {
              "line": 110,
              "text": ""
            }
          ]
        },
        {
          "line": 120,
          "match": "static quint8 unpack5bits(QString const &value);",
          "context": [
            {
              "line": 117,
              "text": "    static quint64 bitsToInt(QVector<bool>::ConstIterator start, int n);"
            },
            {
              "line": 118,
              "text": "    static QVector<bool> bitsListToBits(QList<QVector<bool>> &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": 121,
          "match": "static QString pack5bits(quint8 packed);",
          "context": [
            {
              "line": 118,
              "text": "    static QVector<bool> bitsListToBits(QList<QVector<bool>> &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": 123,
          "match": "static quint8 unpack6bits(QString const &value);",
          "context": [
            {
              "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": 124,
          "match": "static QString pack6bits(quint8 packed);",
          "context": [
            {
              "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,
          "match": "static quint16 unpack16bits(QString const &value);",
          "context": [
            {
              "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": 127,
          "match": "static QString pack16bits(quint16 packed);",
          "context": [
            {
              "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": 129,
          "match": "static quint32 unpack32bits(QString const &value);",
          "context": [
            {
              "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": 130,
          "match": "static QString pack32bits(quint32 packed);",
          "context": [
            {
              "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": 132,
          "match": "static quint64 unpack64bits(QString const &value);",
          "context": [
            {
              "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": 133,
          "match": "static QString pack64bits(quint64 packed);",
          "context": [
            {
              "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": 135,
          "match": "static quint64 unpack72bits(QString const &value, quint8 *pRem);",
          "context": [
            {
              "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,
          "match": "static QString pack72bits(quint64 value, quint8 rem);",
          "context": [
            {
              "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": 138,
          "match": "static quint32 packAlphaNumeric22(QString const &value, bool isFlag);",
          "context": [
            {
              "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": 139,
          "match": "static QString unpackAlphaNumeric22(quint32 packed, bool *isFlag);",
          "context": [
            {
              "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,
          "match": "static quint64 packAlphaNumeric50(QString const &value);",
          "context": [
            {
              "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": 142,
          "match": "static QString unpackAlphaNumeric50(quint64 packed);",
          "context": [
            {
              "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": 144,
          "match": "static quint32 packCallsign(QString const &value, bool *pPortable);",
          "context": [
            {
              "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);"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/whitening_processor.h",
      "exists": true,
      "bytes": 9129,
      "lines": 259,
      "score": 153,
      "keyword_hits": {
        "whiten": 24,
        "decode": 5,
        "Decode": 5,
        "symbol": 20,
        "tone": 14,
        "Costas": 1,
        "llr": 39,
        "LLR": 39
      },
      "phase_scores": {
        "symbol_to_bits": 73,
        "bit_order_interleaver": 0,
        "whitening_mask": 24,
        "ldpc_fec": 0,
        "message91_crc": 0,
        "timing_constants": 0
      },
      "candidate_functions": [],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 15,
          "match": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);",
          "context": [
            {
              "line": 12,
              "text": "#include <sstream>"
            },
            {
              "line": 13,
              "text": "#include <vector>"
            },
            {
              "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,
          "match": "* @brief Compute per-tone/symbol noise medians and whiten LLRs for a JS8 frame.",
          "context": [
            {
              "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": 21,
          "match": "* Given symbol magnitudes (sans Costas) and winners, produces normalized",
          "context": [
            {
              "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": 22,
          "match": "* LLR0/LLR1, optionally applying noise-based whitening and erasure. Fully",
          "context": [
            {
              "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": 24,
          "match": "* decoder per candidate.",
          "context": [
            {
              "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 <int NROWS, int ND, int N> class WhiteningProcessor {"
            },
            {
              "line": 27,
              "text": "  public:"
            }
          ]
        },
        {
          "line": 26,
          "match": "template <int NROWS, int ND, int N> class WhiteningProcessor {",
          "context": [
            {
              "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 <int NROWS, int ND, int N> class WhiteningProcessor {"
            },
            {
              "line": 27,
              "text": "  public:"
            },
            {
              "line": 28,
              "text": "    struct Result {"
            },
            {
              "line": 29,
              "text": "        std::array<float, 3 * ND> llr0;"
            }
          ]
        },
        {
          "line": 29,
          "match": "std::array<float, 3 * ND> llr0;",
          "context": [
            {
              "line": 26,
              "text": "template <int NROWS, int ND, int N> class WhiteningProcessor {"
            },
            {
              "line": 27,
              "text": "  public:"
            },
            {
              "line": 28,
              "text": "    struct Result {"
            },
            {
              "line": 29,
              "text": "        std::array<float, 3 * ND> llr0;"
            },
            {
              "line": 30,
              "text": "        std::array<float, 3 * ND> llr1;"
            },
            {
              "line": 31,
              "text": "        bool whiteningApplied;"
            },
            {
              "line": 32,
              "text": "        bool erasureApplied;"
            }
          ]
        },
        {
          "line": 30,
          "match": "std::array<float, 3 * ND> llr1;",
          "context": [
            {
              "line": 27,
              "text": "  public:"
            },
            {
              "line": 28,
              "text": "    struct Result {"
            },
            {
              "line": 29,
              "text": "        std::array<float, 3 * ND> llr0;"
            },
            {
              "line": 30,
              "text": "        std::array<float, 3 * ND> llr1;"
            },
            {
              "line": 31,
              "text": "        bool whiteningApplied;"
            },
            {
              "line": 32,
              "text": "        bool erasureApplied;"
            },
            {
              "line": 33,
              "text": "        std::size_t erasures;"
            }
          ]
        },
        {
          "line": 31,
          "match": "bool whiteningApplied;",
          "context": [
            {
              "line": 28,
              "text": "    struct Result {"
            },
            {
              "line": 29,
              "text": "        std::array<float, 3 * ND> llr0;"
            },
            {
              "line": 30,
              "text": "        std::array<float, 3 * ND> llr1;"
            },
            {
              "line": 31,
              "text": "        bool whiteningApplied;"
            },
            {
              "line": 32,
              "text": "        bool erasureApplied;"
            },
            {
              "line": 33,
              "text": "        std::size_t erasures;"
            },
            {
              "line": 34,
              "text": "        double avgAbsPre;"
            }
          ]
        },
        {
          "line": 39,
          "match": "std::array<int, ND> const &symbolWinners,",
          "context": [
            {
              "line": 36,
              "text": "    };"
            },
            {
              "line": 37,
              "text": ""
            },
            {
              "line": 38,
              "text": "    static Result process(std::array<std::array<float, ND>, NROWS> const &s1,"
            },
            {
              "line": 39,
              "text": "                          std::array<int, ND> const &symbolWinners,"
            },
            {
              "line": 40,
              "text": "                          float erasureThreshold, bool debug) {"
            },
            {
              "line": 41,
              "text": "        auto const median ="
            },
            {
              "line": 42,
              "text": "            [](std::vector<float> &values) -> std::optional<float> {"
            }
          ]
        },
        {
          "line": 61,
          "match": "// Estimate per-tone noise using non-winning tone magnitudes across the",
          "context": [
            {
              "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<std::array<float, NROWS>> {"
            }
          ]
        },
        {
          "line": 63,
          "match": "auto const toneNoise =",
          "context": [
            {
              "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<std::array<float, NROWS>> {"
            },
            {
              "line": 65,
              "text": "            std::array<std::vector<float>, NROWS> toneSamples;"
            },
            {
              "line": 66,
              "text": "            std::array<float, NROWS> noise = {};"
            }
          ]
        },
        {
          "line": 65,
          "match": "std::array<std::vector<float>, NROWS> toneSamples;",
          "context": [
            {
              "line": 62,
              "text": "        // frame."
            },
            {
              "line": 63,
              "text": "        auto const toneNoise ="
            },
            {
              "line": 64,
              "text": "            [&]() -> std::optional<std::array<float, NROWS>> {"
            },
            {
              "line": 65,
              "text": "            std::array<std::vector<float>, NROWS> toneSamples;"
            },
            {
              "line": 66,
              "text": "            std::array<float, NROWS> noise = {};"
            },
            {
              "line": 67,
              "text": ""
            },
            {
              "line": 68,
              "text": "            // Collect non-winning magnitudes for each tone."
            }
          ]
        },
        {
          "line": 68,
          "match": "// Collect non-winning magnitudes for each tone.",
          "context": [
            {
              "line": 65,
              "text": "            std::array<std::vector<float>, NROWS> toneSamples;"
            },
            {
              "line": 66,
              "text": "            std::array<float, NROWS> 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": 70,
          "match": "int const winner = symbolWinners[j];",
          "context": [
            {
              "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": 73,
              "text": "                    if (i != winner)"
            }
          ]
        },
        {
          "line": 74,
          "match": "toneSamples[i].push_back(s1[i][j]);",
          "context": [
            {
              "line": 71,
              "text": ""
            },
            {
              "line": 72,
              "text": "                for (int i = 0; i < NROWS; ++i) {"
            },
            {
              "line": 73,
              "text": "                    if (i != winner)"
            },
            {
              "line": 74,
              "text": "                        toneSamples[i].push_back(s1[i][j]);"
            },
            {
              "line": 75,
              "text": "                }"
            },
            {
              "line": 76,
              "text": "            }"
            },
            {
              "line": 77,
              "text": ""
            }
          ]
        },
        {
          "line": 81,
          "match": "if (auto m = median(toneSamples[i]); m) {",
          "context": [
            {
              "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": 95,
          "match": "if (toneNoise && debug) {",
          "context": [
            {
              "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,
          "match": "oss << \"toneNoise:\";",
          "context": [
            {
              "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": 99,
          "match": "for (auto const value : *toneNoise)",
          "context": [
            {
              "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": 102,
          "match": "qCDebug(decoder_js8).noquote() << oss.str().c_str();",
          "context": [
            {
              "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": 105,
          "match": "// Estimate per-symbol noise using non-winning tone magnitudes per",
          "context": [
            {
              "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<std::vector<float>> {"
            },
            {
              "line": 108,
              "text": "            std::vector<float> noise;"
            }
          ]
        },
        {
          "line": 106,
          "match": "// symbol.",
          "context": [
            {
              "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<std::vector<float>> {"
            },
            {
              "line": 108,
              "text": "            std::vector<float> noise;"
            },
            {
              "line": 109,
              "text": "            noise.reserve(ND);"
            }
          ]
        },
        {
          "line": 107,
          "match": "auto const symbolNoise = [&]() -> std::optional<std::vector<float>> {",
          "context": [
            {
              "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<std::vector<float>> {"
            },
            {
              "line": 108,
              "text": "            std::vector<float> noise;"
            },
            {
              "line": 109,
              "text": "            noise.reserve(ND);"
            },
            {
              "line": 110,
              "text": ""
            }
          ]
        },
        {
          "line": 115,
          "match": "int const winner = symbolWinners[j];",
          "context": [
            {
              "line": 112,
              "text": "                std::vector<float> bins;"
            },
            {
              "line": 113,
              "text": "                bins.reserve(NROWS - 1);"
            },
            {
              "line": 114,
              "text": ""
            },
            {
              "line": 115,
              "text": "                int const winner = symbolWinners[j];"
            },
            {
              "line": 116,
              "text": ""
            },
            {
              "line": 117,
              "text": "                for (int i = 0; i < NROWS; ++i) {"
            },
            {
              "line": 118,
              "text": "                    if (i != winner)"
            }
          ]
        },
        {
          "line": 132,
          "match": "if (symbolNoise && !symbolNoise->empty() && debug) {",
          "context": [
            {
              "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": 134,
          "match": "std::minmax_element(symbolNoise->begin(), symbolNoise->end());",
          "context": [
            {
              "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<float>(symbolNoise->size());"
            }
          ]
        },
        {
          "line": 135,
          "match": "float const avg = std::accumulate(symbolNoise->begin(),",
          "context": [
            {
              "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<float>(symbolNoise->size());"
            },
            {
              "line": 138,
              "text": ""
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/soft_combiner.h",
      "exists": true,
      "bytes": 9185,
      "lines": 294,
      "score": 125,
      "keyword_hits": {
        "decode": 8,
        "Decode": 8,
        "soft": 11,
        "llr": 49,
        "LLR": 49,
        "ordered": 2
      },
      "phase_scores": {
        "symbol_to_bits": 61,
        "bit_order_interleaver": 2,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 0,
        "timing_constants": 0
      },
      "candidate_functions": [
        {
          "line": 55,
          "name": "SoftCombiner",
          "signature": "explicit SoftCombiner(bool enabled, bool runSelfTest = true)"
        },
        {
          "line": 104,
          "name": "markDecoded",
          "signature": "void markDecoded(Key const &key) {"
        }
      ],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 14,
          "match": "#include <unordered_map>",
          "context": [
            {
              "line": 11,
              "text": "#include <cstdint>"
            },
            {
              "line": 12,
              "text": "#include <mutex>"
            },
            {
              "line": 13,
              "text": "#include <optional>"
            },
            {
              "line": 14,
              "text": "#include <unordered_map>"
            },
            {
              "line": 15,
              "text": "#include <utility>"
            },
            {
              "line": 16,
              "text": "#include <vector>"
            },
            {
              "line": 17,
              "text": ""
            }
          ]
        },
        {
          "line": 18,
          "match": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);",
          "context": [
            {
              "line": 15,
              "text": "#include <utility>"
            },
            {
              "line": 16,
              "text": "#include <vector>"
            },
            {
              "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,
          "match": "* @brief Cache and combine repeated LLR frames for the same decode candidate.",
          "context": [
            {
              "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": 24,
          "match": "* Uses a coarse freq/dt bin and a small LLR signature as the key; repeated",
          "context": [
            {
              "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": 25,
          "match": "* receptions accumulate LLRs to improve decode probability without changing",
          "context": [
            {
              "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,
          "match": "* over-the-air behavior. Templated on the LLR length so the caller binds it",
          "context": [
            {
              "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 <std::size_t N> class SoftCombiner {"
            }
          ]
        },
        {
          "line": 27,
          "match": "* to the decoder's bit count.",
          "context": [
            {
              "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 <std::size_t N> class SoftCombiner {"
            },
            {
              "line": 30,
              "text": "    using Clock = std::chrono::steady_clock;"
            }
          ]
        },
        {
          "line": 29,
          "match": "template <std::size_t N> class SoftCombiner {",
          "context": [
            {
              "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 <std::size_t N> class SoftCombiner {"
            },
            {
              "line": 30,
              "text": "    using Clock = std::chrono::steady_clock;"
            },
            {
              "line": 31,
              "text": ""
            },
            {
              "line": 32,
              "text": "  public:"
            }
          ]
        },
        {
          "line": 47,
          "match": "std::array<float, N> llr0;",
          "context": [
            {
              "line": 44,
              "text": ""
            },
            {
              "line": 45,
              "text": "    struct Combined {"
            },
            {
              "line": 46,
              "text": "        Key key;"
            },
            {
              "line": 47,
              "text": "        std::array<float, N> llr0;"
            },
            {
              "line": 48,
              "text": "        std::array<float, N> llr1;"
            },
            {
              "line": 49,
              "text": "        int repeats;"
            },
            {
              "line": 50,
              "text": "        bool combined;"
            }
          ]
        },
        {
          "line": 48,
          "match": "std::array<float, N> llr1;",
          "context": [
            {
              "line": 45,
              "text": "    struct Combined {"
            },
            {
              "line": 46,
              "text": "        Key key;"
            },
            {
              "line": 47,
              "text": "        std::array<float, N> llr0;"
            },
            {
              "line": 48,
              "text": "        std::array<float, N> llr1;"
            },
            {
              "line": 49,
              "text": "        int repeats;"
            },
            {
              "line": 50,
              "text": "        bool combined;"
            },
            {
              "line": 51,
              "text": "    };"
            }
          ]
        },
        {
          "line": 53,
          "match": "SoftCombiner() : SoftCombiner(defaultEnabled(), true) {}",
          "context": [
            {
              "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": 55,
          "match": "explicit SoftCombiner(bool enabled, bool runSelfTest = true)",
          "context": [
            {
              "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": 58,
          "match": "qCDebug(decoder_js8)",
          "context": [
            {
              "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": 59,
          "match": "<< \"soft-combining disabled (JS8_SOFT_COMBINING=0)\";",
          "context": [
            {
              "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": 65,
          "match": "Key makeKey(int mode, float f1, float dt, std::array<float, N> const &llr0,",
          "context": [
            {
              "line": 62,
              "text": "            maybeRunSelfTest();"
            },
            {
              "line": 63,
              "text": "    }"
            },
            {
              "line": 64,
              "text": ""
            },
            {
              "line": 65,
              "text": "    Key makeKey(int mode, float f1, float dt, std::array<float, N> const &llr0,"
            },
            {
              "line": 66,
              "text": "                std::array<float, N> const &llr1) const {"
            },
            {
              "line": 67,
              "text": "        return Key{mode, static_cast<int>(std::lround(f1)),"
            },
            {
              "line": 68,
              "text": "                   static_cast<int>(std::lround(dt * 10.0f)), // 100 ms bins"
            }
          ]
        },
        {
          "line": 66,
          "match": "std::array<float, N> const &llr1) const {",
          "context": [
            {
              "line": 63,
              "text": "    }"
            },
            {
              "line": 64,
              "text": ""
            },
            {
              "line": 65,
              "text": "    Key makeKey(int mode, float f1, float dt, std::array<float, N> const &llr0,"
            },
            {
              "line": 66,
              "text": "                std::array<float, N> const &llr1) const {"
            },
            {
              "line": 67,
              "text": "        return Key{mode, static_cast<int>(std::lround(f1)),"
            },
            {
              "line": 68,
              "text": "                   static_cast<int>(std::lround(dt * 10.0f)), // 100 ms bins"
            },
            {
              "line": 69,
              "text": "                   signature(llr0, llr1)};"
            }
          ]
        },
        {
          "line": 69,
          "match": "signature(llr0, llr1)};",
          "context": [
            {
              "line": 66,
              "text": "                std::array<float, N> const &llr1) const {"
            },
            {
              "line": 67,
              "text": "        return Key{mode, static_cast<int>(std::lround(f1)),"
            },
            {
              "line": 68,
              "text": "                   static_cast<int>(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<float, N> const &llr0,"
            }
          ]
        },
        {
          "line": 72,
          "match": "Combined combine(Key const &key, std::array<float, N> const &llr0,",
          "context": [
            {
              "line": 69,
              "text": "                   signature(llr0, llr1)};"
            },
            {
              "line": 70,
              "text": "    }"
            },
            {
              "line": 71,
              "text": ""
            },
            {
              "line": 72,
              "text": "    Combined combine(Key const &key, std::array<float, N> const &llr0,"
            },
            {
              "line": 73,
              "text": "                     std::array<float, N> const &llr1,"
            },
            {
              "line": 74,
              "text": "                     std::chrono::seconds ttl) {"
            },
            {
              "line": 75,
              "text": "        flush(ttl);"
            }
          ]
        },
        {
          "line": 73,
          "match": "std::array<float, N> const &llr1,",
          "context": [
            {
              "line": 70,
              "text": "    }"
            },
            {
              "line": 71,
              "text": ""
            },
            {
              "line": 72,
              "text": "    Combined combine(Key const &key, std::array<float, N> const &llr0,"
            },
            {
              "line": 73,
              "text": "                     std::array<float, N> const &llr1,"
            },
            {
              "line": 74,
              "text": "                     std::chrono::seconds ttl) {"
            },
            {
              "line": 75,
              "text": "        flush(ttl);"
            },
            {
              "line": 76,
              "text": ""
            }
          ]
        },
        {
          "line": 78,
          "match": "return Combined{key, llr0, llr1, 1, false};",
          "context": [
            {
              "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": 85,
          "match": "bucket.push_back(makeEntry(key.signature, llr0, llr1));",
          "context": [
            {
              "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": 86,
          "match": "return Combined{key, llr0, llr1, 1, false};",
          "context": [
            {
              "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": 89,
          "match": "for (std::size_t i = 0; i < llr0.size(); ++i) {",
          "context": [
            {
              "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": 90,
          "match": "it->llr0[i] += llr0[i];",
          "context": [
            {
              "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": 91,
          "match": "it->llr1[i] += llr1[i];",
          "context": [
            {
              "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": 97,
          "match": "qCDebug(decoder_js8)",
          "context": [
            {
              "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": 98,
          "match": "<< \"soft-combining repeats\" << it->repeats << \"mode\" << key.mode",
          "context": [
            {
              "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": 101,
          "match": "return Combined{key, it->llr0, it->llr1, it->repeats, true};",
          "context": [
            {
              "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) {"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/ldpc_feedback.h",
      "exists": true,
      "bytes": 3293,
      "lines": 109,
      "score": 109,
      "keyword_hits": {
        "ldpc": 12,
        "LDPC": 12,
        "decode": 3,
        "Decode": 3,
        "tone": 4,
        "llr": 23,
        "LLR": 23
      },
      "phase_scores": {
        "symbol_to_bits": 31,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 13,
        "message91_crc": 0,
        "timing_constants": 0
      },
      "candidate_functions": [
        {
          "line": 33,
          "name": "llrErasureThreshold",
          "signature": "inline float llrErasureThreshold() {"
        },
        {
          "line": 53,
          "name": "ldpcFeedbackEnabled",
          "signature": "inline bool ldpcFeedbackEnabled() {"
        },
        {
          "line": 59,
          "name": "ldpcFeedbackMaxPasses",
          "signature": "inline int ldpcFeedbackMaxPasses() {"
        }
      ],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 14,
          "match": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8);",
          "context": [
            {
              "line": 11,
              "text": "#include <cstdlib>"
            },
            {
              "line": 12,
              "text": "#include <optional>"
            },
            {
              "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,
          "match": "* @brief LDPC erasure threshold config and feedback refinement helpers.",
          "context": [
            {
              "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": 21,
          "match": "* refineLlrsWithLdpcFeedback shrinks/boosts LLRs using the decoded",
          "context": [
            {
              "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": 22,
          "match": "* codeword to retry LDPC. Used inside the JS8 decode loop between",
          "context": [
            {
              "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": 23,
          "match": "* LDPC passes.",
          "context": [
            {
              "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": 25,
          "match": "constexpr float LLR_ERASURE_THRESHOLD_DEFAULT = 0.25f;",
          "context": [
            {
              "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": 26,
          "match": "constexpr float LLR_FEEDBACK_CONFIDENT_MIN = 3.0f;",
          "context": [
            {
              "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": 27,
          "match": "constexpr float LLR_FEEDBACK_UNCERTAIN_MAX = 1.0f;",
          "context": [
            {
              "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": 28,
          "match": "constexpr float LLR_FEEDBACK_CONFIDENT_BOOST = 1.2f;",
          "context": [
            {
              "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": 29,
          "match": "constexpr float LLR_FEEDBACK_UNCERTAIN_SHRINK = 0.5f;",
          "context": [
            {
              "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": 30,
          "match": "constexpr float LLR_FEEDBACK_MAX_MAG = 6.0f;",
          "context": [
            {
              "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": 31,
          "match": "constexpr int LDPC_FEEDBACK_MAX_PASSES_DEFAULT = 8;",
          "context": [
            {
              "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": 33,
          "match": "inline float llrErasureThreshold() {",
          "context": [
            {
              "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": 34,
          "match": "float threshold = LLR_ERASURE_THRESHOLD_DEFAULT;",
          "context": [
            {
              "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,
          "match": "if (auto const env = std::getenv(\"JS8_LLR_ERASURE_THRESH\"); env) {",
          "context": [
            {
              "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": 53,
          "match": "inline bool ldpcFeedbackEnabled() {",
          "context": [
            {
              "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": 55,
          "match": "int value = qEnvironmentVariableIntValue(\"JS8_LDPC_FEEDBACK\", &ok);",
          "context": [
            {
              "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,
          "match": "inline int ldpcFeedbackMaxPasses() {",
          "context": [
            {
              "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": 61,
          "match": "int value = qEnvironmentVariableIntValue(\"JS8_LDPC_MAX_PASSES\", &ok);",
          "context": [
            {
              "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": 64,
          "match": "return LDPC_FEEDBACK_MAX_PASSES_DEFAULT;",
          "context": [
            {
              "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,
          "match": "return std::clamp(value, 1, LDPC_FEEDBACK_MAX_PASSES_DEFAULT);",
          "context": [
            {
              "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 <std::size_t N>"
            }
          ]
        },
        {
          "line": 70,
          "match": "void refineLlrsWithLdpcFeedback(std::array<float, N> const &llrIn,",
          "context": [
            {
              "line": 67,
              "text": "}"
            },
            {
              "line": 68,
              "text": ""
            },
            {
              "line": 69,
              "text": "template <std::size_t N>"
            },
            {
              "line": 70,
              "text": "void refineLlrsWithLdpcFeedback(std::array<float, N> const &llrIn,"
            },
            {
              "line": 71,
              "text": "                                std::array<int8_t, N> const &cw,"
            },
            {
              "line": 72,
              "text": "                                float erasureThreshold,"
            },
            {
              "line": 73,
              "text": "                                std::array<float, N> &llrOut,"
            }
          ]
        },
        {
          "line": 73,
          "match": "std::array<float, N> &llrOut,",
          "context": [
            {
              "line": 70,
              "text": "void refineLlrsWithLdpcFeedback(std::array<float, N> const &llrIn,"
            },
            {
              "line": 71,
              "text": "                                std::array<int8_t, N> const &cw,"
            },
            {
              "line": 72,
              "text": "                                float erasureThreshold,"
            },
            {
              "line": 73,
              "text": "                                std::array<float, N> &llrOut,"
            },
            {
              "line": 74,
              "text": "                                int &confidentCount, int &uncertainCount) {"
            },
            {
              "line": 75,
              "text": "    llrOut = llrIn;"
            },
            {
              "line": 76,
              "text": "    confidentCount = 0;"
            }
          ]
        },
        {
          "line": 75,
          "match": "llrOut = llrIn;",
          "context": [
            {
              "line": 72,
              "text": "                                float erasureThreshold,"
            },
            {
              "line": 73,
              "text": "                                std::array<float, N> &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,
          "match": "for (std::size_t i = 0; i < llrOut.size(); ++i) {",
          "context": [
            {
              "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": 80,
          "match": "float &value = llrOut[i];",
          "context": [
            {
              "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": 88,
          "match": "bool const bitOne = cw[i] != 0;",
          "context": [
            {
              "line": 85,
              "text": "            continue;"
            },
            {
              "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": 90,
          "match": "bool const signMatch = (value >= 0.0f) == bitOne;",
          "context": [
            {
              "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;"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/DecodedText.h",
      "exists": true,
      "bytes": 2704,
      "lines": 90,
      "score": 86,
      "keyword_hits": {
        "decode": 15,
        "Decode": 15,
        "message": 6,
        "Message": 6,
        "pack": 12,
        "unpack": 12
      },
      "phase_scores": {
        "symbol_to_bits": 5,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 24,
        "timing_constants": 0
      },
      "candidate_functions": [
        {
          "line": 27,
          "name": "directedMessage",
          "signature": "QStringList directedMessage() const { return directed_; }"
        },
        {
          "line": 35,
          "name": "isDirectedMessage",
          "signature": "bool isDirectedMessage() const { return directed_.length() > 2; }"
        },
        {
          "line": 38,
          "name": "message",
          "signature": "QString message() const { return message_; }"
        }
      ],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 3,
          "match": "* Class to handle the formatted string as returned from the decoder",
          "context": [
            {
              "line": 1,
              "text": "// -*- Mode: C++ -*-"
            },
            {
              "line": 2,
              "text": "/*"
            },
            {
              "line": 3,
              "text": " * Class to handle the formatted string as returned from the decoder"
            },
            {
              "line": 4,
              "text": " *"
            },
            {
              "line": 5,
              "text": " * VK3ACF August 2013"
            },
            {
              "line": 6,
              "text": " */"
            }
          ]
        },
        {
          "line": 8,
          "match": "#ifndef DECODEDTEXT_H",
          "context": [
            {
              "line": 5,
              "text": " * VK3ACF August 2013"
            },
            {
              "line": 6,
              "text": " */"
            },
            {
              "line": 7,
              "text": ""
            },
            {
              "line": 8,
              "text": "#ifndef DECODEDTEXT_H"
            },
            {
              "line": 9,
              "text": "#define DECODEDTEXT_H"
            },
            {
              "line": 10,
              "text": ""
            },
            {
              "line": 11,
              "text": "#include \"JS8.h\""
            }
          ]
        },
        {
          "line": 9,
          "match": "#define DECODEDTEXT_H",
          "context": [
            {
              "line": 6,
              "text": " */"
            },
            {
              "line": 7,
              "text": ""
            },
            {
              "line": 8,
              "text": "#ifndef DECODEDTEXT_H"
            },
            {
              "line": 9,
              "text": "#define DECODEDTEXT_H"
            },
            {
              "line": 10,
              "text": ""
            },
            {
              "line": 11,
              "text": "#include \"JS8.h\""
            },
            {
              "line": 12,
              "text": ""
            }
          ]
        },
        {
          "line": 16,
          "match": "class DecodedText {",
          "context": [
            {
              "line": 13,
              "text": "#include <QString>"
            },
            {
              "line": 14,
              "text": "#include <QStringList>"
            },
            {
              "line": 15,
              "text": ""
            },
            {
              "line": 16,
              "text": "class DecodedText {"
            },
            {
              "line": 17,
              "text": "  public:"
            },
            {
              "line": 18,
              "text": "    // Constructors"
            },
            {
              "line": 19,
              "text": ""
            }
          ]
        },
        {
          "line": 20,
          "match": "explicit DecodedText(JS8::Event::Decoded const &);",
          "context": [
            {
              "line": 17,
              "text": "  public:"
            },
            {
              "line": 18,
              "text": "    // Constructors"
            },
            {
              "line": 19,
              "text": ""
            },
            {
              "line": 20,
              "text": "    explicit DecodedText(JS8::Event::Decoded const &);"
            },
            {
              "line": 21,
              "text": "    explicit DecodedText(QString const &frame, int bits, int submode);"
            },
            {
              "line": 22,
              "text": ""
            },
            {
              "line": 23,
              "text": "    // Inline accessors"
            }
          ]
        },
        {
          "line": 21,
          "match": "explicit DecodedText(QString const &frame, int bits, int submode);",
          "context": [
            {
              "line": 18,
              "text": "    // Constructors"
            },
            {
              "line": 19,
              "text": ""
            },
            {
              "line": 20,
              "text": "    explicit DecodedText(JS8::Event::Decoded const &);"
            },
            {
              "line": 21,
              "text": "    explicit DecodedText(QString const &frame, int bits, int submode);"
            },
            {
              "line": 22,
              "text": ""
            },
            {
              "line": 23,
              "text": "    // Inline accessors"
            },
            {
              "line": 24,
              "text": ""
            }
          ]
        },
        {
          "line": 27,
          "match": "QStringList directedMessage() const { return directed_; }",
          "context": [
            {
              "line": 24,
              "text": ""
            },
            {
              "line": 25,
              "text": "    int bits() const { return bits_; }"
            },
            {
              "line": 26,
              "text": "    QString compoundCall() const { return compound_; }"
            },
            {
              "line": 27,
              "text": "    QStringList directedMessage() const { return directed_; }"
            },
            {
              "line": 28,
              "text": "    float dt() const { return dt_; }"
            },
            {
              "line": 29,
              "text": "    QString extra() const { return extra_; }"
            },
            {
              "line": 30,
              "text": "    QString frame() const { return frame_; }"
            }
          ]
        },
        {
          "line": 35,
          "match": "bool isDirectedMessage() const { return directed_.length() > 2; }",
          "context": [
            {
              "line": 32,
              "text": "    int frequencyOffset() const { return frequencyOffset_; }"
            },
            {
              "line": 33,
              "text": "    bool isAlt() const { return isAlt_; }"
            },
            {
              "line": 34,
              "text": "    bool isCompound() const { return !compound_.isEmpty(); }"
            },
            {
              "line": 35,
              "text": "    bool isDirectedMessage() const { return directed_.length() > 2; }"
            },
            {
              "line": 36,
              "text": "    bool isHeartbeat() const { return isHeartbeat_; }"
            },
            {
              "line": 37,
              "text": "    bool isLowConfidence() const { return isLowConfidence_; }"
            },
            {
              "line": 38,
              "text": "    QString message() const { return message_; }"
            }
          ]
        },
        {
          "line": 38,
          "match": "QString message() const { return message_; }",
          "context": [
            {
              "line": 35,
              "text": "    bool isDirectedMessage() const { return directed_.length() > 2; }"
            },
            {
              "line": 36,
              "text": "    bool isHeartbeat() const { return isHeartbeat_; }"
            },
            {
              "line": 37,
              "text": "    bool isLowConfidence() const { return isLowConfidence_; }"
            },
            {
              "line": 38,
              "text": "    QString message() const { return message_; }"
            },
            {
              "line": 39,
              "text": "    int snr() const { return snr_; }"
            },
            {
              "line": 40,
              "text": "    int submode() const { return submode_; }"
            },
            {
              "line": 41,
              "text": "    // You can use decode_time() from commons.h to split up this integer:"
            }
          ]
        },
        {
          "line": 41,
          "match": "// You can use decode_time() from commons.h to split up this integer:",
          "context": [
            {
              "line": 38,
              "text": "    QString message() const { return message_; }"
            },
            {
              "line": 39,
              "text": "    int snr() const { return snr_; }"
            },
            {
              "line": 40,
              "text": "    int submode() const { return submode_; }"
            },
            {
              "line": 41,
              "text": "    // You can use decode_time() from commons.h to split up this integer:"
            },
            {
              "line": 42,
              "text": "    int time() const { return time_; }"
            },
            {
              "line": 43,
              "text": ""
            },
            {
              "line": 44,
              "text": "    // Accessors"
            }
          ]
        },
        {
          "line": 46,
          "match": "QStringList messageWords() const;",
          "context": [
            {
              "line": 43,
              "text": ""
            },
            {
              "line": 44,
              "text": "    // Accessors"
            },
            {
              "line": 45,
              "text": ""
            },
            {
              "line": 46,
              "text": "    QStringList messageWords() const;"
            },
            {
              "line": 47,
              "text": "    QString string() const;"
            },
            {
              "line": 48,
              "text": ""
            },
            {
              "line": 49,
              "text": "  private:"
            }
          ]
        },
        {
          "line": 50,
          "match": "// Unpacking strategies, attempted in order until one of them",
          "context": [
            {
              "line": 47,
              "text": "    QString string() const;"
            },
            {
              "line": 48,
              "text": ""
            },
            {
              "line": 49,
              "text": "  private:"
            },
            {
              "line": 50,
              "text": "    // Unpacking strategies, attempted in order until one of them"
            },
            {
              "line": 51,
              "text": "    // works or all of them have failed."
            },
            {
              "line": 52,
              "text": ""
            },
            {
              "line": 53,
              "text": "    bool tryUnpackFastData(QString const &);"
            }
          ]
        },
        {
          "line": 53,
          "match": "bool tryUnpackFastData(QString const &);",
          "context": [
            {
              "line": 50,
              "text": "    // Unpacking strategies, attempted in order until one of them"
            },
            {
              "line": 51,
              "text": "    // works or all of them have failed."
            },
            {
              "line": 52,
              "text": ""
            },
            {
              "line": 53,
              "text": "    bool tryUnpackFastData(QString const &);"
            },
            {
              "line": 54,
              "text": "    bool tryUnpackData(QString const &);"
            },
            {
              "line": 55,
              "text": "    bool tryUnpackHeartbeat(QString const &);"
            },
            {
              "line": 56,
              "text": "    bool tryUnpackCompound(QString const &);"
            }
          ]
        },
        {
          "line": 54,
          "match": "bool tryUnpackData(QString const &);",
          "context": [
            {
              "line": 51,
              "text": "    // works or all of them have failed."
            },
            {
              "line": 52,
              "text": ""
            },
            {
              "line": 53,
              "text": "    bool tryUnpackFastData(QString const &);"
            },
            {
              "line": 54,
              "text": "    bool tryUnpackData(QString const &);"
            },
            {
              "line": 55,
              "text": "    bool tryUnpackHeartbeat(QString const &);"
            },
            {
              "line": 56,
              "text": "    bool tryUnpackCompound(QString const &);"
            },
            {
              "line": 57,
              "text": "    bool tryUnpackDirected(QString const &);"
            }
          ]
        },
        {
          "line": 55,
          "match": "bool tryUnpackHeartbeat(QString const &);",
          "context": [
            {
              "line": 52,
              "text": ""
            },
            {
              "line": 53,
              "text": "    bool tryUnpackFastData(QString const &);"
            },
            {
              "line": 54,
              "text": "    bool tryUnpackData(QString const &);"
            },
            {
              "line": 55,
              "text": "    bool tryUnpackHeartbeat(QString const &);"
            },
            {
              "line": 56,
              "text": "    bool tryUnpackCompound(QString const &);"
            },
            {
              "line": 57,
              "text": "    bool tryUnpackDirected(QString const &);"
            },
            {
              "line": 58,
              "text": ""
            }
          ]
        },
        {
          "line": 56,
          "match": "bool tryUnpackCompound(QString const &);",
          "context": [
            {
              "line": 53,
              "text": "    bool tryUnpackFastData(QString const &);"
            },
            {
              "line": 54,
              "text": "    bool tryUnpackData(QString const &);"
            },
            {
              "line": 55,
              "text": "    bool tryUnpackHeartbeat(QString const &);"
            },
            {
              "line": 56,
              "text": "    bool tryUnpackCompound(QString const &);"
            },
            {
              "line": 57,
              "text": "    bool tryUnpackDirected(QString const &);"
            },
            {
              "line": 58,
              "text": ""
            },
            {
              "line": 59,
              "text": "    static constexpr std::array unpackStrategies = {"
            }
          ]
        },
        {
          "line": 57,
          "match": "bool tryUnpackDirected(QString const &);",
          "context": [
            {
              "line": 54,
              "text": "    bool tryUnpackData(QString const &);"
            },
            {
              "line": 55,
              "text": "    bool tryUnpackHeartbeat(QString const &);"
            },
            {
              "line": 56,
              "text": "    bool tryUnpackCompound(QString const &);"
            },
            {
              "line": 57,
              "text": "    bool tryUnpackDirected(QString const &);"
            },
            {
              "line": 58,
              "text": ""
            },
            {
              "line": 59,
              "text": "    static constexpr std::array unpackStrategies = {"
            },
            {
              "line": 60,
              "text": "        &DecodedText::tryUnpackFastData, &DecodedText::tryUnpackData,"
            }
          ]
        },
        {
          "line": 59,
          "match": "static constexpr std::array unpackStrategies = {",
          "context": [
            {
              "line": 56,
              "text": "    bool tryUnpackCompound(QString const &);"
            },
            {
              "line": 57,
              "text": "    bool tryUnpackDirected(QString const &);"
            },
            {
              "line": 58,
              "text": ""
            },
            {
              "line": 59,
              "text": "    static constexpr std::array unpackStrategies = {"
            },
            {
              "line": 60,
              "text": "        &DecodedText::tryUnpackFastData, &DecodedText::tryUnpackData,"
            },
            {
              "line": 61,
              "text": "        &DecodedText::tryUnpackHeartbeat, &DecodedText::tryUnpackCompound,"
            },
            {
              "line": 62,
              "text": "        &DecodedText::tryUnpackDirected};"
            }
          ]
        },
        {
          "line": 60,
          "match": "&DecodedText::tryUnpackFastData, &DecodedText::tryUnpackData,",
          "context": [
            {
              "line": 57,
              "text": "    bool tryUnpackDirected(QString const &);"
            },
            {
              "line": 58,
              "text": ""
            },
            {
              "line": 59,
              "text": "    static constexpr std::array unpackStrategies = {"
            },
            {
              "line": 60,
              "text": "        &DecodedText::tryUnpackFastData, &DecodedText::tryUnpackData,"
            },
            {
              "line": 61,
              "text": "        &DecodedText::tryUnpackHeartbeat, &DecodedText::tryUnpackCompound,"
            },
            {
              "line": 62,
              "text": "        &DecodedText::tryUnpackDirected};"
            },
            {
              "line": 63,
              "text": ""
            }
          ]
        },
        {
          "line": 61,
          "match": "&DecodedText::tryUnpackHeartbeat, &DecodedText::tryUnpackCompound,",
          "context": [
            {
              "line": 58,
              "text": ""
            },
            {
              "line": 59,
              "text": "    static constexpr std::array unpackStrategies = {"
            },
            {
              "line": 60,
              "text": "        &DecodedText::tryUnpackFastData, &DecodedText::tryUnpackData,"
            },
            {
              "line": 61,
              "text": "        &DecodedText::tryUnpackHeartbeat, &DecodedText::tryUnpackCompound,"
            },
            {
              "line": 62,
              "text": "        &DecodedText::tryUnpackDirected};"
            },
            {
              "line": 63,
              "text": ""
            },
            {
              "line": 64,
              "text": "    // Core constructor; delegated to by the public constructors."
            }
          ]
        },
        {
          "line": 62,
          "match": "&DecodedText::tryUnpackDirected};",
          "context": [
            {
              "line": 59,
              "text": "    static constexpr std::array unpackStrategies = {"
            },
            {
              "line": 60,
              "text": "        &DecodedText::tryUnpackFastData, &DecodedText::tryUnpackData,"
            },
            {
              "line": 61,
              "text": "        &DecodedText::tryUnpackHeartbeat, &DecodedText::tryUnpackCompound,"
            },
            {
              "line": 62,
              "text": "        &DecodedText::tryUnpackDirected};"
            },
            {
              "line": 63,
              "text": ""
            },
            {
              "line": 64,
              "text": "    // Core constructor; delegated to by the public constructors."
            },
            {
              "line": 65,
              "text": ""
            }
          ]
        },
        {
          "line": 66,
          "match": "DecodedText(QString const &frame, int bits, int submode,",
          "context": [
            {
              "line": 63,
              "text": ""
            },
            {
              "line": 64,
              "text": "    // Core constructor; delegated to by the public constructors."
            },
            {
              "line": 65,
              "text": ""
            },
            {
              "line": 66,
              "text": "    DecodedText(QString const &frame, int bits, int submode,"
            },
            {
              "line": 67,
              "text": "                bool isLowConfidence,"
            },
            {
              "line": 68,
              "text": "                int time, // As generated by code_time() in commons.h."
            },
            {
              "line": 69,
              "text": "                int frequencyOffset, float snr, float dt);"
            }
          ]
        },
        {
          "line": 81,
          "match": "QString message_;",
          "context": [
            {
              "line": 78,
              "text": "    QString compound_;"
            },
            {
              "line": 79,
              "text": "    QStringList directed_;"
            },
            {
              "line": 80,
              "text": "    QString extra_;"
            },
            {
              "line": 81,
              "text": "    QString message_;"
            },
            {
              "line": 82,
              "text": "    int bits_;"
            },
            {
              "line": 83,
              "text": "    int submode_;"
            },
            {
              "line": 84,
              "text": "    int time_;"
            }
          ]
        },
        {
          "line": 90,
          "match": "#endif // DECODEDTEXT_H",
          "context": [
            {
              "line": 87,
              "text": "    float dt_;"
            },
            {
              "line": 88,
              "text": "};"
            },
            {
              "line": 89,
              "text": ""
            },
            {
              "line": 90,
              "text": "#endif // DECODEDTEXT_H"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/Decoder.cpp",
      "exists": true,
      "bytes": 3646,
      "lines": 139,
      "score": 79,
      "keyword_hits": {
        "decode": 32,
        "Decode": 32
      },
      "phase_scores": {
        "symbol_to_bits": 0,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 0,
        "timing_constants": 0
      },
      "candidate_functions": [
        {
          "line": 24,
          "name": "Decoder::lock",
          "signature": "void Decoder::lock() {"
        },
        {
          "line": 29,
          "name": "Decoder::unlock",
          "signature": "void Decoder::unlock() {"
        },
        {
          "line": 47,
          "name": "Decoder::start",
          "signature": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }"
        },
        {
          "line": 50,
          "name": "Decoder::quit",
          "signature": "void Decoder::quit() { m_thread.quit(); }"
        },
        {
          "line": 53,
          "name": "Decoder::wait",
          "signature": "bool Decoder::wait() { return m_thread.wait(); }"
        },
        {
          "line": 56,
          "name": "Decoder::processStart",
          "signature": "void Decoder::processStart(QString path, QStringList args) {"
        },
        {
          "line": 65,
          "name": "Decoder::processReady",
          "signature": "void Decoder::processReady(QByteArray t) { emit ready(t); }"
        },
        {
          "line": 68,
          "name": "Decoder::processQuit",
          "signature": "void Decoder::processQuit() { emit quitWorker(); }"
        },
        {
          "line": 71,
          "name": "Decoder::processError",
          "signature": "void Decoder::processError(int errorCode, QString errorString) {"
        }
      ],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 2,
          "match": "* @file Decoder.cpp",
          "context": [
            {
              "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 <kn4crd@gmail.com> - All Rights Reserved"
            },
            {
              "line": 5,
              "text": " */"
            }
          ]
        },
        {
          "line": 3,
          "match": "* @brief Implementation of the JS8 decoder and worker classes",
          "context": [
            {
              "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 <kn4crd@gmail.com> - All Rights Reserved"
            },
            {
              "line": 5,
              "text": " */"
            },
            {
              "line": 6,
              "text": ""
            }
          ]
        },
        {
          "line": 7,
          "match": "#include \"Decoder.h\"",
          "context": [
            {
              "line": 4,
              "text": " * (C) 2019 Jordan Sherer <kn4crd@gmail.com> - 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 <QLoggingCategory>"
            }
          ]
        },
        {
          "line": 13,
          "match": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8)",
          "context": [
            {
              "line": 10,
              "text": "#include <QLoggingCategory>"
            },
            {
              "line": 11,
              "text": "#include <QTimer>"
            },
            {
              "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": 18,
          "match": "Decoder::Decoder(QObject * parent)",
          "context": [
            {
              "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": 21,
          "match": "Decoder::~Decoder() {}",
          "context": [
            {
              "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": 24,
          "match": "void Decoder::lock() {",
          "context": [
            {
              "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,
          "match": "void Decoder::unlock() {",
          "context": [
            {
              "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": 34,
          "match": "Worker *Decoder::createWorker() {",
          "context": [
            {
              "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,
          "match": "connect(this, &Decoder::startWorker, worker, &Worker::start);",
          "context": [
            {
              "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": 39,
          "match": "connect(this, &Decoder::quitWorker, worker, &Worker::quit);",
          "context": [
            {
              "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": 40,
          "match": "connect(worker, &Worker::ready, this, &Decoder::processReady);",
          "context": [
            {
              "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": 41,
          "match": "connect(worker, &Worker::error, this, &Decoder::processError);",
          "context": [
            {
              "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": 42,
          "match": "connect(worker, &Worker::finished, this, &Decoder::processFinished);",
          "context": [
            {
              "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": 47,
          "match": "void Decoder::start(QThread::Priority priority) { m_thread.start(priority); }",
          "context": [
            {
              "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": 50,
          "match": "void Decoder::quit() { m_thread.quit(); }",
          "context": [
            {
              "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,
          "match": "bool Decoder::wait() { return m_thread.wait(); }",
          "context": [
            {
              "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": 56,
          "match": "void Decoder::processStart(QString path, QStringList args) {",
          "context": [
            {
              "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": 65,
          "match": "void Decoder::processReady(QByteArray t) { emit ready(t); }",
          "context": [
            {
              "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": 68,
          "match": "void Decoder::processQuit() { emit quitWorker(); }",
          "context": [
            {
              "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": 71,
          "match": "void Decoder::processError(int errorCode, QString errorString) {",
          "context": [
            {
              "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": 72,
          "match": "qCDebug(decoder_js8) << \"decoder process error\" << errorCode << errorString;",
          "context": [
            {
              "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": 77,
          "match": "void Decoder::processFinished(int exitCode, int statusCode,",
          "context": [
            {
              "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": 79,
          "match": "qCDebug(decoder_js8) << \"decoder process finished\" << exitCode << statusCode",
          "context": [
            {
              "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": 107,
          "match": "qCDebug(decoder_js8) << \"decoder process starting...\";",
          "context": [
            {
              "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": 139,
          "match": "Q_LOGGING_CATEGORY(decoder_js8, \"decoder.js8\", QtWarningMsg)",
          "context": [
            {
              "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_Include/commons.h",
      "exists": true,
      "bytes": 3525,
      "lines": 106,
      "score": 66,
      "keyword_hits": {
        "decode": 18,
        "Decode": 18,
        "symbol": 6,
        "candidates": 1,
        "JS8_NSPS": 1,
        "JS8_RX_SAMPLE_RATE": 2
      },
      "phase_scores": {
        "symbol_to_bits": 6,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 0,
        "timing_constants": 3
      },
      "candidate_functions": [
        {
          "line": 98,
          "name": "decode_time",
          "signature": "inline hour_minute_second decode_time(int nutc){"
        }
      ],
      "candidate_arrays": [],
      "candidate_defines": [
        {
          "line": 11,
          "name": "JS8_NSPS",
          "value": "6192"
        },
        {
          "line": 12,
          "name": "JS8_NSMAX",
          "value": "6827"
        },
        {
          "line": 13,
          "name": "JS8_NTMAX",
          "value": "60"
        },
        {
          "line": 14,
          "name": "JS8_RX_SAMPLE_RATE",
          "value": "12000"
        },
        {
          "line": 15,
          "name": "JS8_RX_SAMPLE_SIZE",
          "value": "(JS8_NTMAX * JS8_RX_SAMPLE_RATE)"
        },
        {
          "line": 17,
          "name": "JS8_RING_BUFFER",
          "value": "1"
        },
        {
          "line": 18,
          "name": "JS8_DECODE_THREAD",
          "value": "1"
        },
        {
          "line": 19,
          "name": "JS8_ALLOW_EXTENDED",
          "value": "1"
        },
        {
          "line": 20,
          "name": "JS8_AUTO_SYNC",
          "value": "1"
        },
        {
          "line": 22,
          "name": "JS8_NUM_SYMBOLS",
          "value": "79"
        },
        {
          "line": 23,
          "name": "JS8_ENABLE_JS8A",
          "value": "1"
        },
        {
          "line": 24,
          "name": "JS8_ENABLE_JS8B",
          "value": "1"
        },
        {
          "line": 25,
          "name": "JS8_ENABLE_JS8C",
          "value": "1"
        },
        {
          "line": 26,
          "name": "JS8_ENABLE_JS8E",
          "value": "1"
        },
        {
          "line": 27,
          "name": "JS8_ENABLE_JS8I",
          "value": "1"
        },
        {
          "line": 29,
          "name": "JS8A_SYMBOL_SAMPLES",
          "value": "1920"
        },
        {
          "line": 30,
          "name": "JS8A_TX_SECONDS",
          "value": "15"
        },
        {
          "line": 31,
          "name": "JS8A_START_DELAY_MS",
          "value": "500"
        },
        {
          "line": 33,
          "name": "JS8B_SYMBOL_SAMPLES",
          "value": "1200"
        },
        {
          "line": 34,
          "name": "JS8B_TX_SECONDS",
          "value": "10"
        },
        {
          "line": 35,
          "name": "JS8B_START_DELAY_MS",
          "value": "200"
        },
        {
          "line": 37,
          "name": "JS8C_SYMBOL_SAMPLES",
          "value": "600"
        },
        {
          "line": 38,
          "name": "JS8C_TX_SECONDS",
          "value": "6"
        },
        {
          "line": 39,
          "name": "JS8C_START_DELAY_MS",
          "value": "100"
        },
        {
          "line": 41,
          "name": "JS8E_SYMBOL_SAMPLES",
          "value": "3840"
        },
        {
          "line": 42,
          "name": "JS8E_TX_SECONDS",
          "value": "30"
        },
        {
          "line": 43,
          "name": "JS8E_START_DELAY_MS",
          "value": "500"
        },
        {
          "line": 45,
          "name": "JS8I_SYMBOL_SAMPLES",
          "value": "384"
        },
        {
          "line": 46,
          "name": "JS8I_TX_SECONDS",
          "value": "4"
        },
        {
          "line": 47,
          "name": "JS8I_START_DELAY_MS",
          "value": "100"
        }
      ],
      "snippets": [
        {
          "line": 11,
          "match": "#define JS8_NSPS           6192",
          "context": [
            {
              "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": 14,
          "match": "#define JS8_RX_SAMPLE_RATE 12000",
          "context": [
            {
              "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"
            }
          ]
        },
        {
          "line": 15,
          "match": "#define JS8_RX_SAMPLE_SIZE (JS8_NTMAX * JS8_RX_SAMPLE_RATE)",
          "context": [
            {
              "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"
            },
            {
              "line": 18,
              "text": "#define JS8_DECODE_THREAD  1       // use a separate thread for decode process handling"
            }
          ]
        },
        {
          "line": 17,
          "match": "#define JS8_RING_BUFFER    1       // use a ring buffer instead of clearing the decode frames",
          "context": [
            {
              "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"
            },
            {
              "line": 18,
              "text": "#define JS8_DECODE_THREAD  1       // use a separate thread for decode process handling"
            },
            {
              "line": 19,
              "text": "#define JS8_ALLOW_EXTENDED 1       // allow extended latin-1 capital charset"
            },
            {
              "line": 20,
              "text": "#define JS8_AUTO_SYNC      1       // enable the experimental auto sync feature"
            }
          ]
        },
        {
          "line": 18,
          "match": "#define JS8_DECODE_THREAD  1       // use a separate thread for decode process handling",
          "context": [
            {
              "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"
            },
            {
              "line": 18,
              "text": "#define JS8_DECODE_THREAD  1       // use a separate thread for decode process handling"
            },
            {
              "line": 19,
              "text": "#define JS8_ALLOW_EXTENDED 1       // allow extended latin-1 capital charset"
            },
            {
              "line": 20,
              "text": "#define JS8_AUTO_SYNC      1       // enable the experimental auto sync feature"
            },
            {
              "line": 21,
              "text": ""
            }
          ]
        },
        {
          "line": 22,
          "match": "#define JS8_NUM_SYMBOLS    79",
          "context": [
            {
              "line": 19,
              "text": "#define JS8_ALLOW_EXTENDED 1       // allow extended latin-1 capital charset"
            },
            {
              "line": 20,
              "text": "#define JS8_AUTO_SYNC      1       // enable the experimental auto sync feature"
            },
            {
              "line": 21,
              "text": ""
            },
            {
              "line": 22,
              "text": "#define JS8_NUM_SYMBOLS    79"
            },
            {
              "line": 23,
              "text": "#define JS8_ENABLE_JS8A    1"
            },
            {
              "line": 24,
              "text": "#define JS8_ENABLE_JS8B    1"
            },
            {
              "line": 25,
              "text": "#define JS8_ENABLE_JS8C    1"
            }
          ]
        },
        {
          "line": 29,
          "match": "#define JS8A_SYMBOL_SAMPLES 1920",
          "context": [
            {
              "line": 26,
              "text": "#define JS8_ENABLE_JS8E    1"
            },
            {
              "line": 27,
              "text": "#define JS8_ENABLE_JS8I    1"
            },
            {
              "line": 28,
              "text": ""
            },
            {
              "line": 29,
              "text": "#define JS8A_SYMBOL_SAMPLES 1920"
            },
            {
              "line": 30,
              "text": "#define JS8A_TX_SECONDS     15"
            },
            {
              "line": 31,
              "text": "#define JS8A_START_DELAY_MS 500"
            },
            {
              "line": 32,
              "text": ""
            }
          ]
        },
        {
          "line": 33,
          "match": "#define JS8B_SYMBOL_SAMPLES 1200",
          "context": [
            {
              "line": 30,
              "text": "#define JS8A_TX_SECONDS     15"
            },
            {
              "line": 31,
              "text": "#define JS8A_START_DELAY_MS 500"
            },
            {
              "line": 32,
              "text": ""
            },
            {
              "line": 33,
              "text": "#define JS8B_SYMBOL_SAMPLES 1200"
            },
            {
              "line": 34,
              "text": "#define JS8B_TX_SECONDS     10"
            },
            {
              "line": 35,
              "text": "#define JS8B_START_DELAY_MS 200"
            },
            {
              "line": 36,
              "text": ""
            }
          ]
        },
        {
          "line": 37,
          "match": "#define JS8C_SYMBOL_SAMPLES 600",
          "context": [
            {
              "line": 34,
              "text": "#define JS8B_TX_SECONDS     10"
            },
            {
              "line": 35,
              "text": "#define JS8B_START_DELAY_MS 200"
            },
            {
              "line": 36,
              "text": ""
            },
            {
              "line": 37,
              "text": "#define JS8C_SYMBOL_SAMPLES 600"
            },
            {
              "line": 38,
              "text": "#define JS8C_TX_SECONDS     6"
            },
            {
              "line": 39,
              "text": "#define JS8C_START_DELAY_MS 100"
            },
            {
              "line": 40,
              "text": ""
            }
          ]
        },
        {
          "line": 41,
          "match": "#define JS8E_SYMBOL_SAMPLES 3840",
          "context": [
            {
              "line": 38,
              "text": "#define JS8C_TX_SECONDS     6"
            },
            {
              "line": 39,
              "text": "#define JS8C_START_DELAY_MS 100"
            },
            {
              "line": 40,
              "text": ""
            },
            {
              "line": 41,
              "text": "#define JS8E_SYMBOL_SAMPLES 3840"
            },
            {
              "line": 42,
              "text": "#define JS8E_TX_SECONDS     30"
            },
            {
              "line": 43,
              "text": "#define JS8E_START_DELAY_MS 500"
            },
            {
              "line": 44,
              "text": ""
            }
          ]
        },
        {
          "line": 45,
          "match": "#define JS8I_SYMBOL_SAMPLES 384",
          "context": [
            {
              "line": 42,
              "text": "#define JS8E_TX_SECONDS     30"
            },
            {
              "line": 43,
              "text": "#define JS8E_START_DELAY_MS 500"
            },
            {
              "line": 44,
              "text": ""
            },
            {
              "line": 45,
              "text": "#define JS8I_SYMBOL_SAMPLES 384"
            },
            {
              "line": 46,
              "text": "#define JS8I_TX_SECONDS     4"
            },
            {
              "line": 47,
              "text": "#define JS8I_START_DELAY_MS 100"
            },
            {
              "line": 48,
              "text": ""
            }
          ]
        },
        {
          "line": 57,
          "match": "int nfa;                    // Low decode limit (Hz) (filter min)",
          "context": [
            {
              "line": 54,
              "text": "    int nutc;                   // UTC as integer. See code_time() below for details."
            },
            {
              "line": 55,
              "text": "    int nfqso;                  // User-selected QSO freq (kHz)"
            },
            {
              "line": 56,
              "text": "    bool newdat;                // true ==> new data, must do long FFT"
            },
            {
              "line": 57,
              "text": "    int nfa;                    // Low decode limit (Hz) (filter min)"
            },
            {
              "line": 58,
              "text": "    int nfb;                    // High decode limit (Hz) (filter max)"
            },
            {
              "line": 59,
              "text": "    bool syncStats;             // only compute sync candidates"
            },
            {
              "line": 60,
              "text": "    int kin;                    // number of frames written to d2"
            }
          ]
        },
        {
          "line": 58,
          "match": "int nfb;                    // High decode limit (Hz) (filter max)",
          "context": [
            {
              "line": 55,
              "text": "    int nfqso;                  // User-selected QSO freq (kHz)"
            },
            {
              "line": 56,
              "text": "    bool newdat;                // true ==> new data, must do long FFT"
            },
            {
              "line": 57,
              "text": "    int nfa;                    // Low decode limit (Hz) (filter min)"
            },
            {
              "line": 58,
              "text": "    int nfb;                    // High decode limit (Hz) (filter max)"
            },
            {
              "line": 59,
              "text": "    bool syncStats;             // only compute sync candidates"
            },
            {
              "line": 60,
              "text": "    int kin;                    // number of frames written to d2"
            },
            {
              "line": 61,
              "text": "    int kposA;                  // starting position of decode for submode A"
            }
          ]
        },
        {
          "line": 59,
          "match": "bool syncStats;             // only compute sync candidates",
          "context": [
            {
              "line": 56,
              "text": "    bool newdat;                // true ==> new data, must do long FFT"
            },
            {
              "line": 57,
              "text": "    int nfa;                    // Low decode limit (Hz) (filter min)"
            },
            {
              "line": 58,
              "text": "    int nfb;                    // High decode limit (Hz) (filter max)"
            },
            {
              "line": 59,
              "text": "    bool syncStats;             // only compute sync candidates"
            },
            {
              "line": 60,
              "text": "    int kin;                    // number of frames written to d2"
            },
            {
              "line": 61,
              "text": "    int kposA;                  // starting position of decode for submode A"
            },
            {
              "line": 62,
              "text": "    int kposB;                  // starting position of decode for submode B"
            }
          ]
        },
        {
          "line": 61,
          "match": "int kposA;                  // starting position of decode for submode A",
          "context": [
            {
              "line": 58,
              "text": "    int nfb;                    // High decode limit (Hz) (filter max)"
            },
            {
              "line": 59,
              "text": "    bool syncStats;             // only compute sync candidates"
            },
            {
              "line": 60,
              "text": "    int kin;                    // number of frames written to d2"
            },
            {
              "line": 61,
              "text": "    int kposA;                  // starting position of decode for submode A"
            },
            {
              "line": 62,
              "text": "    int kposB;                  // starting position of decode for submode B"
            },
            {
              "line": 63,
              "text": "    int kposC;                  // starting position of decode for submode C"
            },
            {
              "line": 64,
              "text": "    int kposE;                  // starting position of decode for submode E"
            }
          ]
        },
        {
          "line": 62,
          "match": "int kposB;                  // starting position of decode for submode B",
          "context": [
            {
              "line": 59,
              "text": "    bool syncStats;             // only compute sync candidates"
            },
            {
              "line": 60,
              "text": "    int kin;                    // number of frames written to d2"
            },
            {
              "line": 61,
              "text": "    int kposA;                  // starting position of decode for submode A"
            },
            {
              "line": 62,
              "text": "    int kposB;                  // starting position of decode for submode B"
            },
            {
              "line": 63,
              "text": "    int kposC;                  // starting position of decode for submode C"
            },
            {
              "line": 64,
              "text": "    int kposE;                  // starting position of decode for submode E"
            },
            {
              "line": 65,
              "text": "    int kposI;                  // starting position of decode for submode I"
            }
          ]
        },
        {
          "line": 63,
          "match": "int kposC;                  // starting position of decode for submode C",
          "context": [
            {
              "line": 60,
              "text": "    int kin;                    // number of frames written to d2"
            },
            {
              "line": 61,
              "text": "    int kposA;                  // starting position of decode for submode A"
            },
            {
              "line": 62,
              "text": "    int kposB;                  // starting position of decode for submode B"
            },
            {
              "line": 63,
              "text": "    int kposC;                  // starting position of decode for submode C"
            },
            {
              "line": 64,
              "text": "    int kposE;                  // starting position of decode for submode E"
            },
            {
              "line": 65,
              "text": "    int kposI;                  // starting position of decode for submode I"
            },
            {
              "line": 66,
              "text": "    int kszA;                   // number of frames for decode for submode A"
            }
          ]
        },
        {
          "line": 64,
          "match": "int kposE;                  // starting position of decode for submode E",
          "context": [
            {
              "line": 61,
              "text": "    int kposA;                  // starting position of decode for submode A"
            },
            {
              "line": 62,
              "text": "    int kposB;                  // starting position of decode for submode B"
            },
            {
              "line": 63,
              "text": "    int kposC;                  // starting position of decode for submode C"
            },
            {
              "line": 64,
              "text": "    int kposE;                  // starting position of decode for submode E"
            },
            {
              "line": 65,
              "text": "    int kposI;                  // starting position of decode for submode I"
            },
            {
              "line": 66,
              "text": "    int kszA;                   // number of frames for decode for submode A"
            },
            {
              "line": 67,
              "text": "    int kszB;                   // number of frames for decode for submode B"
            }
          ]
        },
        {
          "line": 65,
          "match": "int kposI;                  // starting position of decode for submode I",
          "context": [
            {
              "line": 62,
              "text": "    int kposB;                  // starting position of decode for submode B"
            },
            {
              "line": 63,
              "text": "    int kposC;                  // starting position of decode for submode C"
            },
            {
              "line": 64,
              "text": "    int kposE;                  // starting position of decode for submode E"
            },
            {
              "line": 65,
              "text": "    int kposI;                  // starting position of decode for submode I"
            },
            {
              "line": 66,
              "text": "    int kszA;                   // number of frames for decode for submode A"
            },
            {
              "line": 67,
              "text": "    int kszB;                   // number of frames for decode for submode B"
            },
            {
              "line": 68,
              "text": "    int kszC;                   // number of frames for decode for submode C"
            }
          ]
        },
        {
          "line": 66,
          "match": "int kszA;                   // number of frames for decode for submode A",
          "context": [
            {
              "line": 63,
              "text": "    int kposC;                  // starting position of decode for submode C"
            },
            {
              "line": 64,
              "text": "    int kposE;                  // starting position of decode for submode E"
            },
            {
              "line": 65,
              "text": "    int kposI;                  // starting position of decode for submode I"
            },
            {
              "line": 66,
              "text": "    int kszA;                   // number of frames for decode for submode A"
            },
            {
              "line": 67,
              "text": "    int kszB;                   // number of frames for decode for submode B"
            },
            {
              "line": 68,
              "text": "    int kszC;                   // number of frames for decode for submode C"
            },
            {
              "line": 69,
              "text": "    int kszE;                   // number of frames for decode for submode E"
            }
          ]
        },
        {
          "line": 67,
          "match": "int kszB;                   // number of frames for decode for submode B",
          "context": [
            {
              "line": 64,
              "text": "    int kposE;                  // starting position of decode for submode E"
            },
            {
              "line": 65,
              "text": "    int kposI;                  // starting position of decode for submode I"
            },
            {
              "line": 66,
              "text": "    int kszA;                   // number of frames for decode for submode A"
            },
            {
              "line": 67,
              "text": "    int kszB;                   // number of frames for decode for submode B"
            },
            {
              "line": 68,
              "text": "    int kszC;                   // number of frames for decode for submode C"
            },
            {
              "line": 69,
              "text": "    int kszE;                   // number of frames for decode for submode E"
            },
            {
              "line": 70,
              "text": "    int kszI;                   // number of frames for decode for submode I"
            }
          ]
        },
        {
          "line": 68,
          "match": "int kszC;                   // number of frames for decode for submode C",
          "context": [
            {
              "line": 65,
              "text": "    int kposI;                  // starting position of decode for submode I"
            },
            {
              "line": 66,
              "text": "    int kszA;                   // number of frames for decode for submode A"
            },
            {
              "line": 67,
              "text": "    int kszB;                   // number of frames for decode for submode B"
            },
            {
              "line": 68,
              "text": "    int kszC;                   // number of frames for decode for submode C"
            },
            {
              "line": 69,
              "text": "    int kszE;                   // number of frames for decode for submode E"
            },
            {
              "line": 70,
              "text": "    int kszI;                   // number of frames for decode for submode I"
            },
            {
              "line": 71,
              "text": "    int nsubmodes;              // which submodes to decode"
            }
          ]
        },
        {
          "line": 69,
          "match": "int kszE;                   // number of frames for decode for submode E",
          "context": [
            {
              "line": 66,
              "text": "    int kszA;                   // number of frames for decode for submode A"
            },
            {
              "line": 67,
              "text": "    int kszB;                   // number of frames for decode for submode B"
            },
            {
              "line": 68,
              "text": "    int kszC;                   // number of frames for decode for submode C"
            },
            {
              "line": 69,
              "text": "    int kszE;                   // number of frames for decode for submode E"
            },
            {
              "line": 70,
              "text": "    int kszI;                   // number of frames for decode for submode I"
            },
            {
              "line": 71,
              "text": "    int nsubmodes;              // which submodes to decode"
            },
            {
              "line": 72,
              "text": "  } params;"
            }
          ]
        },
        {
          "line": 70,
          "match": "int kszI;                   // number of frames for decode for submode I",
          "context": [
            {
              "line": 67,
              "text": "    int kszB;                   // number of frames for decode for submode B"
            },
            {
              "line": 68,
              "text": "    int kszC;                   // number of frames for decode for submode C"
            },
            {
              "line": 69,
              "text": "    int kszE;                   // number of frames for decode for submode E"
            },
            {
              "line": 70,
              "text": "    int kszI;                   // number of frames for decode for submode I"
            },
            {
              "line": 71,
              "text": "    int nsubmodes;              // which submodes to decode"
            },
            {
              "line": 72,
              "text": "  } params;"
            },
            {
              "line": 73,
              "text": "} dec_data;"
            }
          ]
        },
        {
          "line": 71,
          "match": "int nsubmodes;              // which submodes to decode",
          "context": [
            {
              "line": 68,
              "text": "    int kszC;                   // number of frames for decode for submode C"
            },
            {
              "line": 69,
              "text": "    int kszE;                   // number of frames for decode for submode E"
            },
            {
              "line": 70,
              "text": "    int kszI;                   // number of frames for decode for submode I"
            },
            {
              "line": 71,
              "text": "    int nsubmodes;              // which submodes to decode"
            },
            {
              "line": 72,
              "text": "  } params;"
            },
            {
              "line": 73,
              "text": "} dec_data;"
            },
            {
              "line": 74,
              "text": ""
            }
          ]
        },
        {
          "line": 86,
          "match": "// See also decode_time() below.",
          "context": [
            {
              "line": 83,
              "text": "extern std::mutex fftw_mutex;"
            },
            {
              "line": 84,
              "text": ""
            },
            {
              "line": 85,
              "text": "// The way we squeeze a timestamp into an int."
            },
            {
              "line": 86,
              "text": "// See also decode_time() below."
            },
            {
              "line": 87,
              "text": "inline int code_time(int hour, int minute, int second){"
            },
            {
              "line": 88,
              "text": "  return hour * 10000 + minute * 100 + second;"
            },
            {
              "line": 89,
              "text": "}"
            }
          ]
        },
        {
          "line": 98,
          "match": "inline hour_minute_second decode_time(int nutc){",
          "context": [
            {
              "line": 95,
              "text": "};"
            },
            {
              "line": 96,
              "text": ""
            },
            {
              "line": 97,
              "text": "// Undo code_time()."
            },
            {
              "line": 98,
              "text": "inline hour_minute_second decode_time(int nutc){"
            },
            {
              "line": 99,
              "text": "  struct hour_minute_second result;"
            },
            {
              "line": 100,
              "text": "  result.hour = nutc / 10000;"
            },
            {
              "line": 101,
              "text": "  result.minute = nutc % 10000 / 100;"
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/JS8Submode.h",
      "exists": true,
      "bytes": 2884,
      "lines": 102,
      "score": 40,
      "keyword_hits": {
        "decode": 2,
        "Decode": 2,
        "symbol": 10,
        "tone": 1,
        "Costas": 2,
        "samplesForOneSymbol": 2,
        "toneSpacing": 1
      },
      "phase_scores": {
        "symbol_to_bits": 11,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 0,
        "timing_constants": 3
      },
      "candidate_functions": [],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 25,
          "match": "// Something seemingly harmless such as 3 - samplesForOneSymbol",
          "context": [
            {
              "line": 22,
              "text": "// will throw if provided with an invalid JS8 submode."
            },
            {
              "line": 23,
              "text": ""
            },
            {
              "line": 24,
              "text": "// Be careful when doing arithmetic with values that are unsigned."
            },
            {
              "line": 25,
              "text": "// Something seemingly harmless such as 3 - samplesForOneSymbol"
            },
            {
              "line": 26,
              "text": "// might end up as 4,294,965,379."
            },
            {
              "line": 27,
              "text": ""
            },
            {
              "line": 28,
              "text": "// One way to see the actual values of the various modes:"
            }
          ]
        },
        {
          "line": 36,
          "match": "Costas::Type costas(int);",
          "context": [
            {
              "line": 33,
              "text": "/** Name of the submode, in all uppercase letters. */"
            },
            {
              "line": 34,
              "text": "QString name(int);"
            },
            {
              "line": 35,
              "text": "unsigned int bandwidth(int);"
            },
            {
              "line": 36,
              "text": "Costas::Type costas(int);"
            },
            {
              "line": 37,
              "text": ""
            },
            {
              "line": 38,
              "text": "/**"
            },
            {
              "line": 39,
              "text": " * How long from one transmission start to the next transmission start,"
            }
          ]
        },
        {
          "line": 47,
          "match": "* one symbol. */",
          "context": [
            {
              "line": 44,
              "text": "unsigned int period(int);"
            },
            {
              "line": 45,
              "text": ""
            },
            {
              "line": 46,
              "text": "/** How many audio samples (at 12000 samples per second) it takes to transfer"
            },
            {
              "line": 47,
              "text": " * one symbol. */"
            },
            {
              "line": 48,
              "text": "unsigned int samplesForOneSymbol(int);"
            },
            {
              "line": 49,
              "text": ""
            },
            {
              "line": 50,
              "text": "/**"
            }
          ]
        },
        {
          "line": 48,
          "match": "unsigned int samplesForOneSymbol(int);",
          "context": [
            {
              "line": 45,
              "text": ""
            },
            {
              "line": 46,
              "text": "/** How many audio samples (at 12000 samples per second) it takes to transfer"
            },
            {
              "line": 47,
              "text": " * one symbol. */"
            },
            {
              "line": 48,
              "text": "unsigned int samplesForOneSymbol(int);"
            },
            {
              "line": 49,
              "text": ""
            },
            {
              "line": 50,
              "text": "/**"
            },
            {
              "line": 51,
              "text": " * How many audio samples we use to transmit the symbols"
            }
          ]
        },
        {
          "line": 51,
          "match": "* How many audio samples we use to transmit the symbols",
          "context": [
            {
              "line": 48,
              "text": "unsigned int samplesForOneSymbol(int);"
            },
            {
              "line": 49,
              "text": ""
            },
            {
              "line": 50,
              "text": "/**"
            },
            {
              "line": 51,
              "text": " * How many audio samples we use to transmit the symbols"
            },
            {
              "line": 52,
              "text": " * of one period."
            },
            {
              "line": 53,
              "text": " *"
            },
            {
              "line": 54,
              "text": " * As there are JS8_NUM_SYMBOLS = 79 symbols in a period,"
            }
          ]
        },
        {
          "line": 54,
          "match": "* As there are JS8_NUM_SYMBOLS = 79 symbols in a period,",
          "context": [
            {
              "line": 51,
              "text": " * How many audio samples we use to transmit the symbols"
            },
            {
              "line": 52,
              "text": " * of one period."
            },
            {
              "line": 53,
              "text": " *"
            },
            {
              "line": 54,
              "text": " * As there are JS8_NUM_SYMBOLS = 79 symbols in a period,"
            },
            {
              "line": 55,
              "text": " * this is 79 * samplesForOneSymol."
            },
            {
              "line": 56,
              "text": " */"
            },
            {
              "line": 57,
              "text": "unsigned int samplesForSymbols(int);"
            }
          ]
        },
        {
          "line": 57,
          "match": "unsigned int samplesForSymbols(int);",
          "context": [
            {
              "line": 54,
              "text": " * As there are JS8_NUM_SYMBOLS = 79 symbols in a period,"
            },
            {
              "line": 55,
              "text": " * this is 79 * samplesForOneSymol."
            },
            {
              "line": 56,
              "text": " */"
            },
            {
              "line": 57,
              "text": "unsigned int samplesForSymbols(int);"
            },
            {
              "line": 58,
              "text": ""
            },
            {
              "line": 59,
              "text": "/**"
            },
            {
              "line": 60,
              "text": " * The number of samples needed to capture the entire TX duration,"
            }
          ]
        },
        {
          "line": 76,
          "match": "double toneSpacing(int);",
          "context": [
            {
              "line": 73,
              "text": "/** How long to wait after tx start before actually sending data, in"
            },
            {
              "line": 74,
              "text": " * milliseconds. */"
            },
            {
              "line": 75,
              "text": "unsigned int startDelayMS(int);"
            },
            {
              "line": 76,
              "text": "double toneSpacing(int);"
            },
            {
              "line": 77,
              "text": ""
            },
            {
              "line": 78,
              "text": "/**"
            },
            {
              "line": 79,
              "text": " * Duration in seconds that it takes to transmit the symbols."
            }
          ]
        },
        {
          "line": 79,
          "match": "* Duration in seconds that it takes to transmit the symbols.",
          "context": [
            {
              "line": 76,
              "text": "double toneSpacing(int);"
            },
            {
              "line": 77,
              "text": ""
            },
            {
              "line": 78,
              "text": "/**"
            },
            {
              "line": 79,
              "text": " * Duration in seconds that it takes to transmit the symbols."
            },
            {
              "line": 80,
              "text": " *"
            },
            {
              "line": 81,
              "text": " * This is samplesForSymbols / 12000."
            },
            {
              "line": 82,
              "text": " */"
            }
          ]
        },
        {
          "line": 81,
          "match": "* This is samplesForSymbols / 12000.",
          "context": [
            {
              "line": 78,
              "text": "/**"
            },
            {
              "line": 79,
              "text": " * Duration in seconds that it takes to transmit the symbols."
            },
            {
              "line": 80,
              "text": " *"
            },
            {
              "line": 81,
              "text": " * This is samplesForSymbols / 12000."
            },
            {
              "line": 82,
              "text": " */"
            },
            {
              "line": 83,
              "text": "double dataDuration(int);"
            },
            {
              "line": 84,
              "text": ""
            }
          ]
        },
        {
          "line": 88,
          "match": "* This is samplesForSymbols / 12000 + startDelayMS / 1000",
          "context": [
            {
              "line": 85,
              "text": "/**"
            },
            {
              "line": 86,
              "text": " * Actual duration of the transmission, in seconds."
            },
            {
              "line": 87,
              "text": " *"
            },
            {
              "line": 88,
              "text": " * This is samplesForSymbols / 12000 + startDelayMS / 1000"
            },
            {
              "line": 89,
              "text": " */"
            },
            {
              "line": 90,
              "text": "double txDuration(int);"
            },
            {
              "line": 91,
              "text": ""
            }
          ]
        },
        {
          "line": 97,
          "match": "int computeCycleForDecode(int, int);",
          "context": [
            {
              "line": 94,
              "text": "// Each of these functions will throw if provided with an invalid JS8"
            },
            {
              "line": 95,
              "text": "// submode."
            },
            {
              "line": 96,
              "text": ""
            },
            {
              "line": 97,
              "text": "int computeCycleForDecode(int, int);"
            },
            {
              "line": 98,
              "text": "int computeAltCycleForDecode(int, int, int);"
            },
            {
              "line": 99,
              "text": "double computeRatio(int, double);"
            },
            {
              "line": 100,
              "text": "} // namespace JS8::Submode"
            }
          ]
        },
        {
          "line": 98,
          "match": "int computeAltCycleForDecode(int, int, int);",
          "context": [
            {
              "line": 95,
              "text": "// submode."
            },
            {
              "line": 96,
              "text": ""
            },
            {
              "line": 97,
              "text": "int computeCycleForDecode(int, int);"
            },
            {
              "line": 98,
              "text": "int computeAltCycleForDecode(int, int, int);"
            },
            {
              "line": 99,
              "text": "double computeRatio(int, double);"
            },
            {
              "line": 100,
              "text": "} // namespace JS8::Submode"
            },
            {
              "line": 101,
              "text": ""
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/JS8.h",
      "exists": true,
      "bytes": 2284,
      "lines": 108,
      "score": 39,
      "keyword_hits": {
        "decode": 13,
        "Decode": 13,
        "message": 1,
        "Message": 1,
        "tone": 1,
        "Costas": 8
      },
      "phase_scores": {
        "symbol_to_bits": 1,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 0,
        "timing_constants": 0
      },
      "candidate_functions": [],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 15,
          "match": "namespace Costas {",
          "context": [
            {
              "line": 12,
              "text": "namespace JS8 {"
            },
            {
              "line": 13,
              "text": "Q_NAMESPACE"
            },
            {
              "line": 14,
              "text": ""
            },
            {
              "line": 15,
              "text": "namespace Costas {"
            },
            {
              "line": 16,
              "text": "// JS8 originally used the same Costas arrays as FT8 did, and so"
            },
            {
              "line": 17,
              "text": "// that's still the array in use by 'normal' mode. All the other"
            },
            {
              "line": 18,
              "text": "// modes use the modified arrays."
            }
          ]
        },
        {
          "line": 16,
          "match": "// JS8 originally used the same Costas arrays as FT8 did, and so",
          "context": [
            {
              "line": 13,
              "text": "Q_NAMESPACE"
            },
            {
              "line": 14,
              "text": ""
            },
            {
              "line": 15,
              "text": "namespace Costas {"
            },
            {
              "line": 16,
              "text": "// JS8 originally used the same Costas arrays as FT8 did, and so"
            },
            {
              "line": 17,
              "text": "// that's still the array in use by 'normal' mode. All the other"
            },
            {
              "line": 18,
              "text": "// modes use the modified arrays."
            },
            {
              "line": 19,
              "text": ""
            }
          ]
        },
        {
          "line": 25,
          "match": "constexpr auto COSTAS =",
          "context": [
            {
              "line": 22,
              "text": "using Array = std::array<std::array<int, 7>, 3>;"
            },
            {
              "line": 23,
              "text": ""
            },
            {
              "line": 24,
              "text": "constexpr auto array = [] {"
            },
            {
              "line": 25,
              "text": "    constexpr auto COSTAS ="
            },
            {
              "line": 26,
              "text": "        std::array{std::array{std::array{4, 2, 5, 6, 1, 3, 0},"
            },
            {
              "line": 27,
              "text": "                              std::array{4, 2, 5, 6, 1, 3, 0},"
            },
            {
              "line": 28,
              "text": "                              std::array{4, 2, 5, 6, 1, 3, 0}},"
            }
          ]
        },
        {
          "line": 33,
          "match": "return [COSTAS](Type type) -> Array const & {",
          "context": [
            {
              "line": 30,
              "text": "                              std::array{1, 5, 0, 2, 3, 6, 4},"
            },
            {
              "line": 31,
              "text": "                              std::array{2, 5, 0, 6, 4, 1, 3}}};"
            },
            {
              "line": 32,
              "text": ""
            },
            {
              "line": 33,
              "text": "    return [COSTAS](Type type) -> Array const & {"
            },
            {
              "line": 34,
              "text": "        return COSTAS[static_cast<std::underlying_type_t<Type>>(type)];"
            },
            {
              "line": 35,
              "text": "    };"
            },
            {
              "line": 36,
              "text": "}();"
            }
          ]
        },
        {
          "line": 34,
          "match": "return COSTAS[static_cast<std::underlying_type_t<Type>>(type)];",
          "context": [
            {
              "line": 31,
              "text": "                              std::array{2, 5, 0, 6, 4, 1, 3}}};"
            },
            {
              "line": 32,
              "text": ""
            },
            {
              "line": 33,
              "text": "    return [COSTAS](Type type) -> Array const & {"
            },
            {
              "line": 34,
              "text": "        return COSTAS[static_cast<std::underlying_type_t<Type>>(type)];"
            },
            {
              "line": 35,
              "text": "    };"
            },
            {
              "line": 36,
              "text": "}();"
            },
            {
              "line": 37,
              "text": "} // namespace Costas"
            }
          ]
        },
        {
          "line": 37,
          "match": "} // namespace Costas",
          "context": [
            {
              "line": 34,
              "text": "        return COSTAS[static_cast<std::underlying_type_t<Type>>(type)];"
            },
            {
              "line": 35,
              "text": "    };"
            },
            {
              "line": 36,
              "text": "}();"
            },
            {
              "line": 37,
              "text": "} // namespace Costas"
            },
            {
              "line": 38,
              "text": ""
            },
            {
              "line": 39,
              "text": "void encode(int type, Costas::Array const &costas, const char *message,"
            },
            {
              "line": 40,
              "text": "            int *tones);"
            }
          ]
        },
        {
          "line": 39,
          "match": "void encode(int type, Costas::Array const &costas, const char *message,",
          "context": [
            {
              "line": 36,
              "text": "}();"
            },
            {
              "line": 37,
              "text": "} // namespace Costas"
            },
            {
              "line": 38,
              "text": ""
            },
            {
              "line": 39,
              "text": "void encode(int type, Costas::Array const &costas, const char *message,"
            },
            {
              "line": 40,
              "text": "            int *tones);"
            },
            {
              "line": 41,
              "text": ""
            },
            {
              "line": 42,
              "text": "namespace Event {"
            }
          ]
        },
        {
          "line": 40,
          "match": "int *tones);",
          "context": [
            {
              "line": 37,
              "text": "} // namespace Costas"
            },
            {
              "line": 38,
              "text": ""
            },
            {
              "line": 39,
              "text": "void encode(int type, Costas::Array const &costas, const char *message,"
            },
            {
              "line": 40,
              "text": "            int *tones);"
            },
            {
              "line": 41,
              "text": ""
            },
            {
              "line": 42,
              "text": "namespace Event {"
            },
            {
              "line": 43,
              "text": "struct DecodeStarted {"
            }
          ]
        },
        {
          "line": 43,
          "match": "struct DecodeStarted {",
          "context": [
            {
              "line": 40,
              "text": "            int *tones);"
            },
            {
              "line": 41,
              "text": ""
            },
            {
              "line": 42,
              "text": "namespace Event {"
            },
            {
              "line": 43,
              "text": "struct DecodeStarted {"
            },
            {
              "line": 44,
              "text": "    int submodes;"
            },
            {
              "line": 45,
              "text": "};"
            },
            {
              "line": 46,
              "text": ""
            }
          ]
        },
        {
          "line": 53,
          "match": "enum class Type { CANDIDATE, DECODED } type;",
          "context": [
            {
              "line": 50,
              "text": "};"
            },
            {
              "line": 51,
              "text": ""
            },
            {
              "line": 52,
              "text": "struct SyncState {"
            },
            {
              "line": 53,
              "text": "    enum class Type { CANDIDATE, DECODED } type;"
            },
            {
              "line": 54,
              "text": "    int mode;"
            },
            {
              "line": 55,
              "text": "    float frequency;"
            },
            {
              "line": 56,
              "text": "    float dt;"
            }
          ]
        },
        {
          "line": 59,
          "match": "float decoded;",
          "context": [
            {
              "line": 56,
              "text": "    float dt;"
            },
            {
              "line": 57,
              "text": "    union {"
            },
            {
              "line": 58,
              "text": "        int candidate;"
            },
            {
              "line": 59,
              "text": "        float decoded;"
            },
            {
              "line": 60,
              "text": "    } sync;"
            },
            {
              "line": 61,
              "text": "};"
            },
            {
              "line": 62,
              "text": ""
            }
          ]
        },
        {
          "line": 63,
          "match": "struct Decoded {",
          "context": [
            {
              "line": 60,
              "text": "    } sync;"
            },
            {
              "line": 61,
              "text": "};"
            },
            {
              "line": 62,
              "text": ""
            },
            {
              "line": 63,
              "text": "struct Decoded {"
            },
            {
              "line": 64,
              "text": "    int utc; // you can use the output of code_time() from commons.h here."
            },
            {
              "line": 65,
              "text": "    int snr;"
            },
            {
              "line": 66,
              "text": "    float xdt;"
            }
          ]
        },
        {
          "line": 74,
          "match": "struct DecodeFinished {",
          "context": [
            {
              "line": 71,
              "text": "    int mode;"
            },
            {
              "line": 72,
              "text": "};"
            },
            {
              "line": 73,
              "text": ""
            },
            {
              "line": 74,
              "text": "struct DecodeFinished {"
            },
            {
              "line": 75,
              "text": "    std::size_t decoded;"
            },
            {
              "line": 76,
              "text": "};"
            },
            {
              "line": 77,
              "text": ""
            }
          ]
        },
        {
          "line": 75,
          "match": "std::size_t decoded;",
          "context": [
            {
              "line": 72,
              "text": "};"
            },
            {
              "line": 73,
              "text": ""
            },
            {
              "line": 74,
              "text": "struct DecodeFinished {"
            },
            {
              "line": 75,
              "text": "    std::size_t decoded;"
            },
            {
              "line": 76,
              "text": "};"
            },
            {
              "line": 77,
              "text": ""
            },
            {
              "line": 78,
              "text": "using Variant ="
            }
          ]
        },
        {
          "line": 79,
          "match": "std::variant<DecodeStarted, SyncStart, SyncState, Decoded, DecodeFinished>;",
          "context": [
            {
              "line": 76,
              "text": "};"
            },
            {
              "line": 77,
              "text": ""
            },
            {
              "line": 78,
              "text": "using Variant ="
            },
            {
              "line": 79,
              "text": "    std::variant<DecodeStarted, SyncStart, SyncState, Decoded, DecodeFinished>;"
            },
            {
              "line": 80,
              "text": ""
            },
            {
              "line": 81,
              "text": "using Emitter = std::function<void(Variant const &)>;"
            },
            {
              "line": 82,
              "text": "} // namespace Event"
            }
          ]
        },
        {
          "line": 86,
          "match": "class Decoder : public QObject {",
          "context": [
            {
              "line": 83,
              "text": ""
            },
            {
              "line": 84,
              "text": "class Worker;"
            },
            {
              "line": 85,
              "text": ""
            },
            {
              "line": 86,
              "text": "class Decoder : public QObject {"
            },
            {
              "line": 87,
              "text": "    Q_OBJECT"
            },
            {
              "line": 88,
              "text": ""
            },
            {
              "line": 89,
              "text": "    QSemaphore m_semaphore;"
            }
          ]
        },
        {
          "line": 94,
          "match": "Decoder(QObject *parent = nullptr);",
          "context": [
            {
              "line": 91,
              "text": "    Worker *m_worker;"
            },
            {
              "line": 92,
              "text": ""
            },
            {
              "line": 93,
              "text": "  public:"
            },
            {
              "line": 94,
              "text": "    Decoder(QObject *parent = nullptr);"
            },
            {
              "line": 95,
              "text": ""
            },
            {
              "line": 96,
              "text": "  signals:"
            },
            {
              "line": 97,
              "text": ""
            }
          ]
        },
        {
          "line": 98,
          "match": "void decodeEvent(Event::Variant const &);",
          "context": [
            {
              "line": 95,
              "text": ""
            },
            {
              "line": 96,
              "text": "  signals:"
            },
            {
              "line": 97,
              "text": ""
            },
            {
              "line": 98,
              "text": "    void decodeEvent(Event::Variant const &);"
            },
            {
              "line": 99,
              "text": ""
            },
            {
              "line": 100,
              "text": "  public slots:"
            },
            {
              "line": 101,
              "text": ""
            }
          ]
        },
        {
          "line": 104,
          "match": "void decode();",
          "context": [
            {
              "line": 101,
              "text": ""
            },
            {
              "line": 102,
              "text": "    void start(QThread::Priority priority);"
            },
            {
              "line": 103,
              "text": "    void quit();"
            },
            {
              "line": 104,
              "text": "    void decode();"
            },
            {
              "line": 105,
              "text": "};"
            },
            {
              "line": 106,
              "text": "} // namespace JS8"
            },
            {
              "line": 107,
              "text": ""
            }
          ]
        }
      ]
    },
    {
      "path": "JS8_Mode/Decoder.h",
      "exists": true,
      "bytes": 2022,
      "lines": 90,
      "score": 14,
      "keyword_hits": {
        "decode": 7,
        "Decode": 7
      },
      "phase_scores": {
        "symbol_to_bits": 0,
        "bit_order_interleaver": 0,
        "whitening_mask": 0,
        "ldpc_fec": 0,
        "message91_crc": 0,
        "timing_constants": 0
      },
      "candidate_functions": [],
      "candidate_arrays": [],
      "candidate_defines": [],
      "snippets": [
        {
          "line": 1,
          "match": "#ifndef DECODER_H",
          "context": [
            {
              "line": 1,
              "text": "#ifndef DECODER_H"
            },
            {
              "line": 2,
              "text": "#define DECODER_H"
            },
            {
              "line": 3,
              "text": ""
            },
            {
              "line": 4,
              "text": "/**"
            }
          ]
        },
        {
          "line": 2,
          "match": "#define DECODER_H",
          "context": [
            {
              "line": 1,
              "text": "#ifndef DECODER_H"
            },
            {
              "line": 2,
              "text": "#define DECODER_H"
            },
            {
              "line": 3,
              "text": ""
            },
            {
              "line": 4,
              "text": "/**"
            },
            {
              "line": 5,
              "text": " * (C) 2019 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved"
            }
          ]
        },
        {
          "line": 37,
          "match": "class Decoder : public QObject {",
          "context": [
            {
              "line": 34,
              "text": "    QScopedPointer<QProcess> m_proc;"
            },
            {
              "line": 35,
              "text": "};"
            },
            {
              "line": 36,
              "text": ""
            },
            {
              "line": 37,
              "text": "class Decoder : public QObject {"
            },
            {
              "line": 38,
              "text": "    Q_OBJECT"
            },
            {
              "line": 39,
              "text": "  public:"
            },
            {
              "line": 40,
              "text": "    Decoder(QObject *parent = nullptr);"
            }
          ]
        },
        {
          "line": 40,
          "match": "Decoder(QObject *parent = nullptr);",
          "context": [
            {
              "line": 37,
              "text": "class Decoder : public QObject {"
            },
            {
              "line": 38,
              "text": "    Q_OBJECT"
            },
            {
              "line": 39,
              "text": "  public:"
            },
            {
              "line": 40,
              "text": "    Decoder(QObject *parent = nullptr);"
            },
            {
              "line": 41,
              "text": "    ~Decoder();"
            },
            {
              "line": 42,
              "text": ""
            },
            {
              "line": 43,
              "text": "    void lock();"
            }
          ]
        },
        {
          "line": 41,
          "match": "~Decoder();",
          "context": [
            {
              "line": 38,
              "text": "    Q_OBJECT"
            },
            {
              "line": 39,
              "text": "  public:"
            },
            {
              "line": 40,
              "text": "    Decoder(QObject *parent = nullptr);"
            },
            {
              "line": 41,
              "text": "    ~Decoder();"
            },
            {
              "line": 42,
              "text": ""
            },
            {
              "line": 43,
              "text": "    void lock();"
            },
            {
              "line": 44,
              "text": "    void unlock();"
            }
          ]
        },
        {
          "line": 88,
          "match": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8)",
          "context": [
            {
              "line": 85,
              "text": "    QThread m_thread;"
            },
            {
              "line": 86,
              "text": "};"
            },
            {
              "line": 87,
              "text": ""
            },
            {
              "line": 88,
              "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8)"
            },
            {
              "line": 89,
              "text": ""
            },
            {
              "line": 90,
              "text": "#endif // DECODER_H"
            }
          ]
        },
        {
          "line": 90,
          "match": "#endif // DECODER_H",
          "context": [
            {
              "line": 87,
              "text": ""
            },
            {
              "line": 88,
              "text": "Q_DECLARE_LOGGING_CATEGORY(decoder_js8)"
            },
            {
              "line": 89,
              "text": ""
            },
            {
              "line": 90,
              "text": "#endif // DECODER_H"
            }
          ]
        }
      ]
    }
  ],
  "additional_candidates": [],
  "phase_top_files": {
    "symbol_to_bits": [
      {
        "path": "JS8_JSC/JSC_list.cpp",
        "phase_score": 837,
        "score": 1105
      },
      {
        "path": "JS8_JSC/JSC_map.cpp",
        "phase_score": 837,
        "score": 1104
      },
      {
        "path": "JS8_Main/Varicode.cpp",
        "phase_score": 231,
        "score": 1011
      },
      {
        "path": "JS8_Mode/JS8.cpp",
        "phase_score": 224,
        "score": 387
      },
      {
        "path": "JS8_Mode/whitening_processor.h",
        "phase_score": 73,
        "score": 153
      },
      {
        "path": "JS8_Mode/soft_combiner.h",
        "phase_score": 61,
        "score": 125
      },
      {
        "path": "JS8_Mode/JS8Submode.cpp",
        "phase_score": 41,
        "score": 157
      },
      {
        "path": "JS8_Main/Varicode.h",
        "phase_score": 32,
        "score": 154
      },
      {
        "path": "JS8_Mode/ldpc_feedback.h",
        "phase_score": 31,
        "score": 109
      },
      {
        "path": "JS8_Mode/DecodedText.cpp",
        "phase_score": 23,
        "score": 176
      }
    ],
    "bit_order_interleaver": [
      {
        "path": "JS8_JSC/JSC_list.cpp",
        "phase_score": 10,
        "score": 1105
      },
      {
        "path": "JS8_JSC/JSC_map.cpp",
        "phase_score": 10,
        "score": 1104
      },
      {
        "path": "JS8_Mode/JS8.cpp",
        "phase_score": 6,
        "score": 387
      },
      {
        "path": "JS8_Mode/soft_combiner.h",
        "phase_score": 2,
        "score": 125
      }
    ],
    "whitening_mask": [
      {
        "path": "JS8_JSC/JSC_list.cpp",
        "phase_score": 76,
        "score": 1105
      },
      {
        "path": "JS8_JSC/JSC_map.cpp",
        "phase_score": 76,
        "score": 1104
      },
      {
        "path": "JS8_Mode/whitening_processor.h",
        "phase_score": 24,
        "score": 153
      },
      {
        "path": "JS8_Mode/JS8.cpp",
        "phase_score": 21,
        "score": 387
      },
      {
        "path": "JS8_Main/Varicode.cpp",
        "phase_score": 11,
        "score": 1011
      }
    ],
    "ldpc_fec": [
      {
        "path": "JS8_Mode/JS8.cpp",
        "phase_score": 30,
        "score": 387
      },
      {
        "path": "JS8_Mode/ldpc_feedback.h",
        "phase_score": 13,
        "score": 109
      },
      {
        "path": "JS8_JSC/JSC_list.cpp",
        "phase_score": 5,
        "score": 1105
      },
      {
        "path": "JS8_JSC/JSC_map.cpp",
        "phase_score": 5,
        "score": 1104
      }
    ],
    "message91_crc": [
      {
        "path": "JS8_Main/Varicode.cpp",
        "phase_score": 641,
        "score": 1011
      },
      {
        "path": "JS8_JSC/JSC_list.cpp",
        "phase_score": 121,
        "score": 1105
      },
      {
        "path": "JS8_JSC/JSC_map.cpp",
        "phase_score": 120,
        "score": 1104
      },
      {
        "path": "JS8_Mode/DecodedText.cpp",
        "phase_score": 76,
        "score": 176
      },
      {
        "path": "JS8_Main/Varicode.h",
        "phase_score": 66,
        "score": 154
      },
      {
        "path": "JS8_Mode/JS8.cpp",
        "phase_score": 24,
        "score": 387
      },
      {
        "path": "JS8_Mode/DecodedText.h",
        "phase_score": 24,
        "score": 86
      },
      {
        "path": "JS8_Mode/JS8Submode.cpp",
        "phase_score": 7,
        "score": 157
      }
    ],
    "timing_constants": [
      {
        "path": "JS8_Mode/JS8Submode.cpp",
        "phase_score": 26,
        "score": 157
      },
      {
        "path": "JS8_Mode/JS8.cpp",
        "phase_score": 5,
        "score": 387
      },
      {
        "path": "JS8_Include/commons.h",
        "phase_score": 3,
        "score": 66
      },
      {
        "path": "JS8_Mode/JS8Submode.h",
        "phase_score": 3,
        "score": 40
      }
    ]
  },
  "lab_alignment_questions": [
    {
      "lab_observation": "Step51 source-aligned NSPS=6192 still reaches best syndrome 22 and prefers tone-spacing offset -0.03.",
      "source_question": "Find whether JS8Call-Improved applies submode-specific symbol timing/tone correction after JS8_NSPS or before FEC extraction.",
      "look_in": [
        "JS8_Mode/JS8Submode.cpp",
        "JS8_Mode/JS8.cpp",
        "JS8_Mode/Decoder.cpp"
      ]
    },
    {
      "lab_observation": "Best row currently depends on lab FT8-style Gray demap and bit-order hypotheses.",
      "source_question": "Find exact symbol-to-bit and interleaver/deinterleaver path before LDPC to replace the lab hypothesis.",
      "look_in": [
        "JS8_Mode/Decoder.cpp",
        "JS8_Mode/ldpc_feedback.h",
        "JS8_Mode/soft_combiner.h"
      ]
    },
    {
      "lab_observation": "Syndrome-closure/CRC probes do not validate Message91 candidates.",
      "source_question": "Find whitening/scrambling/mask and Varicode/JSC unpack order before adding more repair probes.",
      "look_in": [
        "JS8_Mode/whitening_processor.h",
        "JS8_Main/Varicode.cpp",
        "JS8_JSC/JSC_map.cpp"
      ]
    }
  ],
  "audit_conclusion": {
    "no_gui_runtime_started": true,
    "recommended_next_step": "Use top focused snippets to implement a source-derived bitpath/interleaver/whitening patch before another LDPC/CRC repair run.",
    "why": "Step51 confirmed source NSPS but did not improve below syndrome 22; remaining uncertainty is exact source bitpath rather than wider timing."
  }
}
