hamnet70/impl/src/layer1/transmission.c

120 lines
2.7 KiB
C

#include <math.h>
#include "transmission.h"
#include "config.h"
result_t transmission_init(transmission_ctx_t *ctx)
{
ctx->rrc_interp = firinterp_crcf_create_prototype(LIQUID_FIRFILT_RRC, RRC_SPS, RRC_DELAY, RRC_BETA, 0);
return OK;
}
result_t transmission_free(transmission_ctx_t *ctx)
{
firinterp_crcf_destroy(ctx->rrc_interp);
return OK;
}
result_t transmission_ramp_up(transmission_ctx_t *ctx, float complex *output, size_t *output_size)
{
if(*output_size < RRC_SPS*TRANSMISSION_RAMP_UP_LEN) {
*output_size = RRC_SPS*TRANSMISSION_RAMP_UP_LEN;
return ERR_SIZE;
}
// ramp up alternating ±1 symbols following a sin(t)^2 curve
for(size_t i = 0; i < TRANSMISSION_RAMP_UP_LEN; i++) {
float s = sinf((float)M_PI / 2.0f * i / TRANSMISSION_RAMP_UP_LEN);
float symbol = s*s;
if((i % 2) != 0) {
symbol = -symbol;
}
firinterp_crcf_execute(ctx->rrc_interp, symbol, output + (RRC_SPS*i));
}
*output_size = RRC_SPS*TRANSMISSION_RAMP_UP_LEN;
return OK;
}
result_t transmission_ramp_down(transmission_ctx_t *ctx, float complex *output, size_t *output_size)
{
const size_t total_symbols = TRANSMISSION_RAMP_DOWN_LEN + 2*RRC_DELAY;
if(*output_size < RRC_SPS*total_symbols) {
*output_size = RRC_SPS*total_symbols;
return ERR_SIZE;
}
// ramp down alternating ±1 symbols following a cos(t)^2 curve
for(size_t i = 0; i < TRANSMISSION_RAMP_DOWN_LEN; i++) {
float s = cosf((float)M_PI / 2.0f * i / TRANSMISSION_RAMP_DOWN_LEN);
float symbol = s*s;
if((i % 2) != 0) {
symbol = -symbol;
}
firinterp_crcf_execute(ctx->rrc_interp, symbol, output + (RRC_SPS*i));
}
// add 2*RRC_DELAY zeros to flush the filter history
for(size_t i = 0; i < 2*RRC_DELAY; i++) {
firinterp_crcf_execute(ctx->rrc_interp, 0.0f, output + (RRC_SPS*(TRANSMISSION_RAMP_DOWN_LEN+i)));
}
*output_size = RRC_SPS*total_symbols;
return OK;
}
result_t transmission_filter_packet(
transmission_ctx_t *ctx,
const float complex *packet,
size_t packet_size,
float complex *output,
size_t *output_size)
{
if(*output_size < RRC_SPS*packet_size) {
*output_size = RRC_SPS*packet_size;
return ERR_SIZE;
}
// ramp down alternating ±1 symbols following a cos(t)^2 curve
for(size_t i = 0; i < packet_size; i++) {
firinterp_crcf_execute(ctx->rrc_interp, packet[i], output + (RRC_SPS*i));
}
*output_size = RRC_SPS*packet_size;
return OK;
}
size_t transmission_calculate_ramp_up_length(transmission_ctx_t *ctx)
{
(void)ctx;
return RRC_SPS * TRANSMISSION_RAMP_UP_LEN;
}
size_t transmission_calculate_ramp_down_length(transmission_ctx_t *ctx)
{
(void)ctx;
return RRC_SPS * (TRANSMISSION_RAMP_DOWN_LEN + 2 * RRC_DELAY);
}
size_t transmission_calculate_packet_length(transmission_ctx_t *ctx, size_t symbol_count)
{
(void)ctx;
return RRC_SPS * symbol_count;
}