Integrate the interleaver
This commit is contained in:
parent
325abdbd02
commit
ecb8840064
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -214,4 +214,5 @@ add_executable(
|
|||
|
||||
target_link_libraries(
|
||||
test_interleaver
|
||||
m
|
||||
)
|
||||
|
|
|
@ -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]));
|
||||
|
|
Loading…
Reference in a new issue