Integrate the interleaver

This commit is contained in:
Thomas Kolb 2024-08-14 19:13:41 +02:00
parent 325abdbd02
commit 017eb221f1
7 changed files with 87 additions and 10 deletions

View file

@ -39,6 +39,8 @@ set(sources
src/layer1/whitening.h
src/layer1/modcod.c
src/layer1/modcod.h
src/layer1/interleaver.c
src/layer1/interleaver.h
src/layer2/tundev.c
src/layer2/tundev.h
src/layer2/packet_queue.c

View file

@ -1,12 +1,24 @@
#include <math.h>
#include "interleaver.h"
#define INTERLEAVE_DISTANCE 16
void interleaver_interleave(const float complex *in, float complex *out, size_t n)
static size_t calculate_distance(size_t n)
{
// note: benchmarking shows that this is faster than a integer-specific
// Newton-Raphson implementation on systems with an FPU. On amd64, sqrtf
// was faster by a factor of 6.
return ceilf(sqrtf(n));
}
void interleaver_interleave_cf(const float complex *in, float complex *out, size_t n)
{
size_t interleaved_base = 0;
size_t interleaved_index = 0;
size_t interleave_distance = calculate_distance(n);
/* example for this algorithm with INTERLEAVE_DISTANCE = 5:
* original: abcdefghijklmn
* output: adgjmbehkncfil
@ -14,7 +26,7 @@ void interleaver_interleave(const float complex *in, float complex *out, size_t
for(size_t orig_index = 0; orig_index < n; orig_index++) {
out[interleaved_index] = in[orig_index];
interleaved_index += INTERLEAVE_DISTANCE;
interleaved_index += interleave_distance;
if(interleaved_index >= n) {
interleaved_base++;
interleaved_index = interleaved_base;
@ -22,15 +34,58 @@ void interleaver_interleave(const float complex *in, float complex *out, size_t
}
}
void interleaver_deinterleave(const float complex *in, float complex *out, size_t n)
void interleaver_deinterleave_cf(const float complex *in, float complex *out, size_t n)
{
size_t interleaved_base = 0;
size_t interleaved_index = 0;
size_t interleave_distance = calculate_distance(n);
for(size_t orig_index = 0; orig_index < n; orig_index++) {
out[orig_index] = in[interleaved_index];
interleaved_index += INTERLEAVE_DISTANCE;
interleaved_index += interleave_distance;
if(interleaved_index >= n) {
interleaved_base++;
interleaved_index = interleaved_base;
}
}
}
void interleaver_interleave_u8(const uint8_t *in, uint8_t *out, size_t n)
{
size_t interleaved_base = 0;
size_t interleaved_index = 0;
size_t interleave_distance = calculate_distance(n);
/* example for this algorithm with INTERLEAVE_DISTANCE = 5:
* original: abcdefghijklmn
* output: adgjmbehkncfil
*/
for(size_t orig_index = 0; orig_index < n; orig_index++) {
out[interleaved_index] = in[orig_index];
interleaved_index += interleave_distance;
if(interleaved_index >= n) {
interleaved_base++;
interleaved_index = interleaved_base;
}
}
}
void interleaver_deinterleave_u8(const uint8_t *in, uint8_t *out, size_t n)
{
size_t interleaved_base = 0;
size_t interleaved_index = 0;
size_t interleave_distance = calculate_distance(n);
for(size_t orig_index = 0; orig_index < n; orig_index++) {
out[orig_index] = in[interleaved_index];
interleaved_index += interleave_distance;
if(interleaved_index >= n) {
interleaved_base++;
interleaved_index = interleaved_base;

View file

@ -3,9 +3,12 @@
#include <complex.h>
#include <stddef.h>
#include <stdint.h>
void interleaver_interleave(const float complex *in, float complex *out, size_t n);
void interleaver_interleave_cf(const float complex *in, float complex *out, size_t n);
void interleaver_deinterleave_cf(const float complex *in, float complex *out, size_t n);
void interleaver_deinterleave(const float complex *in, float complex *out, size_t n);
void interleaver_interleave_u8(const uint8_t *in, uint8_t *out, size_t n);
void interleaver_deinterleave_u8(const uint8_t *in, uint8_t *out, size_t n);
#endif // INTERLEAVER_H

View file

@ -2,6 +2,7 @@
#include <string.h>
#include "whitening.h"
#include "interleaver.h"
#include "preamble.h"
#include "config.h"
@ -133,6 +134,7 @@ result_t packet_mod_modulate(packet_mod_ctx_t *ctx)
unsigned int nsyms = (ctx->length * 8 + bps/2) / bps;
unsigned char msg_sym_idcs[nsyms];
unsigned char msg_sym_idcs_interleaved[nsyms];
float complex *msg_mod = malloc(sizeof(float complex) * nsyms);
if(!msg_mod) {
@ -142,8 +144,11 @@ result_t packet_mod_modulate(packet_mod_ctx_t *ctx)
ERR_CHECK_LIQUID(liquid_repack_bytes(ctx->pkt_bytes, 8, ctx->length, msg_sym_idcs, bps, nsyms, &nsyms));
// interleave the message symbols
interleaver_interleave_u8(msg_sym_idcs, msg_sym_idcs_interleaved, nsyms);
for(size_t i = 0; i < nsyms; i++) {
ERR_CHECK_LIQUID(modem_modulate(payload_modem, msg_sym_idcs[i], &msg_mod[i]));
ERR_CHECK_LIQUID(modem_modulate(payload_modem, msg_sym_idcs_interleaved[i], &msg_mod[i]));
}
modem_destroy(payload_modem);

View file

@ -12,6 +12,7 @@
#include "preamble.h"
#include "freq_est.h"
#include "whitening.h"
#include "interleaver.h"
#include "config.h"
#include "options.h"
@ -465,8 +466,12 @@ result_t layer1_rx_process(layer1_rx_t *rx, const float complex *samples, size_t
rx->packet_debug_info.data_rssi = agc_crcf_get_rssi(rx->agc);
rx->packet_debug_info.data_evm = -1e38f; // FIXME
// deinterleave the message symbols
uint8_t symbols_int_deinterleaved[rx->payload_len_symbols];
interleaver_deinterleave_u8(symbols_int, symbols_int_deinterleaved, rx->payload_len_symbols);
ERR_CHECK_LIQUID(liquid_repack_bytes(
symbols_int, modem_get_bps(rx->payload_demod), rx->payload_len_symbols,
symbols_int_deinterleaved, modem_get_bps(rx->payload_demod), rx->payload_len_symbols,
payload_enc, 8, sizeof(payload_enc), &nsyms));
fec payload_fec = modcod_create_fec(rx->modcod);

View file

@ -38,6 +38,8 @@ add_executable(
../src/layer1/whitening.h
../src/layer1/modcod.c
../src/layer1/modcod.h
../src/layer1/interleaver.c
../src/layer1/interleaver.h
../src/utils.c
../src/utils.h
../src/var_array.c
@ -89,6 +91,8 @@ add_executable(
../src/layer1/whitening.h
../src/layer1/modcod.c
../src/layer1/modcod.h
../src/layer1/interleaver.c
../src/layer1/interleaver.h
../src/layer1/preamble.c
../src/layer1/preamble.h
../src/utils.c
@ -128,6 +132,8 @@ add_executable(
../src/layer1/whitening.h
../src/layer1/modcod.c
../src/layer1/modcod.h
../src/layer1/interleaver.c
../src/layer1/interleaver.h
../src/layer1/preamble.c
../src/layer1/preamble.h
../src/utils.c
@ -214,4 +220,5 @@ add_executable(
target_link_libraries(
test_interleaver
m
)

View file

@ -16,8 +16,8 @@ int main(void)
orig[i] = (float complex)i;
}
interleaver_interleave(orig, interleaved, N);
interleaver_deinterleave(interleaved, deinterleaved, N);
interleaver_interleave_cf(orig, interleaved, N);
interleaver_deinterleave_cf(interleaved, deinterleaved, N);
for(size_t i = 0; i < N; i++) {
printf("%5zu %5.1f %5.1f %5.1f\n", i, crealf(orig[i]), crealf(interleaved[i]), crealf(deinterleaved[i]));