From 26decf92f73800c6faa36750332cdd62d9b260cc Mon Sep 17 00:00:00 2001 From: Karlis Goba Date: Wed, 17 Nov 2021 10:31:01 +0200 Subject: [PATCH] Added prefixes to ft8/ft4/ftx functions and clang-formatted code --- .clang-format | 31 ++++++++++++++++++++++++ Makefile | 4 ++-- common/wave.c | 64 ++++++++++++++++++++++++------------------------- common/wave.h | 4 ++-- decode_ft8.c | 21 ++++++++-------- ft8/constants.h | 14 +++++------ ft8/crc.c | 8 +++---- ft8/crc.h | 12 +++++----- ft8/decode.c | 62 ++++++++++++++++++++++++++++++++++++----------- ft8/decode.h | 22 ++++++++--------- ft8/encode.c | 28 +++++++++++----------- ft8/encode.h | 4 ++-- ft8/ldpc.c | 31 ++---------------------- ft8/ldpc.h | 8 ++----- ft8/pack.c | 44 ++++++++++++++++------------------ ft8/pack.h | 2 +- ft8/text.c | 20 ++++++++-------- ft8/text.h | 18 +++++++------- ft8/unpack.c | 44 +++++++++++++++++----------------- ft8/unpack.h | 4 ++-- gen_ft8.c | 28 +++++++++++----------- test.c | 10 ++++---- 22 files changed, 258 insertions(+), 225 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..3b11ab3 --- /dev/null +++ b/.clang-format @@ -0,0 +1,31 @@ +BasedOnStyle: WebKit +# Cpp11BracedListStyle: false +# ColumnLimit: 120 +IndentCaseLabels: false +IndentWidth: 4 +TabWidth: 8 +UseTab: Never +PointerAlignment: Left +SortIncludes: false +AlignConsecutiveMacros: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +BreakConstructorInitializers: BeforeColon +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 0 +BreakBeforeBraces: Custom +BreakBeforeBinaryOperators: All +BraceWrapping: + AfterControlStatement: true + AfterClass: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeElse: true + BeforeCatch: true diff --git a/Makefile b/Makefile index 57299b1..563292e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -CFLAGS = -O3 +CFLAGS = -O3 -ggdb3 -fsanitize=address CPPFLAGS = -std=c11 -I. -LDFLAGS = -lm +LDFLAGS = -lm -fsanitize=address TARGETS = gen_ft8 decode_ft8 test diff --git a/common/wave.c b/common/wave.c index a54b5ca..e02757f 100644 --- a/common/wave.c +++ b/common/wave.c @@ -7,25 +7,25 @@ #include // Save signal in floating point format (-1 .. +1) as a WAVE file using 16-bit signed integers. -void save_wav(const float *signal, int num_samples, int sample_rate, const char *path) +void save_wav(const float* signal, int num_samples, int sample_rate, const char* path) { - char subChunk1ID[4] = {'f', 'm', 't', ' '}; + char subChunk1ID[4] = { 'f', 'm', 't', ' ' }; uint32_t subChunk1Size = 16; // 16 for PCM - uint16_t audioFormat = 1; // PCM = 1 + uint16_t audioFormat = 1; // PCM = 1 uint16_t numChannels = 1; uint16_t bitsPerSample = 16; uint32_t sampleRate = sample_rate; uint16_t blockAlign = numChannels * bitsPerSample / 8; uint32_t byteRate = sampleRate * blockAlign; - char subChunk2ID[4] = {'d', 'a', 't', 'a'}; + char subChunk2ID[4] = { 'd', 'a', 't', 'a' }; uint32_t subChunk2Size = num_samples * blockAlign; - char chunkID[4] = {'R', 'I', 'F', 'F'}; + char chunkID[4] = { 'R', 'I', 'F', 'F' }; uint32_t chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size); - char format[4] = {'W', 'A', 'V', 'E'}; + char format[4] = { 'W', 'A', 'V', 'E' }; - int16_t *raw_data = (int16_t *)malloc(num_samples * blockAlign); + int16_t* raw_data = (int16_t*)malloc(num_samples * blockAlign); for (int i = 0; i < num_samples; i++) { float x = signal[i]; @@ -36,7 +36,7 @@ void save_wav(const float *signal, int num_samples, int sample_rate, const char raw_data[i] = (int)(0.5 + (x * 32767.0)); } - FILE *f = fopen(path, "wb"); + FILE* f = fopen(path, "wb"); // NOTE: works only on little-endian architecture fwrite(chunkID, sizeof(chunkID), 1, f); @@ -63,48 +63,48 @@ void save_wav(const float *signal, int num_samples, int sample_rate, const char } // Load signal in floating point format (-1 .. +1) as a WAVE file using 16-bit signed integers. -int load_wav(float *signal, int *num_samples, int *sample_rate, const char *path) +int load_wav(float* signal, int* num_samples, int* sample_rate, const char* path) { - char subChunk1ID[4]; // = {'f', 'm', 't', ' '}; + char subChunk1ID[4]; // = {'f', 'm', 't', ' '}; uint32_t subChunk1Size; // = 16; // 16 for PCM - uint16_t audioFormat; // = 1; // PCM = 1 - uint16_t numChannels; // = 1; + uint16_t audioFormat; // = 1; // PCM = 1 + uint16_t numChannels; // = 1; uint16_t bitsPerSample; // = 16; uint32_t sampleRate; uint16_t blockAlign; // = numChannels * bitsPerSample / 8; - uint32_t byteRate; // = sampleRate * blockAlign; + uint32_t byteRate; // = sampleRate * blockAlign; - char subChunk2ID[4]; // = {'d', 'a', 't', 'a'}; + char subChunk2ID[4]; // = {'d', 'a', 't', 'a'}; uint32_t subChunk2Size; // = num_samples * blockAlign; - char chunkID[4]; // = {'R', 'I', 'F', 'F'}; + char chunkID[4]; // = {'R', 'I', 'F', 'F'}; uint32_t chunkSize; // = 4 + (8 + subChunk1Size) + (8 + subChunk2Size); - char format[4]; // = {'W', 'A', 'V', 'E'}; + char format[4]; // = {'W', 'A', 'V', 'E'}; - FILE *f = fopen(path, "rb"); + FILE* f = fopen(path, "rb"); // NOTE: works only on little-endian architecture - fread((void *)chunkID, sizeof(chunkID), 1, f); - fread((void *)&chunkSize, sizeof(chunkSize), 1, f); - fread((void *)format, sizeof(format), 1, f); + fread((void*)chunkID, sizeof(chunkID), 1, f); + fread((void*)&chunkSize, sizeof(chunkSize), 1, f); + fread((void*)format, sizeof(format), 1, f); - fread((void *)subChunk1ID, sizeof(subChunk1ID), 1, f); - fread((void *)&subChunk1Size, sizeof(subChunk1Size), 1, f); + fread((void*)subChunk1ID, sizeof(subChunk1ID), 1, f); + fread((void*)&subChunk1Size, sizeof(subChunk1Size), 1, f); if (subChunk1Size != 16) return -1; - fread((void *)&audioFormat, sizeof(audioFormat), 1, f); - fread((void *)&numChannels, sizeof(numChannels), 1, f); - fread((void *)&sampleRate, sizeof(sampleRate), 1, f); - fread((void *)&byteRate, sizeof(byteRate), 1, f); - fread((void *)&blockAlign, sizeof(blockAlign), 1, f); - fread((void *)&bitsPerSample, sizeof(bitsPerSample), 1, f); + fread((void*)&audioFormat, sizeof(audioFormat), 1, f); + fread((void*)&numChannels, sizeof(numChannels), 1, f); + fread((void*)&sampleRate, sizeof(sampleRate), 1, f); + fread((void*)&byteRate, sizeof(byteRate), 1, f); + fread((void*)&blockAlign, sizeof(blockAlign), 1, f); + fread((void*)&bitsPerSample, sizeof(bitsPerSample), 1, f); if (audioFormat != 1 || numChannels != 1 || bitsPerSample != 16) return -1; - fread((void *)subChunk2ID, sizeof(subChunk2ID), 1, f); - fread((void *)&subChunk2Size, sizeof(subChunk2Size), 1, f); + fread((void*)subChunk2ID, sizeof(subChunk2ID), 1, f); + fread((void*)&subChunk2Size, sizeof(subChunk2Size), 1, f); if (subChunk2Size / blockAlign > *num_samples) return -2; @@ -112,9 +112,9 @@ int load_wav(float *signal, int *num_samples, int *sample_rate, const char *path *num_samples = subChunk2Size / blockAlign; *sample_rate = sampleRate; - int16_t *raw_data = (int16_t *)malloc(*num_samples * blockAlign); + int16_t* raw_data = (int16_t*)malloc(*num_samples * blockAlign); - fread((void *)raw_data, blockAlign, *num_samples, f); + fread((void*)raw_data, blockAlign, *num_samples, f); for (int i = 0; i < *num_samples; i++) { signal[i] = raw_data[i] / 32768.0f; diff --git a/common/wave.h b/common/wave.h index 2dfee74..def1296 100644 --- a/common/wave.h +++ b/common/wave.h @@ -2,9 +2,9 @@ #define _INCLUDE_WAVE_H_ // Save signal in floating point format (-1 .. +1) as a WAVE file using 16-bit signed integers. -void save_wav(const float *signal, int num_samples, int sample_rate, const char *path); +void save_wav(const float* signal, int num_samples, int sample_rate, const char* path); // Load signal in floating point format (-1 .. +1) as a WAVE file using 16-bit signed integers. -int load_wav(float *signal, int *num_samples, int *sample_rate, const char *path); +int load_wav(float* signal, int* num_samples, int* sample_rate, const char* path); #endif // _INCLUDE_WAVE_H_ diff --git a/decode_ft8.c b/decode_ft8.c index cac66b2..7e0dda4 100644 --- a/decode_ft8.c +++ b/decode_ft8.c @@ -68,7 +68,7 @@ static float max2(float a, float b) } // Compute FFT magnitudes (log power) for each timeslot in the signal -void extract_power(const float signal[], waterfall_t *power, int block_size) +void extract_power(const float signal[], waterfall_t* power, int block_size) { const int subblock_size = block_size / power->time_osr; const int nfft = block_size * power->freq_osr; @@ -93,7 +93,7 @@ void extract_power(const float signal[], waterfall_t *power, int block_size) LOG(LOG_INFO, "N_FFT = %d\n", nfft); LOG(LOG_INFO, "FFT work area = %lu\n", fft_work_size); - void *fft_work = malloc(fft_work_size); + void* fft_work = malloc(fft_work_size); kiss_fftr_cfg fft_cfg = kiss_fftr_alloc(nfft, 0, fft_work, &fft_work_size); int offset = 0; @@ -146,7 +146,7 @@ void extract_power(const float signal[], waterfall_t *power, int block_size) free(fft_work); } -int main(int argc, char **argv) +int main(int argc, char** argv) { // Expect one command-line argument if (argc < 2) @@ -155,7 +155,7 @@ int main(int argc, char **argv) return -1; } - const char *wav_path = argv[1]; + const char* wav_path = argv[1]; int sample_rate = 12000; int num_samples = 15 * sample_rate; @@ -169,7 +169,7 @@ int main(int argc, char **argv) // Compute DSP parameters that depend on the sample rate const int num_bins = (int)(sample_rate / (2 * kFSK_dev)); // number bins of FSK tone width that the spectrum can be divided into - const int block_size = (int)(sample_rate / kFSK_dev); // samples corresponding to one FSK symbol + const int block_size = (int)(sample_rate / kFSK_dev); // samples corresponding to one FSK symbol const int subblock_size = block_size / kTime_osr; const int nfft = block_size * kFreq_osr; const int num_blocks = (num_samples - nfft + subblock_size) / block_size; @@ -183,17 +183,18 @@ int main(int argc, char **argv) .num_bins = num_bins, .time_osr = kTime_osr, .freq_osr = kFreq_osr, - .mag = mag_power}; + .mag = mag_power + }; extract_power(signal, &power, block_size); // Find top candidates by Costas sync score and localize them in time and frequency candidate_t candidate_list[kMax_candidates]; - int num_candidates = find_sync(&power, kMax_candidates, candidate_list, kMin_score); + int num_candidates = ft8_find_sync(&power, kMax_candidates, candidate_list, kMin_score); // Hash table for decoded messages (to check for duplicates) int num_decoded = 0; message_t decoded[kMax_decoded_messages]; - message_t *decoded_hashtable[kMax_decoded_messages]; + message_t* decoded_hashtable[kMax_decoded_messages]; // Initialize hash table pointers for (int i = 0; i < kMax_decoded_messages; ++i) @@ -204,7 +205,7 @@ int main(int argc, char **argv) // Go over candidates and attempt to decode messages for (int idx = 0; idx < num_candidates; ++idx) { - const candidate_t *cand = &candidate_list[idx]; + const candidate_t* cand = &candidate_list[idx]; if (cand->score < kMin_score) continue; @@ -213,7 +214,7 @@ int main(int argc, char **argv) message_t message; decode_status_t status; - if (!decode(&power, cand, &message, kLDPC_iterations, &status)) + if (!ft8_decode(&power, cand, &message, kLDPC_iterations, &status)) { if (status.ldpc_errors > 0) { diff --git a/ft8/constants.h b/ft8/constants.h index 0e8a3a7..d595cc7 100644 --- a/ft8/constants.h +++ b/ft8/constants.h @@ -9,21 +9,21 @@ #define FT8_NN (79) ///< Total channel symbols (FT8_NS + FT8_ND) // Define FT4 symbol counts -#define FT4_ND (87) ///< Data symbols -#define FT4_NS (16) ///< Sync symbols (3 @ Costas 7x7) -#define FT4_NR (2) ///< Ramp symbols (beginning + end) +#define FT4_ND (87) ///< Data symbols +#define FT4_NS (16) ///< Sync symbols (3 @ Costas 7x7) +#define FT4_NR (2) ///< Ramp symbols (beginning + end) #define FT4_NN (105) ///< Total channel symbols (FT4_NS + FT4_ND + FT4_NR) // Define LDPC parameters -#define FT8_LDPC_N (174) ///< Number of bits in the encoded message (payload with LDPC checksum bits) -#define FT8_LDPC_K (91) ///< Number of payload bits (including CRC) -#define FT8_LDPC_M (83) ///< Number of LDPC checksum bits (FT8_LDPC_N - FT8_LDPC_K) +#define FT8_LDPC_N (174) ///< Number of bits in the encoded message (payload with LDPC checksum bits) +#define FT8_LDPC_K (91) ///< Number of payload bits (including CRC) +#define FT8_LDPC_M (83) ///< Number of LDPC checksum bits (FT8_LDPC_N - FT8_LDPC_K) #define FT8_LDPC_N_BYTES ((FT8_LDPC_N + 7) / 8) ///< Number of whole bytes needed to store 174 bits (full message) #define FT8_LDPC_K_BYTES ((FT8_LDPC_K + 7) / 8) ///< Number of whole bytes needed to store 91 bits (payload + CRC only) // Define CRC parameters #define FT8_CRC_POLYNOMIAL ((uint16_t)0x2757u) ///< CRC-14 polynomial without the leading (MSB) 1 -#define FT8_CRC_WIDTH (14) +#define FT8_CRC_WIDTH (14) /// Costas 7x7 tone pattern for synchronization extern const uint8_t kFT8_Costas_pattern[7]; diff --git a/ft8/crc.c b/ft8/crc.c index 393c42e..72a4c89 100644 --- a/ft8/crc.c +++ b/ft8/crc.c @@ -7,7 +7,7 @@ // Adapted from https://barrgroup.com/Embedded-Systems/How-To/CRC-Calculation-C-Code // [IN] message - byte sequence (MSB first) // [IN] num_bits - number of bits in the sequence -uint16_t ft8_crc(const uint8_t message[], int num_bits) +uint16_t ftx_compute_crc(const uint8_t message[], int num_bits) { uint16_t remainder = 0; int idx_byte = 0; @@ -36,13 +36,13 @@ uint16_t ft8_crc(const uint8_t message[], int num_bits) return remainder & ((TOPBIT << 1) - 1u); } -uint16_t extract_crc(const uint8_t a91[]) +uint16_t ftx_extract_crc(const uint8_t a91[]) { uint16_t chksum = ((a91[9] & 0x07) << 11) | (a91[10] << 3) | (a91[11] >> 5); return chksum; } -void add_crc(const uint8_t payload[], uint8_t a91[]) +void ftx_add_crc(const uint8_t payload[], uint8_t a91[]) { // Copy 77 bits of payload data for (int i = 0; i < 10; i++) @@ -54,7 +54,7 @@ void add_crc(const uint8_t payload[], uint8_t a91[]) // Calculate CRC of 82 bits (77 + 5 zeros) // 'The CRC is calculated on the source-encoded message, zero-extended from 77 to 82 bits' - uint16_t checksum = ft8_crc(a91, 96 - 14); + uint16_t checksum = ftx_compute_crc(a91, 96 - 14); // Store the CRC at the end of 77 bit message a91[9] |= (uint8_t)(checksum >> 11); diff --git a/ft8/crc.h b/ft8/crc.h index 2e92293..b510122 100644 --- a/ft8/crc.h +++ b/ft8/crc.h @@ -4,19 +4,19 @@ #include #include -// Compute 14-bit CRC for a sequence of given number of bits +// Compute 14-bit CRC for a sequence of given number of bits using FT8/FT4 CRC polynomial // [IN] message - byte sequence (MSB first) // [IN] num_bits - number of bits in the sequence -uint16_t ft8_crc(const uint8_t message[], int num_bits); +uint16_t ftx_compute_crc(const uint8_t message[], int num_bits); -/// Extract the FT8 CRC of a packed message (during decoding) +/// Extract the FT8/FT4 CRC of a packed message (during decoding) /// @param[in] a91 77 bits of payload data + CRC /// @return Extracted CRC -uint16_t extract_crc(const uint8_t a91[]); +uint16_t ftx_extract_crc(const uint8_t a91[]); -/// Add the FT8 CRC to a packed message (during encoding) +/// Add FT8/FT4 CRC to a packed message (during encoding) /// @param[in] payload 77 bits of payload data /// @param[out] a91 91 bits of payload data + CRC -void add_crc(const uint8_t payload[], uint8_t a91[]); +void ftx_add_crc(const uint8_t payload[], uint8_t a91[]); #endif // _INCLUDE_CRC_H_ \ No newline at end of file diff --git a/ft8/decode.c b/ft8/decode.c index de3c986..2ac600f 100644 --- a/ft8/decode.c +++ b/ft8/decode.c @@ -12,21 +12,28 @@ /// @param[in] cand Candidate to extract the message from /// @param[in] code_map Symbol encoding map /// @param[out] log174 Output of decoded log likelihoods for each of the 174 message bits -static void extract_likelihood(const waterfall_t *power, const candidate_t *cand, float *log174); +static void ft8_extract_likelihood(const waterfall_t* power, const candidate_t* cand, float* log174); + +/// Packs a string of bits each represented as a zero/non-zero byte in bit_array[], +/// as a string of packed bits starting from the MSB of the first byte of packed[] +/// @param[in] plain Array of bits (0 and nonzero values) with num_bits entires +/// @param[in] num_bits Number of bits (entries) passed in bit_array +/// @param[out] packed Byte-packed bits representing the data in bit_array +static void pack_bits(const uint8_t bit_array[], int num_bits, uint8_t packed[]); static float max2(float a, float b); static float max4(float a, float b, float c, float d); static void heapify_down(candidate_t heap[], int heap_size); static void heapify_up(candidate_t heap[], int heap_size); -static void decode_symbol(const uint8_t *power, int bit_idx, float *log174); -static void decode_multi_symbols(const uint8_t *power, int num_bins, int n_syms, int bit_idx, float *log174); +static void decode_symbol(const uint8_t* power, int bit_idx, float* log174); +static void decode_multi_symbols(const uint8_t* power, int num_bins, int n_syms, int bit_idx, float* log174); -static int get_index(const waterfall_t *power, int block, int time_sub, int freq_sub, int bin) +static int get_index(const waterfall_t* power, int block, int time_sub, int freq_sub, int bin) { return ((((block * power->time_osr) + time_sub) * power->freq_osr + freq_sub) * power->num_bins) + bin; } -int find_sync(const waterfall_t *power, int num_candidates, candidate_t heap[], int min_score) +int ft8_find_sync(const waterfall_t* power, int num_candidates, candidate_t heap[], int min_score) { int heap_size = 0; int sym_stride = power->time_osr * power->freq_osr * power->num_bins; @@ -58,7 +65,7 @@ int find_sync(const waterfall_t *power, int num_candidates, candidate_t heap[], break; int offset = get_index(power, block, time_sub, freq_sub, freq_offset); - const uint8_t *p8 = power->mag + offset; + const uint8_t* p8 = power->mag + offset; // Weighted difference between the expected and all other symbols // Does not work as well as the alternative score below @@ -143,7 +150,7 @@ int find_sync(const waterfall_t *power, int num_candidates, candidate_t heap[], return heap_size; } -void extract_likelihood(const waterfall_t *power, const candidate_t *cand, float *log174) +void ft8_extract_likelihood(const waterfall_t* power, const candidate_t* cand, float* log174) { int sym_stride = power->time_osr * power->freq_osr * power->num_bins; int offset = get_index(power, cand->time_offset, cand->time_sub, cand->freq_sub, cand->freq_offset); @@ -168,7 +175,7 @@ void extract_likelihood(const waterfall_t *power, const candidate_t *cand, float else { // Pointer to 8 bins of the current symbol - const uint8_t *ps = power->mag + offset + (sym_idx * sym_stride); + const uint8_t* ps = power->mag + offset + (sym_idx * sym_stride); decode_symbol(ps, bit_idx, log174); } @@ -193,10 +200,10 @@ void extract_likelihood(const waterfall_t *power, const candidate_t *cand, float } } -bool decode(const waterfall_t *power, const candidate_t *cand, message_t *message, int max_iterations, decode_status_t *status) +bool ft8_decode(const waterfall_t* power, const candidate_t* cand, message_t* message, int max_iterations, decode_status_t* status) { float log174[FT8_LDPC_N]; // message bits encoded as likelihood - extract_likelihood(power, cand, log174); + ft8_extract_likelihood(power, cand, log174); uint8_t plain174[FT8_LDPC_N]; // message bits (0/1) bp_decode(log174, max_iterations, plain174, &status->ldpc_errors); @@ -212,11 +219,11 @@ bool decode(const waterfall_t *power, const candidate_t *cand, message_t *messag pack_bits(plain174, FT8_LDPC_K, a91); // Extract CRC and check it - status->crc_extracted = extract_crc(a91); + status->crc_extracted = ftx_extract_crc(a91); // [1]: 'The CRC is calculated on the source-encoded message, zero-extended from 77 to 82 bits.' a91[9] &= 0xF8; a91[10] &= 0x00; - status->crc_calculated = ft8_crc(a91, 96 - 14); + status->crc_calculated = ftx_compute_crc(a91, 96 - 14); if (status->crc_extracted != status->crc_calculated) { @@ -296,7 +303,7 @@ static void heapify_up(candidate_t heap[], int heap_size) } // Compute unnormalized log likelihood log(p(1) / p(0)) of 3 message bits (1 FSK symbol) -static void decode_symbol(const uint8_t *power, int bit_idx, float *log174) +static void decode_symbol(const uint8_t* power, int bit_idx, float* log174) { // Cleaned up code for the simple case of n_syms==1 float s2[8]; @@ -312,7 +319,7 @@ static void decode_symbol(const uint8_t *power, int bit_idx, float *log174) } // Compute unnormalized log likelihood log(p(1) / p(0)) of bits corresponding to several FSK symbols at once -static void decode_multi_symbols(const uint8_t *power, int num_bins, int n_syms, int bit_idx, float *log174) +static void decode_multi_symbols(const uint8_t* power, int num_bins, int n_syms, int bit_idx, float* log174) { const int n_bits = 3 * n_syms; const int n_tones = (1 << n_bits); @@ -367,3 +374,30 @@ static void decode_multi_symbols(const uint8_t *power, int num_bins, int n_syms, log174[bit_idx + i] = max_one - max_zero; } } + +// Packs a string of bits each represented as a zero/non-zero byte in plain[], +// as a string of packed bits starting from the MSB of the first byte of packed[] +static void pack_bits(const uint8_t bit_array[], int num_bits, uint8_t packed[]) +{ + int num_bytes = (num_bits + 7) / 8; + for (int i = 0; i < num_bytes; ++i) + { + packed[i] = 0; + } + + uint8_t mask = 0x80; + int byte_idx = 0; + for (int i = 0; i < num_bits; ++i) + { + if (bit_array[i]) + { + packed[byte_idx] |= mask; + } + mask >>= 1; + if (!mask) + { + mask = 0x80; + ++byte_idx; + } + } +} \ No newline at end of file diff --git a/ft8/decode.h b/ft8/decode.h index 3f7dd62..7d960eb 100644 --- a/ft8/decode.h +++ b/ft8/decode.h @@ -4,7 +4,7 @@ #include #include -/// Input structure to find_sync() function. This structure describes stored waterfall data over the whole message slot. +/// Input structure to ft8_find_sync() function. This structure describes stored waterfall data over the whole message slot. /// Fields time_osr and freq_osr specify additional oversampling rate for time and frequency resolution. /// If time_osr=1, FFT magnitude data is collected once for every symbol transmitted, i.e. every 1/6.25 = 0.16 seconds. /// Values time_osr > 1 mean each symbol is further subdivided in time. @@ -13,21 +13,21 @@ typedef struct { int num_blocks; ///< number of total blocks (symbols) in terms of 160 ms time periods - int num_bins; ///< number of FFT bins in terms of 6.25 Hz - int time_osr; ///< number of time subdivisions - int freq_osr; ///< number of frequency subdivisions - uint8_t *mag; ///< FFT magnitudes stored as uint8_t[blocks][time_osr][freq_osr][num_bins] + int num_bins; ///< number of FFT bins in terms of 6.25 Hz + int time_osr; ///< number of time subdivisions + int freq_osr; ///< number of frequency subdivisions + uint8_t* mag; ///< FFT magnitudes stored as uint8_t[blocks][time_osr][freq_osr][num_bins] } waterfall_t; -/// Output structure of find_sync() and input structure of extract_likelihood(). +/// Output structure of ft8_find_sync() and input structure of ft8_decode(). /// Holds the position of potential start of a message in time and frequency. typedef struct { - int16_t score; ///< Candidate score (non-negative number; higher score means higher likelihood) + int16_t score; ///< Candidate score (non-negative number; higher score means higher likelihood) int16_t time_offset; ///< Index of the time block int16_t freq_offset; ///< Index of the frequency bin - uint8_t time_sub; ///< Index of the time subdivision used - uint8_t freq_sub; ///< Index of the frequency subdivision used + uint8_t time_sub; ///< Index of the time subdivision used + uint8_t freq_sub; ///< Index of the frequency subdivision used } candidate_t; /// Structure that holds the decoded message @@ -55,7 +55,7 @@ typedef struct /// @param[in,out] heap Array of 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 find_sync(const waterfall_t *power, int num_candidates, candidate_t heap[], int min_score); +int ft8_find_sync(const waterfall_t* power, int num_candidates, 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 @@ -64,6 +64,6 @@ int find_sync(const waterfall_t *power, int num_candidates, candidate_t heap[], /// @param[in] max_iterations Maximum allowed LDPC iterations (lower number means faster decode, but less precise) /// @param[out] status 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 decode(const waterfall_t *power, const candidate_t *cand, message_t *message, int max_iterations, decode_status_t *status); +bool ft8_decode(const waterfall_t* power, const candidate_t* cand, message_t* message, int max_iterations, decode_status_t* status); #endif // _INCLUDE_DECODE_H_ diff --git a/ft8/encode.c b/ft8/encode.c index b0e051f..7edd7c0 100644 --- a/ft8/encode.c +++ b/ft8/encode.c @@ -5,21 +5,21 @@ #include // Returns 1 if an odd number of bits are set in x, zero otherwise -uint8_t parity8(uint8_t x) +static uint8_t parity8(uint8_t x) { - x ^= x >> 4; // a b c d ae bf cg dh - x ^= x >> 2; // a b ac bd cae dbf aecg bfdh - x ^= x >> 1; // a ab bac acbd bdcae caedbf aecgbfdh + x ^= x >> 4; // a b c d ae bf cg dh + x ^= x >> 2; // a b ac bd cae dbf aecg bfdh + x ^= x >> 1; // a ab bac acbd bdcae caedbf aecgbfdh return x % 2; // modulo 2 } -// Encode a 91-bit message and return a 174-bit codeword. +// Encode via LDPC a 91-bit message and return a 174-bit codeword. // The generator matrix has dimensions (87,87). // The code is a (174,91) regular LDPC code with column weight 3. // Arguments: // [IN] message - array of 91 bits stored as 12 bytes (MSB first) // [OUT] codeword - array of 174 bits stored as 22 bytes (MSB first) -void encode174(const uint8_t *message, uint8_t *codeword) +static void encode174(const uint8_t* message, uint8_t* codeword) { // This implementation accesses the generator bits straight from the packed binary representation in kFT8_LDPC_generator @@ -31,7 +31,7 @@ void encode174(const uint8_t *message, uint8_t *codeword) // Compute the byte index and bit mask for the first checksum bit uint8_t col_mask = (0x80u >> (FT8_LDPC_K % 8u)); // bitmask of current byte - uint8_t col_idx = FT8_LDPC_K_BYTES - 1; // index into byte array + uint8_t col_idx = FT8_LDPC_K_BYTES - 1; // index into byte array // Compute the LDPC checksum bits and store them in codeword for (int i = 0; i < FT8_LDPC_M; ++i) @@ -43,7 +43,7 @@ void encode174(const uint8_t *message, uint8_t *codeword) for (int j = 0; j < FT8_LDPC_K_BYTES; ++j) { uint8_t bits = message[j] & kFT8_LDPC_generator[i][j]; // bitwise AND (bitwise multiplication) - nsum ^= parity8(bits); // bitwise XOR (addition modulo 2) + nsum ^= parity8(bits); // bitwise XOR (addition modulo 2) } // Set the current checksum bit in codeword if nsum is odd @@ -62,13 +62,13 @@ void encode174(const uint8_t *message, uint8_t *codeword) } } -void genft8(const uint8_t *payload, uint8_t *tones) +void ft8_encode(const uint8_t* payload, uint8_t* tones) { uint8_t a91[12]; // Store 77 bits of payload + 14 bits CRC // Compute and add CRC at the end of the message // a91 contains 77 bits of payload + 14 bits of CRC - add_crc(payload, a91); + ftx_add_crc(payload, a91); uint8_t codeword[22]; encode174(a91, codeword); @@ -77,7 +77,7 @@ void genft8(const uint8_t *payload, uint8_t *tones) // Total symbols: 79 (FT8_NN) uint8_t mask = 0x80u; // Mask to extract 1 bit from codeword - int i_byte = 0; // Index of the current byte of the codeword + int i_byte = 0; // Index of the current byte of the codeword for (int i_tone = 0; i_tone < FT8_NN; ++i_tone) { if ((i_tone >= 0) && (i_tone < 7)) @@ -124,13 +124,13 @@ void genft8(const uint8_t *payload, uint8_t *tones) } } -void genft4(const uint8_t *payload, uint8_t *tones) +void ft4_encode(const uint8_t* payload, uint8_t* tones) { uint8_t a91[12]; // Store 77 bits of payload + 14 bits CRC // Compute and add CRC at the end of the message // a91 contains 77 bits of payload + 14 bits of CRC - add_crc(payload, a91); + ftx_add_crc(payload, a91); uint8_t codeword[22]; encode174(a91, codeword); // 91 bits -> 174 bits @@ -139,7 +139,7 @@ void genft4(const uint8_t *payload, uint8_t *tones) // Total symbols: 105 (FT4_NN) uint8_t mask = 0x80u; // Mask to extract 1 bit from codeword - int i_byte = 0; // Index of the current byte of the codeword + int i_byte = 0; // Index of the current byte of the codeword for (int i_tone = 0; i_tone < FT4_NN; ++i_tone) { if ((i_tone == 0) || (i_tone == 104)) diff --git a/ft8/encode.h b/ft8/encode.h index 410c89a..d5e2759 100644 --- a/ft8/encode.h +++ b/ft8/encode.h @@ -22,11 +22,11 @@ /// Generate FT8 tone sequence from payload data /// @param[in] payload - 10 byte array consisting of 77 bit payload /// @param[out] tones - array of FT8_NN (79) bytes to store the generated tones (encoded as 0..7) -void genft8(const uint8_t *payload, uint8_t *tones); +void ft8_encode(const uint8_t* payload, uint8_t* tones); /// Generate FT4 tone sequence from payload data /// @param[in] payload - 10 byte array consisting of 77 bit payload /// @param[out] tones - array of FT4_NN (105) bytes to store the generated tones (encoded as 0..3) -void genft4(const uint8_t *payload, uint8_t *tones); +void ft4_encode(const uint8_t* payload, uint8_t* tones); #endif // _INCLUDE_ENCODE_H_ diff --git a/ft8/ldpc.c b/ft8/ldpc.c index 42e58dd..9299dc9 100644 --- a/ft8/ldpc.c +++ b/ft8/ldpc.c @@ -21,38 +21,11 @@ static int ldpc_check(uint8_t codeword[]); static float fast_tanh(float x); static float fast_atanh(float x); -// Packs a string of bits each represented as a zero/non-zero byte in plain[], -// as a string of packed bits starting from the MSB of the first byte of packed[] -void pack_bits(const uint8_t plain[], int num_bits, uint8_t packed[]) -{ - int num_bytes = (num_bits + 7) / 8; - for (int i = 0; i < num_bytes; ++i) - { - packed[i] = 0; - } - - uint8_t mask = 0x80; - int byte_idx = 0; - for (int i = 0; i < num_bits; ++i) - { - if (plain[i]) - { - packed[byte_idx] |= mask; - } - mask >>= 1; - if (!mask) - { - mask = 0x80; - ++byte_idx; - } - } -} - // codeword is 174 log-likelihoods. // plain is a return value, 174 ints, to be 0 or 1. // max_iters is how hard to try. // ok == 87 means success. -void ldpc_decode(float codeword[], int max_iters, uint8_t plain[], int *ok) +void ldpc_decode(float codeword[], int max_iters, uint8_t plain[], int* ok) { float m[FT8_LDPC_M][FT8_LDPC_N]; // ~60 kB float e[FT8_LDPC_M][FT8_LDPC_N]; // ~60 kB @@ -154,7 +127,7 @@ static int ldpc_check(uint8_t codeword[]) return errors; } -void bp_decode(float codeword[], int max_iters, uint8_t plain[], int *ok) +void bp_decode(float codeword[], int max_iters, uint8_t plain[], int* ok) { float tov[FT8_LDPC_N][3]; float toc[FT8_LDPC_M][7]; diff --git a/ft8/ldpc.h b/ft8/ldpc.h index e726589..fd33d7a 100644 --- a/ft8/ldpc.h +++ b/ft8/ldpc.h @@ -7,12 +7,8 @@ // plain is a return value, 174 ints, to be 0 or 1. // iters is how hard to try. // ok == 87 means success. -void ldpc_decode(float codeword[], int max_iters, uint8_t plain[], int *ok); +void ldpc_decode(float codeword[], int max_iters, uint8_t plain[], int* ok); -void bp_decode(float codeword[], int max_iters, uint8_t plain[], int *ok); - -// Packs a string of bits each represented as a zero/non-zero byte in plain[], -// as a string of packed bits starting from the MSB of the first byte of packed[] -void pack_bits(const uint8_t plain[], int num_bits, uint8_t packed[]); +void bp_decode(float codeword[], int max_iters, uint8_t plain[], int* ok); #endif // _INCLUDE_LDPC_H_ diff --git a/ft8/pack.c b/ft8/pack.c index fc113e1..c00a0d1 100644 --- a/ft8/pack.c +++ b/ft8/pack.c @@ -6,8 +6,8 @@ #include #include -#define NTOKENS ((uint32_t)2063592L) -#define MAX22 ((uint32_t)4194304L) +#define NTOKENS ((uint32_t)2063592L) +#define MAX22 ((uint32_t)4194304L) #define MAXGRID4 ((uint16_t)32400) // TODO: This is wasteful, should figure out something more elegant @@ -19,7 +19,7 @@ const char A4[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // Pack a special token, a 22-bit hash code, or a valid base call // into a 28-bit integer. -int32_t pack28(const char *callsign) +int32_t pack28(const char* callsign) { // Check for special tokens first if (starts_with(callsign, "DE ")) @@ -38,7 +38,7 @@ int32_t pack28(const char *callsign) // TODO: Check for <...> callsign - char c6[6] = {' ', ' ', ' ', ' ', ' ', ' '}; + char c6[6] = { ' ', ' ', ' ', ' ', ' ', ' ' }; int length = 0; // strlen(callsign); // We will need it later while (callsign[length] != ' ' && callsign[length] != 0) @@ -75,9 +75,7 @@ int32_t pack28(const char *callsign) // Check for standard callsign int i0, i1, i2, i3, i4, i5; - if ((i0 = char_index(A1, c6[0])) >= 0 && (i1 = char_index(A2, c6[1])) >= 0 && - (i2 = char_index(A3, c6[2])) >= 0 && (i3 = char_index(A4, c6[3])) >= 0 && - (i4 = char_index(A4, c6[4])) >= 0 && (i5 = char_index(A4, c6[5])) >= 0) + if ((i0 = char_index(A1, c6[0])) >= 0 && (i1 = char_index(A2, c6[1])) >= 0 && (i2 = char_index(A3, c6[2])) >= 0 && (i3 = char_index(A4, c6[3])) >= 0 && (i4 = char_index(A4, c6[4])) >= 0 && (i5 = char_index(A4, c6[5])) >= 0) { // This is a standard callsign int32_t n28 = i0; @@ -100,7 +98,7 @@ int32_t pack28(const char *callsign) // Check if a string could be a valid standard callsign or a valid // compound callsign. // Return base call "bc" and a logical "cok" indicator. -bool chkcall(const char *call, char *bc) +bool chkcall(const char* call, char* bc) { int length = strlen(call); // n1=len_trim(w) if (length > 11) @@ -121,7 +119,7 @@ bool chkcall(const char *call, char *bc) return true; } -uint16_t packgrid(const char *grid4) +uint16_t packgrid(const char* grid4) { if (grid4 == 0) { @@ -138,9 +136,7 @@ uint16_t packgrid(const char *grid4) return MAXGRID4 + 4; // Check for standard 4 letter grid - if (in_range(grid4[0], 'A', 'R') && - in_range(grid4[1], 'A', 'R') && - is_digit(grid4[2]) && is_digit(grid4[3])) + if (in_range(grid4[0], 'A', 'R') && in_range(grid4[1], 'A', 'R') && is_digit(grid4[2]) && is_digit(grid4[3])) { uint16_t igrid4 = (grid4[0] - 'A'); igrid4 = igrid4 * 18 + (grid4[1] - 'A'); @@ -168,15 +164,15 @@ uint16_t packgrid(const char *grid4) } // Pack Type 1 (Standard 77-bit message) and Type 2 (ditto, with a "/P" call) -int pack77_1(const char *msg, uint8_t *b77) +int pack77_1(const char* msg, uint8_t* b77) { // Locate the first delimiter - const char *s1 = strchr(msg, ' '); + const char* s1 = strchr(msg, ' '); if (s1 == 0) return -1; - const char *call1 = msg; // 1st call - const char *call2 = s1 + 1; // 2nd call + const char* call1 = msg; // 1st call + const char* call2 = s1 + 1; // 2nd call int32_t n28a = pack28(call1); int32_t n28b = pack28(call2); @@ -187,7 +183,7 @@ int pack77_1(const char *msg, uint8_t *b77) uint16_t igrid4; // Locate the second delimiter - const char *s2 = strchr(s1 + 1, ' '); + const char* s2 = strchr(s1 + 1, ' '); if (s2 != 0) { igrid4 = packgrid(s2 + 1); @@ -221,7 +217,7 @@ int pack77_1(const char *msg, uint8_t *b77) return 0; } -void packtext77(const char *text, uint8_t *b77) +void packtext77(const char* text, uint8_t* b77) { int length = strlen(text); @@ -285,7 +281,7 @@ void packtext77(const char *text, uint8_t *b77) b77[9] &= 0x00; } -int pack77(const char *msg, uint8_t *c77) +int pack77(const char* msg, uint8_t* c77) { // Check Type 1 (Standard 77-bit message) or Type 2, with optional "/P" if (0 == pack77_1(msg, c77)) @@ -310,7 +306,7 @@ int pack77(const char *msg, uint8_t *c77) bool test1() { - const char *inputs[] = { + const char* inputs[] = { "", " ", "ABC", @@ -321,7 +317,8 @@ bool test1() "LL3JG", "LL3AJG", "CQ ", - 0}; + 0 + }; for (int i = 0; inputs[i]; ++i) { @@ -334,14 +331,15 @@ bool test1() bool test2() { - const char *inputs[] = { + const char* inputs[] = { "CQ LL3JG", "CQ LL3JG KO26", "L0UAA LL3JG KO26", "L0UAA LL3JG +02", "L0UAA LL3JG RRR", "L0UAA LL3JG 73", - 0}; + 0 + }; for (int i = 0; inputs[i]; ++i) { diff --git a/ft8/pack.h b/ft8/pack.h index baa42f8..4c03c9e 100644 --- a/ft8/pack.h +++ b/ft8/pack.h @@ -6,6 +6,6 @@ // Pack FT8 text message into 72 bits // [IN] msg - FT8 message (e.g. "CQ TE5T KN01") // [OUT] c77 - 10 byte array to store the 77 bit payload (MSB first) -int pack77(const char *msg, uint8_t *c77); +int pack77(const char* msg, uint8_t* c77); #endif // _INCLUDE_PACK_H_ diff --git a/ft8/text.c b/ft8/text.c index aae5705..68393a9 100644 --- a/ft8/text.c +++ b/ft8/text.c @@ -2,7 +2,7 @@ #include -const char *trim_front(const char *str) +const char* trim_front(const char* str) { // Skip leading whitespace while (*str == ' ') @@ -12,7 +12,7 @@ const char *trim_front(const char *str) return str; } -void trim_back(char *str) +void trim_back(char* str) { // Skip trailing whitespace by replacing it with '\0' characters int idx = strlen(str) - 1; @@ -24,9 +24,9 @@ void trim_back(char *str) // 1) trims a string from the back by changing whitespaces to '\0' // 2) trims a string from the front by skipping whitespaces -char *trim(char *str) +char* trim(char* str) { - str = (char *)trim_front(str); + str = (char*)trim_front(str); trim_back(str); // return a pointer to the first non-whitespace character return str; @@ -57,17 +57,17 @@ bool in_range(char c, char min, char max) return (c >= min) && (c <= max); } -bool starts_with(const char *string, const char *prefix) +bool starts_with(const char* string, const char* prefix) { return 0 == memcmp(string, prefix, strlen(prefix)); } -bool equals(const char *string1, const char *string2) +bool equals(const char* string1, const char* string2) { return 0 == strcmp(string1, string2); } -int char_index(const char *string, char c) +int char_index(const char* string, char c) { for (int i = 0; *string; ++i, ++string) { @@ -82,7 +82,7 @@ int char_index(const char *string, char c) // Text message formatting: // - replaces lowercase letters with uppercase // - merges consecutive spaces into single space -void fmtmsg(char *msg_out, const char *msg_in) +void fmtmsg(char* msg_out, const char* msg_in) { char c; char last_out = 0; @@ -100,7 +100,7 @@ void fmtmsg(char *msg_out, const char *msg_in) } // Parse a 2 digit integer from string -int dd_to_int(const char *str, int length) +int dd_to_int(const char* str, int length) { int result = 0; bool negative; @@ -131,7 +131,7 @@ int dd_to_int(const char *str, int length) } // Convert a 2 digit integer to string -void int_to_dd(char *str, int value, int width, bool full_sign) +void int_to_dd(char* str, int value, int width, bool full_sign) { if (value < 0) { diff --git a/ft8/text.h b/ft8/text.h index 1c07f1e..aac9921 100644 --- a/ft8/text.h +++ b/ft8/text.h @@ -6,30 +6,30 @@ // Utility functions for characters and strings -const char *trim_front(const char *str); -void trim_back(char *str); -char *trim(char *str); +const char* trim_front(const char* str); +void trim_back(char* str); +char* trim(char* str); char to_upper(char c); bool is_digit(char c); bool is_letter(char c); bool is_space(char c); bool in_range(char c, char min, char max); -bool starts_with(const char *string, const char *prefix); -bool equals(const char *string1, const char *string2); +bool starts_with(const char* string, const char* prefix); +bool equals(const char* string1, const char* string2); -int char_index(const char *string, char c); +int char_index(const char* string, char c); // Text message formatting: // - replaces lowercase letters with uppercase // - merges consecutive spaces into single space -void fmtmsg(char *msg_out, const char *msg_in); +void fmtmsg(char* msg_out, const char* msg_in); // Parse a 2 digit integer from string -int dd_to_int(const char *str, int length); +int dd_to_int(const char* str, int length); // Convert a 2 digit integer to string -void int_to_dd(char *str, int value, int width, bool full_sign); +void int_to_dd(char* str, int value, int width, bool full_sign); char charn(int c, int table_idx); int nchar(char c, int table_idx); diff --git a/ft8/unpack.c b/ft8/unpack.c index 734e2b9..2d34999 100644 --- a/ft8/unpack.c +++ b/ft8/unpack.c @@ -1,18 +1,18 @@ #ifdef __linux__ - #define _GNU_SOURCE +#define _GNU_SOURCE #endif #include "unpack.h" #include "text.h" #include -#define MAX22 ((uint32_t)4194304L) -#define NTOKENS ((uint32_t)2063592L) +#define MAX22 ((uint32_t)4194304L) +#define NTOKENS ((uint32_t)2063592L) #define MAXGRID4 ((uint16_t)32400L) // n28 is a 28-bit integer, e.g. n28a or n28b, containing all the // call sign bits from a packed message. -int unpack_callsign(uint32_t n28, uint8_t ip, uint8_t i3, char *result) +int unpack_callsign(uint32_t n28, uint8_t ip, uint8_t i3, char* result) { // Check for special tokens DE, QRZ, CQ, CQ_nnn, CQ_aaaa if (n28 < NTOKENS) @@ -108,7 +108,7 @@ int unpack_callsign(uint32_t n28, uint8_t ip, uint8_t i3, char *result) return 0; // Success } -int unpack_type1(const uint8_t *a77, uint8_t i3, char *call_to, char *call_de, char *extra) +int unpack_type1(const uint8_t* a77, uint8_t i3, char* call_to, char* call_de, char* extra) { uint32_t n28a, n28b; uint16_t igrid4; @@ -148,7 +148,7 @@ int unpack_type1(const uint8_t *a77, uint8_t i3, char *call_to, char *call_de, c // save_hash_call(call_de) // } - char *dst = extra; + char* dst = extra; if (igrid4 <= MAXGRID4) { @@ -205,7 +205,7 @@ int unpack_type1(const uint8_t *a77, uint8_t i3, char *call_to, char *call_de, c return 0; // Success } -int unpack_text(const uint8_t *a71, char *text) +int unpack_text(const uint8_t* a71, char* text) { // TODO: test uint8_t b71[9]; @@ -237,7 +237,7 @@ int unpack_text(const uint8_t *a71, char *text) return 0; // Success } -int unpack_telemetry(const uint8_t *a71, char *telemetry) +int unpack_telemetry(const uint8_t* a71, char* telemetry) { uint8_t b71[9]; @@ -266,21 +266,21 @@ int unpack_telemetry(const uint8_t *a71, char *telemetry) //none standard for wsjt-x 2.0 //by KD8CEC -int unpack_nonstandard(const uint8_t *a77, char *call_to, char *call_de, char *extra) +int unpack_nonstandard(const uint8_t* a77, char* call_to, char* call_de, char* extra) { uint32_t n12, iflip, nrpt, icq; uint64_t n58; - n12 = (a77[0] << 4); //11 ~4 : 8 + n12 = (a77[0] << 4); //11 ~4 : 8 n12 |= (a77[1] >> 4); //3~0 : 12 n58 = ((uint64_t)(a77[1] & 0x0F) << 54); //57 ~ 54 : 4 - n58 |= ((uint64_t)a77[2] << 46); //53 ~ 46 : 12 - n58 |= ((uint64_t)a77[3] << 38); //45 ~ 38 : 12 - n58 |= ((uint64_t)a77[4] << 30); //37 ~ 30 : 12 - n58 |= ((uint64_t)a77[5] << 22); //29 ~ 22 : 12 - n58 |= ((uint64_t)a77[6] << 14); //21 ~ 14 : 12 - n58 |= ((uint64_t)a77[7] << 6); //13 ~ 6 : 12 - n58 |= ((uint64_t)a77[8] >> 2); //5 ~ 0 : 765432 10 + n58 |= ((uint64_t)a77[2] << 46); //53 ~ 46 : 12 + n58 |= ((uint64_t)a77[3] << 38); //45 ~ 38 : 12 + n58 |= ((uint64_t)a77[4] << 30); //37 ~ 30 : 12 + n58 |= ((uint64_t)a77[5] << 22); //29 ~ 22 : 12 + n58 |= ((uint64_t)a77[6] << 14); //21 ~ 14 : 12 + n58 |= ((uint64_t)a77[7] << 6); //13 ~ 6 : 12 + n58 |= ((uint64_t)a77[8] >> 2); //5 ~ 0 : 765432 10 iflip = (a77[8] >> 1) & 0x01; //76543210 nrpt = ((a77[8] & 0x01) << 1); @@ -306,8 +306,8 @@ int unpack_nonstandard(const uint8_t *a77, char *call_to, char *call_de, char *e // call_3[5] = '>'; // call_3[6] = '\0'; - char *call_1 = (iflip) ? c11 : call_3; - char *call_2 = (iflip) ? call_3 : c11; + char* call_1 = (iflip) ? c11 : call_3; + char* call_2 = (iflip) ? call_3 : c11; //save_hash_call(c11_trimmed); if (icq == 0) @@ -334,7 +334,7 @@ int unpack_nonstandard(const uint8_t *a77, char *call_to, char *call_de, char *e return 0; } -int unpack77_fields(const uint8_t *a77, char *call_to, char *call_de, char *extra) +int unpack77_fields(const uint8_t* a77, char* call_to, char* call_de, char* extra) { call_to[0] = call_de[0] = extra[0] = '\0'; @@ -390,7 +390,7 @@ int unpack77_fields(const uint8_t *a77, char *call_to, char *call_de, char *extr return -1; } -int unpack77(const uint8_t *a77, char *message) +int unpack77(const uint8_t* a77, char* message) { char call_to[14]; char call_de[14]; @@ -401,7 +401,7 @@ int unpack77(const uint8_t *a77, char *message) return rc; // int msg_sz = strlen(call_to) + strlen(call_de) + strlen(extra) + 2; - char *dst = message; + char* dst = message; dst[0] = '\0'; diff --git a/ft8/unpack.h b/ft8/unpack.h index 2575083..6e09db8 100644 --- a/ft8/unpack.h +++ b/ft8/unpack.h @@ -6,9 +6,9 @@ // field1 - at least 14 bytes // field2 - at least 14 bytes // field3 - at least 7 bytes -int unpack77_fields(const uint8_t *a77, char *field1, char *field2, char *field3); +int unpack77_fields(const uint8_t* a77, char* field1, char* field2, char* field3); // message should have at least 35 bytes allocated (34 characters + zero terminator) -int unpack77(const uint8_t *a77, char *message); +int unpack77(const uint8_t* a77, char* message); #endif // _INCLUDE_UNPACK_H_ diff --git a/gen_ft8.c b/gen_ft8.c index efd873c..73fa06d 100644 --- a/gen_ft8.c +++ b/gen_ft8.c @@ -13,13 +13,13 @@ #define LOG_LEVEL LOG_INFO -#define FT8_SLOT_TIME 15.0f // total length of output waveform in seconds +#define FT8_SLOT_TIME 15.0f // total length of output waveform in seconds #define FT8_SYMBOL_RATE 6.25f // tone deviation (and symbol rate) in Hz -#define FT8_SYMBOL_BT 2.0f // symbol smoothing filter bandwidth factor (BT) +#define FT8_SYMBOL_BT 2.0f // symbol smoothing filter bandwidth factor (BT) -#define FT4_SLOT_TIME 7.5f // total length of output waveform in seconds +#define FT4_SLOT_TIME 7.5f // total length of output waveform in seconds #define FT4_SYMBOL_RATE 20.833333f // tone deviation (and symbol rate) in Hz -#define FT4_SYMBOL_BT 1.0f // symbol smoothing filter bandwidth factor (BT) +#define FT4_SYMBOL_BT 1.0f // symbol smoothing filter bandwidth factor (BT) #define GFSK_CONST_K 5.336446f // pi * sqrt(2 / log(2)) @@ -30,7 +30,7 @@ /// @param[in] b Shape parameter (values defined for FT8/FT4) /// @param[out] pulse Output array of pulse samples /// -void gfsk_pulse(int n_spsym, float symbol_bt, float *pulse) +void gfsk_pulse(int n_spsym, float symbol_bt, float* pulse) { for (int i = 0; i < 3 * n_spsym; ++i) { @@ -51,10 +51,10 @@ void gfsk_pulse(int n_spsym, float symbol_bt, float *pulse) /// @param[in] signal_rate Sample rate of synthesized signal, Hertz /// @param[out] signal Output array of signal waveform samples (should have space for n_sym*n_spsym samples) /// -void synth_gfsk(const uint8_t *symbols, int n_sym, float f0, float symbol_bt, float symbol_rate, int signal_rate, float *signal) +void synth_gfsk(const uint8_t* symbols, int n_sym, float f0, float symbol_bt, float symbol_rate, int signal_rate, float* signal) { int n_spsym = (int)(0.5f + signal_rate / symbol_rate); // Samples per symbol - int n_wave = n_sym * n_spsym; // Number of output samples + int n_wave = n_sym * n_spsym; // Number of output samples float hmod = 1.0f; LOG(LOG_DEBUG, "n_spsym = %d\n", n_spsym); @@ -116,7 +116,7 @@ void usage() printf("(Note that you might have to enclose your message in quote marks if it contains spaces)\n"); } -int main(int argc, char **argv) +int main(int argc, char** argv) { // Expect two command-line arguments if (argc < 3) @@ -125,8 +125,8 @@ int main(int argc, char **argv) return -1; } - const char *message = argv[1]; - const char *wav_path = argv[2]; + const char* message = argv[1]; + const char* wav_path = argv[2]; float frequency = 1000.0; if (argc > 3) { @@ -170,11 +170,11 @@ int main(int argc, char **argv) uint8_t tones[num_tones]; // Array of 79 tones (symbols) if (is_ft4) { - genft4(packed, tones); + ft4_encode(packed, tones); } else { - genft8(packed, tones); + ft8_encode(packed, tones); } printf("FSK tones: "); @@ -187,8 +187,8 @@ int main(int argc, char **argv) // Third, convert the FSK tones into an audio signal int sample_rate = 12000; int num_samples = (int)(0.5f + num_tones / symbol_rate * sample_rate); // Number of samples in the data signal - int num_silence = (slot_time * sample_rate - num_samples) / 2; // Silence padding at both ends to make 15 seconds - int num_total_samples = num_silence + num_samples + num_silence; // Number of samples in the padded signal + int num_silence = (slot_time * sample_rate - num_samples) / 2; // Silence padding at both ends to make 15 seconds + int num_total_samples = num_silence + num_samples + num_silence; // Number of samples in the padded signal float signal[num_total_samples]; for (int i = 0; i < num_silence; i++) { diff --git a/test.c b/test.c index f017adb..8d1b68a 100644 --- a/test.c +++ b/test.c @@ -15,7 +15,7 @@ #define LOG_LEVEL LOG_INFO -void convert_8bit_to_6bit(uint8_t *dst, const uint8_t *src, int nBits) +void convert_8bit_to_6bit(uint8_t* dst, const uint8_t* src, int nBits) { // Zero-fill the destination array as we will only be setting bits later for (int j = 0; j < (nBits + 5) / 6; ++j) @@ -96,17 +96,17 @@ void test2() { void test3() { uint8_t test_in2[10] = { 0x11, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x04, 0x01, 0x00 }; - uint16_t crc1 = ft8_crc(test_in2, 76); // Calculate CRC of 76 bits only + uint16_t crc1 = ftx_compute_crc(test_in2, 76); // Calculate CRC of 76 bits only LOG(LOG_INFO, "CRC: %04x\n", crc1); // should be 0x0708 } */ -void test_tones(float *log174) +void test_tones(float* log174) { // Just a test case for (int i = 0; i < FT8_ND; ++i) { - const uint8_t inv_map[8] = {0, 1, 3, 2, 6, 4, 5, 7}; + const uint8_t inv_map[8] = { 0, 1, 3, 2, 6, 4, 5, 7 }; uint8_t tone = ("0000000011721762454112705354533170166234757420515470163426"[i]) - '0'; uint8_t b3 = inv_map[tone]; log174[3 * i] = (b3 & 4) ? +1.0 : -1.0; @@ -126,7 +126,7 @@ void test4() printf("N_FFT = %d\n", nfft); printf("FFT work area = %lu\n", fft_work_size); - void *fft_work = malloc(fft_work_size); + void* fft_work = malloc(fft_work_size); kiss_fftr_cfg fft_cfg = kiss_fftr_alloc(nfft, 0, fft_work, &fft_work_size); kiss_fft_scalar window[nfft];