Naming consistency + time slot display in decode_ft8

pull/37/head
Karlis Goba 2022-06-28 09:07:52 +03:00
rodzic 7dc84b972a
commit a28593682e
4 zmienionych plików z 37 dodań i 37 usunięć

Wyświetl plik

@ -32,7 +32,7 @@ void usage(const char* error_msg)
{
fprintf(stderr, "ERROR: %s\n", error_msg);
}
fprintf(stderr, "Usage: decode_ft8 [-list|-ft4] INPUT\n\n");
fprintf(stderr, "Usage: decode_ft8 [-list|([-ft4] [INPUT|-dev DEVICE])]\n\n");
fprintf(stderr, "Decode a 15-second (or slighly shorter) WAV file.\n");
}
@ -40,8 +40,8 @@ void usage(const char* error_msg)
static struct
{
char callsign[12];
uint32_t hash;
char callsign[12]; ///> Up to 11 symbols of callsign + trailing zeros (always filled)
uint32_t hash; ///> 8 MSBs contain the age of callsign; 22 LSBs contain hash value
} callsign_hashtable[CALLSIGN_HASHTABLE_SIZE];
static int callsign_hashtable_size;
@ -105,7 +105,7 @@ void hashtable_add(const char* callsign, uint32_t hash)
bool hashtable_lookup(ftx_callsign_hash_type_t hash_type, uint32_t hash, char* callsign)
{
uint8_t hash_shift = (hash_type == FTX_CALLSIGN_HASH_10_BITS) ? 12 : (hash_type == FTX_CALLSIGN_HASH_12_BITS ? 10 : 0);
uint16_t hash10 = (hash >> (12 - hash_shift)) & 0x3FF;
uint16_t hash10 = (hash >> (12 - hash_shift)) & 0x3FFu;
int idx_hash = (hash10 * 23) % CALLSIGN_HASHTABLE_SIZE;
while (callsign_hashtable[idx_hash].callsign[0] != '\0')
{
@ -126,12 +126,12 @@ ftx_callsign_hash_interface_t hash_if = {
.save_hash = hashtable_add
};
void decode(const monitor_t* mon)
void decode(const monitor_t* mon, struct tm* tm_slot_start)
{
const ftx_waterfall_t* wf = &mon->wf;
// Find top candidates by Costas sync score and localize them in time and frequency
ftx_candidate_t candidate_list[kMax_candidates];
int num_candidates = ft8_find_sync(wf, kMax_candidates, candidate_list, kMin_score);
int num_candidates = ftx_find_candidates(wf, kMax_candidates, candidate_list, kMin_score);
// Hash table for decoded messages (to check for duplicates)
int num_decoded = 0;
@ -154,10 +154,8 @@ void decode(const monitor_t* mon)
ftx_message_t message;
ftx_decode_status_t status;
if (!ft8_decode(wf, cand, kLDPC_iterations, &message, &status))
if (!ftx_decode_candidate(wf, cand, kLDPC_iterations, &message, &status))
{
// float snr = cand->score * 0.5f; // TODO: compute better approximation of SNR
// printf("000000 %2.1f %+4.2f %4.0f ~ %s\n", snr, time_sec, freq_hz, "---");
if (status.ldpc_errors > 0)
{
LOG(LOG_DEBUG, "LDPC decode: %d errors\n", status.ldpc_errors);
@ -201,25 +199,17 @@ void decode(const monitor_t* mon)
++num_decoded;
char text[FTX_MAX_MESSAGE_LENGTH];
// int unpack_status = unpack77(message.payload, text, NULL);
int unpack_status = ftx_message_decode(&message, &hash_if, text);
if (unpack_status != 0)
ftx_message_rc_t unpack_status = ftx_message_decode(&message, &hash_if, text);
if (unpack_status != FTX_MESSAGE_RC_OK)
{
strcpy(text, "Error while unpacking!");
snprintf(text, sizeof(text), "Error [%d] while unpacking!", (int)unpack_status);
}
// uint8_t i3 = ftx_message_get_i3(&message);
// if (i3 == 0)
// {
// uint8_t n3 = ftx_message_get_n3(&message);
// printf("000000 %02d %+4.2f %4.0f [%d.%d] ~ %s\n", cand->score, time_sec, freq_hz, i3, n3, text);
// }
// else
// printf("000000 %02d %+4.2f %4.0f [%d ] ~ %s\n", cand->score, time_sec, freq_hz, i3, text);
// Fake WSJT-X-like output for now
float snr = cand->score * 0.5f; // TODO: compute better approximation of SNR
printf("000000 %+05.1f %+4.2f %4.0f ~ %s\n", snr, time_sec, freq_hz, text);
printf("%02d%02d%02d %+05.1f %+4.2f %4.0f ~ %s\n",
tm_slot_start->tm_hour, tm_slot_start->tm_min, tm_slot_start->tm_sec,
snr, time_sec, freq_hz, text);
}
}
LOG(LOG_INFO, "Decoded %d messages, callsign hashtable size %d\n", num_decoded, callsign_hashtable_size);
@ -292,9 +282,9 @@ int main(int argc, char** argv)
return -1;
}
float slot_time = ((protocol == FTX_PROTOCOL_FT8) ? FT8_SLOT_TIME : FT4_SLOT_TIME);
float slot_period = ((protocol == FTX_PROTOCOL_FT8) ? FT8_SLOT_TIME : FT4_SLOT_TIME);
int sample_rate = 12000;
int num_samples = slot_time * sample_rate;
int num_samples = slot_period * sample_rate;
float signal[num_samples];
bool isContinuous = false;
@ -312,7 +302,7 @@ int main(int argc, char** argv)
{
audio_init();
audio_open(dev_name);
num_samples = (slot_time - 0.4f) * sample_rate;
num_samples = (slot_period - 0.4f) * sample_rate;
isContinuous = true;
}
@ -334,6 +324,7 @@ int main(int argc, char** argv)
do
{
struct tm tm_slot_start = { 0 };
if (dev_name != NULL)
{
// Wait for the start of time slot
@ -341,12 +332,18 @@ int main(int argc, char** argv)
{
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
float time_within_slot = fmod((double)spec.tv_sec + (spec.tv_nsec * 1e-9) - time_shift, slot_time);
if (time_within_slot > slot_time / 3)
double time = (double)spec.tv_sec + (spec.tv_nsec / 1e9);
double time_within_slot = fmod(time - time_shift, slot_period);
if (time_within_slot > slot_period / 4)
{
audio_read(signal, mon.block_size);
}
else
{
LOG(LOG_INFO, "Time within slot: %.3f s\n", time_within_slot);
time_t time_slot_start = (time_t)(time - time_within_slot);
gmtime_r(&time_slot_start, &tm_slot_start);
LOG(LOG_INFO, "Time within slot %02d%02d%02d: %.3f s\n", tm_slot_start.tm_hour,
tm_slot_start.tm_min, tm_slot_start.tm_sec, time_within_slot);
break;
}
}
@ -369,7 +366,7 @@ int main(int argc, char** argv)
LOG(LOG_INFO, "Max magnitude: %.1f dB\n", mon.max_mag);
// Decode accumulated data (containing slightly less than a full time slot)
decode(&mon);
decode(&mon, &tm_slot_start);
// Reset internal variables for the next time slot
monitor_reset(&mon);

Wyświetl plik

@ -229,7 +229,7 @@ static int ft4_sync_score(const ftx_waterfall_t* wf, const ftx_candidate_t* cand
return score;
}
int ft8_find_sync(const ftx_waterfall_t* wf, int num_candidates, ftx_candidate_t heap[], int min_score)
int ftx_find_candidates(const ftx_waterfall_t* wf, int num_candidates, ftx_candidate_t heap[], int min_score)
{
int heap_size = 0;
ftx_candidate_t candidate;
@ -377,7 +377,7 @@ static void ftx_normalize_logl(float* log174)
}
}
bool ft8_decode(const ftx_waterfall_t* wf, const ftx_candidate_t* cand, int max_iterations, ftx_message_t* message, ftx_decode_status_t* status)
bool ftx_decode_candidate(const ftx_waterfall_t* wf, const ftx_candidate_t* cand, int max_iterations, ftx_message_t* message, ftx_decode_status_t* status)
{
float log174[FTX_LDPC_N]; // message bits encoded as likelihood
if (wf->protocol == FTX_PROTOCOL_FT4)

Wyświetl plik

@ -59,7 +59,7 @@ typedef struct
/// @param[in,out] heap Array of ftx_candidate_t type entries (with num_candidates allocated entries)
/// @param[in] min_score Minimal score allowed for pruning unlikely candidates (can be zero for no effect)
/// @return Number of candidates filled in the heap
int ft8_find_sync(const ftx_waterfall_t* power, int num_candidates, ftx_candidate_t heap[], int min_score);
int ftx_find_candidates(const ftx_waterfall_t* power, int num_candidates, ftx_candidate_t heap[], int min_score);
/// Attempt to decode a message candidate. Extracts the bit probabilities, runs LDPC decoder, checks CRC and unpacks the message in plain text.
/// @param[in] power Waterfall data collected during message slot
@ -68,7 +68,7 @@ int ft8_find_sync(const ftx_waterfall_t* power, int num_candidates, ftx_candidat
/// @param[out] message ftx_message_t structure that will receive the decoded message
/// @param[out] status ftx_decode_status_t structure that will be filled with the status of various decoding steps
/// @return True if the decoding was successful, false otherwise (check status for details)
bool ft8_decode(const ftx_waterfall_t* power, const ftx_candidate_t* cand, int max_iterations, ftx_message_t* message, ftx_decode_status_t* status);
bool ftx_decode_candidate(const ftx_waterfall_t* power, const ftx_candidate_t* cand, int max_iterations, ftx_message_t* message, ftx_decode_status_t* status);
#ifdef __cplusplus
}

Wyświetl plik

@ -78,9 +78,12 @@ typedef enum
FTX_MESSAGE_RC_ERROR_TYPE
} ftx_message_rc_t;
// Basecall - 1-2 letter/digit prefix (at least one letter), 1 digit area code, 1-3 letter suffix, total 3-6 chars (except for 7 char 3DA0- and 3X- calls)
// Ext. basecall - basecall followed by /R or /P
// Nonstd. call - all the rest, limited to 3-11 characters either alphanumeric or stroke (/)
// Callsign types and sizes:
// * Std. call (basecall) - 1-2 letter/digit prefix (at least one letter), 1 digit area code, 1-3 letter suffix,
// total 3-6 chars (exception: 7 character calls with prefixes 3DA0- and 3XA..3XZ-)
// * Ext. std. call - basecall followed by /R or /P
// * Nonstd. call - all the rest, limited to 3-11 characters either alphanumeric or stroke (/)
// In case a call is looked up from its hash value, the call is enclosed in angular brackets (<CA0LL>).
void ftx_message_init(ftx_message_t* msg);