mirror of
https://github.com/RFnexus/modem73.git
synced 2026-04-27 14:30:33 +00:00
fix for error stats
This commit is contained in:
parent
042b6ce6c6
commit
70b9385f00
3 changed files with 113 additions and 11 deletions
16
kiss_tnc.cc
16
kiss_tnc.cc
|
|
@ -787,6 +787,18 @@ private:
|
||||||
float db = 20.0f * std::log10(rms + 1e-10f);
|
float db = 20.0f * std::log10(rms + 1e-10f);
|
||||||
|
|
||||||
g_ui_state->update_level(db);
|
g_ui_state->update_level(db);
|
||||||
|
|
||||||
|
// Copy decoder stats
|
||||||
|
if (g_ui_state->stats_reset_requested.exchange(false)) {
|
||||||
|
decoder_->stats_sync_count = 0;
|
||||||
|
decoder_->stats_preamble_errors = 0;
|
||||||
|
decoder_->stats_symbol_errors = 0;
|
||||||
|
decoder_->stats_crc_errors = 0;
|
||||||
|
}
|
||||||
|
g_ui_state->sync_count = decoder_->stats_sync_count;
|
||||||
|
g_ui_state->preamble_errors = decoder_->stats_preamble_errors;
|
||||||
|
g_ui_state->symbol_errors = decoder_->stats_symbol_errors;
|
||||||
|
g_ui_state->crc_errors = decoder_->stats_crc_errors;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -880,7 +892,7 @@ private:
|
||||||
std::chrono::steady_clock::time_point tx_lockout_until_;
|
std::chrono::steady_clock::time_point tx_lockout_until_;
|
||||||
static constexpr float RX_LOCKOUT_SECONDS = 0.5f;
|
static constexpr float RX_LOCKOUT_SECONDS = 0.5f;
|
||||||
|
|
||||||
// TX blanking
|
// TX blanking
|
||||||
std::atomic<bool> tx_blanking_active_{false};
|
std::atomic<bool> tx_blanking_active_{false};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -892,7 +904,7 @@ public:
|
||||||
config_.p_persistence = new_config.p_persistence;
|
config_.p_persistence = new_config.p_persistence;
|
||||||
config_.slot_time_ms = new_config.slot_time_ms;
|
config_.slot_time_ms = new_config.slot_time_ms;
|
||||||
|
|
||||||
// TX blanking
|
// TX blanking
|
||||||
config_.tx_blanking_enabled = new_config.tx_blanking_enabled;
|
config_.tx_blanking_enabled = new_config.tx_blanking_enabled;
|
||||||
|
|
||||||
// Update callsign if changed
|
// Update callsign if changed
|
||||||
|
|
|
||||||
10
modem.hh
10
modem.hh
|
|
@ -452,6 +452,11 @@ public:
|
||||||
// Get current modulation bits
|
// Get current modulation bits
|
||||||
int get_mod_bits() const { return mod_bits; }
|
int get_mod_bits() const { return mod_bits; }
|
||||||
|
|
||||||
|
// decode statistics
|
||||||
|
int stats_sync_count = 0; // corelator
|
||||||
|
int stats_preamble_errors = 0; // preamble decoding failed
|
||||||
|
int stats_symbol_errors = 0; // seed damage
|
||||||
|
int stats_crc_errors = 0; // polar CRC failed
|
||||||
private:
|
private:
|
||||||
enum class State {
|
enum class State {
|
||||||
SEARCHING, // looking for preamble
|
SEARCHING, // looking for preamble
|
||||||
|
|
@ -621,6 +626,7 @@ private:
|
||||||
case State::SEARCHING:
|
case State::SEARCHING:
|
||||||
if ((*correlator_ptr)(buf_)) {
|
if ((*correlator_ptr)(buf_)) {
|
||||||
// Sync found
|
// Sync found
|
||||||
|
++stats_sync_count;
|
||||||
symbol_pos = correlator_ptr->symbol_pos;
|
symbol_pos = correlator_ptr->symbol_pos;
|
||||||
cfo_rad = correlator_ptr->cfo_rad;
|
cfo_rad = correlator_ptr->cfo_rad;
|
||||||
|
|
||||||
|
|
@ -638,6 +644,8 @@ private:
|
||||||
// Need to advance past preamble: symbol_pos + symbol_len + extended_len
|
// Need to advance past preamble: symbol_pos + symbol_len + extended_len
|
||||||
// Plus extended_len for the first data symbol
|
// Plus extended_len for the first data symbol
|
||||||
samples_needed_ = symbol_pos + symbol_len + 2 * extended_len;
|
samples_needed_ = symbol_pos + symbol_len + 2 * extended_len;
|
||||||
|
} else {
|
||||||
|
++stats_preamble_errors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -651,6 +659,7 @@ private:
|
||||||
// Process this symbol
|
// Process this symbol
|
||||||
if (!process_symbol(symbol_index_)) {
|
if (!process_symbol(symbol_index_)) {
|
||||||
// Error, go back to searching
|
// Error, go back to searching
|
||||||
|
++stats_symbol_errors;
|
||||||
state_ = State::SEARCHING;
|
state_ = State::SEARCHING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -956,6 +965,7 @@ private:
|
||||||
|
|
||||||
if (best < 0) {
|
if (best < 0) {
|
||||||
std::cerr << "Decoder: CRC failed" << std::endl;
|
std::cerr << "Decoder: CRC failed" << std::endl;
|
||||||
|
++stats_crc_errors;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
98
tnc_ui.hh
98
tnc_ui.hh
|
|
@ -151,13 +151,19 @@ struct TNCUIState {
|
||||||
std::atomic<int> tx_frame_count{0};
|
std::atomic<int> tx_frame_count{0};
|
||||||
std::atomic<int> rx_error_count{0};
|
std::atomic<int> rx_error_count{0};
|
||||||
|
|
||||||
|
// Decode statistics
|
||||||
|
std::atomic<int> sync_count{0};
|
||||||
|
std::atomic<int> preamble_errors{0};
|
||||||
|
std::atomic<int> symbol_errors{0};
|
||||||
|
std::atomic<int> crc_errors{0};
|
||||||
|
std::atomic<bool> stats_reset_requested{false};
|
||||||
|
|
||||||
// Signal visualization
|
// Signal visualization
|
||||||
static constexpr int LEVEL_HISTORY_SIZE = 60;
|
static constexpr int LEVEL_HISTORY_SIZE = 60;
|
||||||
std::mutex level_mutex;
|
std::mutex level_mutex;
|
||||||
float level_history[LEVEL_HISTORY_SIZE];
|
float level_history[LEVEL_HISTORY_SIZE];
|
||||||
int level_history_pos = 0;
|
int level_history_pos = 0;
|
||||||
std::atomic<bool> decoding_active{false};
|
std::atomic<bool> decoding_active{false};
|
||||||
std::atomic<int> sync_count{0};
|
|
||||||
|
|
||||||
// SNR history
|
// SNR history
|
||||||
static constexpr int SNR_HISTORY_SIZE = 32;
|
static constexpr int SNR_HISTORY_SIZE = 32;
|
||||||
|
|
@ -1835,14 +1841,34 @@ private:
|
||||||
attroff(COLOR_PAIR(2) | A_BOLD);
|
attroff(COLOR_PAIR(2) | A_BOLD);
|
||||||
|
|
||||||
addstr(" ");
|
addstr(" ");
|
||||||
addstr("Err");
|
int syncs = state_.sync_count.load();
|
||||||
int errs = state_.rx_error_count.load();
|
int total_errors = state_.preamble_errors.load() +
|
||||||
if (errs > 0) {
|
state_.symbol_errors.load() +
|
||||||
attron(COLOR_PAIR(2));
|
state_.crc_errors.load() +
|
||||||
printw(" %d", errs);
|
state_.rx_error_count.load();
|
||||||
attroff(COLOR_PAIR(2));
|
if (syncs > 0) {
|
||||||
|
float err_pct = 100.0f * total_errors / syncs;
|
||||||
|
addstr("Err");
|
||||||
|
if (total_errors == 0) {
|
||||||
|
attron(COLOR_PAIR(1));
|
||||||
|
printw(" 0/%d", syncs);
|
||||||
|
attroff(COLOR_PAIR(1));
|
||||||
|
} else if (err_pct < 20.0f) {
|
||||||
|
attron(COLOR_PAIR(3));
|
||||||
|
printw(" %d/%d", total_errors, syncs);
|
||||||
|
attroff(COLOR_PAIR(3));
|
||||||
|
} else {
|
||||||
|
attron(COLOR_PAIR(2));
|
||||||
|
printw(" %d/%d", total_errors, syncs);
|
||||||
|
attroff(COLOR_PAIR(2));
|
||||||
|
}
|
||||||
|
attron(A_DIM);
|
||||||
|
printw(" (%.0f%%)", err_pct);
|
||||||
|
attroff(A_DIM);
|
||||||
} else {
|
} else {
|
||||||
printw(" %d", errs);
|
attron(A_DIM);
|
||||||
|
addstr("Err 0/0");
|
||||||
|
attroff(A_DIM);
|
||||||
}
|
}
|
||||||
y++;
|
y++;
|
||||||
|
|
||||||
|
|
@ -2742,6 +2768,55 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_log(int y, int h, int cols) {
|
void draw_log(int y, int h, int cols) {
|
||||||
|
// Decode stats header
|
||||||
|
int c1 = 3;
|
||||||
|
attron(A_DIM);
|
||||||
|
mvaddstr(y, c1, "DECODE STATS");
|
||||||
|
attroff(A_DIM);
|
||||||
|
y++;
|
||||||
|
|
||||||
|
int syncs = state_.sync_count.load();
|
||||||
|
int pre_err = state_.preamble_errors.load();
|
||||||
|
int sym_err = state_.symbol_errors.load();
|
||||||
|
int crc_err = state_.crc_errors.load();
|
||||||
|
int unframe_err = state_.rx_error_count.load();
|
||||||
|
int decoded = state_.rx_frame_count.load();
|
||||||
|
|
||||||
|
mvaddstr(y, c1, "Syncs");
|
||||||
|
attron(COLOR_PAIR(4));
|
||||||
|
printw(" %d", syncs);
|
||||||
|
attroff(COLOR_PAIR(4));
|
||||||
|
|
||||||
|
addstr(" Decoded");
|
||||||
|
attron(COLOR_PAIR(1));
|
||||||
|
printw(" %d", decoded);
|
||||||
|
attroff(COLOR_PAIR(1));
|
||||||
|
|
||||||
|
addstr(" CRC Fail");
|
||||||
|
if (crc_err > 0) attron(COLOR_PAIR(2));
|
||||||
|
printw(" %d", crc_err);
|
||||||
|
if (crc_err > 0) attroff(COLOR_PAIR(2));
|
||||||
|
|
||||||
|
addstr(" Seed Err");
|
||||||
|
if (sym_err > 0) attron(COLOR_PAIR(2));
|
||||||
|
printw(" %d", sym_err);
|
||||||
|
if (sym_err > 0) attroff(COLOR_PAIR(2));
|
||||||
|
|
||||||
|
addstr(" Pre Err");
|
||||||
|
if (pre_err > 0) attron(COLOR_PAIR(2));
|
||||||
|
printw(" %d", pre_err);
|
||||||
|
if (pre_err > 0) attroff(COLOR_PAIR(2));
|
||||||
|
|
||||||
|
if (unframe_err > 0) {
|
||||||
|
addstr(" Unframe");
|
||||||
|
attron(COLOR_PAIR(2));
|
||||||
|
printw(" %d", unframe_err);
|
||||||
|
attroff(COLOR_PAIR(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
y += 2;
|
||||||
|
h -= 3;
|
||||||
|
|
||||||
auto log = state_.get_log();
|
auto log = state_.get_log();
|
||||||
int visible = h - 1;
|
int visible = h - 1;
|
||||||
int max_scroll = std::max(0, (int)log.size() - visible);
|
int max_scroll = std::max(0, (int)log.size() - visible);
|
||||||
|
|
@ -2893,7 +2968,7 @@ private:
|
||||||
// Ensure at least 1 grid cell per display cell (prevents striping)
|
// Ensure at least 1 grid cell per display cell (prevents striping)
|
||||||
int gx_end = std::max(gx + 1, std::min((int)((dx + 1) * scale_x), grid_size));
|
int gx_end = std::max(gx + 1, std::min((int)((dx + 1) * scale_x), grid_size));
|
||||||
int gy_end = std::max(gy + 1, std::min((int)((dy + 1) * scale_y), grid_size));
|
int gy_end = std::max(gy + 1, std::min((int)((dy + 1) * scale_y), grid_size));
|
||||||
|
|
||||||
int density = 0;
|
int density = 0;
|
||||||
for (int sy = gy; sy < gy_end; ++sy) {
|
for (int sy = gy; sy < gy_end; ++sy) {
|
||||||
for (int sx = gx; sx < gx_end; ++sx) {
|
for (int sx = gx; sx < gx_end; ++sx) {
|
||||||
|
|
@ -3229,6 +3304,11 @@ private:
|
||||||
state_.rx_frame_count = 0;
|
state_.rx_frame_count = 0;
|
||||||
state_.tx_frame_count = 0;
|
state_.tx_frame_count = 0;
|
||||||
state_.rx_error_count = 0;
|
state_.rx_error_count = 0;
|
||||||
|
state_.sync_count = 0;
|
||||||
|
state_.preamble_errors = 0;
|
||||||
|
state_.symbol_errors = 0;
|
||||||
|
state_.crc_errors = 0;
|
||||||
|
state_.stats_reset_requested = true;
|
||||||
state_.total_tx_time = 0;
|
state_.total_tx_time = 0;
|
||||||
state_.add_log("S");
|
state_.add_log("S");
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue