You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
3.6 KiB
C

/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 The srsLTE Developers. See the
* COPYRIGHT file at the top-level directory of this distribution.
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <stdlib.h>
#include <strings.h>
#include "srslte/utils/vector.h"
#include "srslte/utils/bit.h"
#include "srslte/modem/demod_soft.h"
#include "soft_algs.h"
int srslte_demod_soft_init(srslte_demod_soft_t *q, uint32_t max_symbols) {
int ret = SRSLTE_ERROR;
bzero((void*)q,sizeof(srslte_demod_soft_t));
q->sigma = 1.0;
q->zones = srslte_vec_malloc(sizeof(uint32_t) * max_symbols);
if (!q->zones) {
perror("malloc");
goto clean_exit;
}
q->dd = srslte_vec_malloc(sizeof(float*) * max_symbols * 7);
if (!q->dd) {
perror("malloc");
goto clean_exit;
}
q->max_symbols = max_symbols;
ret = SRSLTE_SUCCESS;
clean_exit:
if (ret != SRSLTE_SUCCESS) {
srslte_demod_soft_free(q);
}
return ret;
}
void srslte_demod_soft_free(srslte_demod_soft_t *q) {
if (q->zones) {
free(q->zones);
}
if (q->dd) {
free(q->dd);
}
bzero((void*)q,sizeof(srslte_demod_soft_t));
}
void srslte_demod_soft_table_set(srslte_demod_soft_t *q, srslte_modem_table_t *table) {
q->table = table;
}
void srslte_demod_soft_alg_set(srslte_demod_soft_t *q, srslte_demod_soft_alg_t alg_type) {
q->alg_type = alg_type;
}
void srslte_demod_soft_sigma_set(srslte_demod_soft_t *q, float sigma) {
q->sigma = 2*sigma;
}
int srslte_demod_soft_demodulate(srslte_demod_soft_t *q, const cf_t* symbols, float* llr, int nsymbols) {
switch(q->alg_type) {
case SRSLTE_DEMOD_SOFT_ALG_EXACT:
llr_exact(symbols, llr, nsymbols, q->table->nsymbols, q->table->nbits_x_symbol,
q->table->symbol_table, q->table->soft_table.idx, q->sigma);
break;
case SRSLTE_DEMOD_SOFT_ALG_APPROX:
if (nsymbols <= q->max_symbols) {
llr_approx(symbols, llr, nsymbols, q->table->nsymbols,
q->table->nbits_x_symbol,
q->table->symbol_table, q->table->soft_table.idx,
q->table->soft_table.d_idx, q->table->soft_table.min_idx, q->sigma,
q->zones, q->dd);
} else {
fprintf(stderr, "Too many symbols (%d>%d)\n", nsymbols, q->max_symbols);
return -1;
}
break;
}
return nsymbols*q->table->nbits_x_symbol;
}
/* High-Level API */
int srslte_demod_soft_initialize(srslte_demod_soft_hl* hl) {
srslte_modem_table_init(&hl->table);
if (srslte_modem_table_lte(&hl->table,hl->init.std,true)) {
return -1;
}
srslte_demod_soft_init(&hl->obj, 10000);
hl->obj.table = &hl->table;
return 0;
}
int srslte_demod_soft_work(srslte_demod_soft_hl* hl) {
hl->obj.sigma = hl->ctrl_in.sigma;
hl->obj.alg_type = hl->ctrl_in.alg_type;
int ret = srslte_demod_soft_demodulate(&hl->obj,hl->input,hl->output,hl->in_len);
hl->out_len = ret;
return 0;
}
int srslte_demod_soft_stop(srslte_demod_soft_hl* hl) {
srslte_modem_table_free(&hl->table);
return 0;
}