mirror of https://github.com/pvnis/srsRAN_4G.git
CFO correction using LUT
parent
f5f1ee186e
commit
adf5260e29
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2014 The libLTE Developers. See the
|
||||||
|
* COPYRIGHT file at the top-level directory of this distribution.
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the libLTE library.
|
||||||
|
*
|
||||||
|
* libLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* libLTE 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Lesser 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/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _cfo_
|
||||||
|
#define _cfo_
|
||||||
|
|
||||||
|
#include <complex.h>
|
||||||
|
|
||||||
|
typedef _Complex float cf_t;
|
||||||
|
|
||||||
|
/** If the frequency is changed more than the tolerance, a new table is generated */
|
||||||
|
#define CFO_TOLERANCE 0.00001
|
||||||
|
|
||||||
|
#define CFO_CEXPTAB_SIZE 4096
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float last_freq;
|
||||||
|
float tol;
|
||||||
|
int nsamples;
|
||||||
|
cexptab_t tab;
|
||||||
|
cf_t *cur_cexp;
|
||||||
|
}cfo_t;
|
||||||
|
|
||||||
|
int cfo_init(cfo_t *h, int nsamples);
|
||||||
|
void cfo_free(cfo_t *h);
|
||||||
|
|
||||||
|
void cfo_set_tol(cfo_t *h, float tol);
|
||||||
|
void cfo_correct(cfo_t *h, cf_t *x, float freq);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2014 The libLTE Developers. See the
|
||||||
|
* COPYRIGHT file at the top-level directory of this distribution.
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the libLTE library.
|
||||||
|
*
|
||||||
|
* libLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* libLTE 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Lesser 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 <strings.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "lte/utils/cexptab.h"
|
||||||
|
#include "lte/sync/cfo.h"
|
||||||
|
#include "lte/utils/vector.h"
|
||||||
|
#include "lte/utils/debug.h"
|
||||||
|
|
||||||
|
int cfo_init(cfo_t *h, int nsamples) {
|
||||||
|
int ret = -1;
|
||||||
|
bzero(h, sizeof(cfo_t));
|
||||||
|
|
||||||
|
if (cexptab_init(&h->tab, CFO_CEXPTAB_SIZE)) {
|
||||||
|
goto clean;
|
||||||
|
}
|
||||||
|
h->cur_cexp = malloc(sizeof(cf_t) * nsamples);
|
||||||
|
if (!h->cur_cexp) {
|
||||||
|
goto clean;
|
||||||
|
}
|
||||||
|
h->tol = CFO_TOLERANCE;
|
||||||
|
h->last_freq = 0;
|
||||||
|
h->nsamples = nsamples;
|
||||||
|
cexptab_gen(&h->tab, h->cur_cexp, h->last_freq, h->nsamples);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
clean:
|
||||||
|
if (ret == -1) {
|
||||||
|
cfo_free(h);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfo_free(cfo_t *h) {
|
||||||
|
cexptab_free(&h->tab);
|
||||||
|
if (h->cur_cexp) {
|
||||||
|
free(h->cur_cexp);
|
||||||
|
}
|
||||||
|
bzero(h, sizeof(cf_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfo_set_tol(cfo_t *h, float tol) {
|
||||||
|
h->tol = tol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfo_correct(cfo_t *h, cf_t *x, float freq) {
|
||||||
|
if (fabs(h->last_freq - freq) > h->tol) {
|
||||||
|
h->last_freq = freq;
|
||||||
|
cexptab_gen(&h->tab, h->cur_cexp, h->last_freq, h->nsamples);
|
||||||
|
INFO("CFO generating new table for frequency %.4f\n", freq);
|
||||||
|
}
|
||||||
|
vec_prod_ccc(h->cur_cexp, x, x, h->nsamples);
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2014 The libLTE Developers. See the
|
||||||
|
* COPYRIGHT file at the top-level directory of this distribution.
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the libLTE library.
|
||||||
|
*
|
||||||
|
* libLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* libLTE 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Lesser 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 <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <complex.h>
|
||||||
|
|
||||||
|
#include "lte/utils/cexptab.h"
|
||||||
|
|
||||||
|
int cexptab_init(cexptab_t *h, int size) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
h->size = size;
|
||||||
|
h->tab = malloc(sizeof(cf_t) * size);
|
||||||
|
if (h->tab) {
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
h->tab[i] = cexpf(_Complex_I * 2 * M_PI * (float) i / size);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cexptab_free(cexptab_t *h) {
|
||||||
|
if (h->tab) {
|
||||||
|
free(h->tab);
|
||||||
|
}
|
||||||
|
bzero(h, sizeof(cexptab_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cexptab_gen(cexptab_t *h, cf_t *x, float freq, int len) {
|
||||||
|
int i;
|
||||||
|
unsigned int idx;
|
||||||
|
float phase_inc = freq * h->size;
|
||||||
|
float phase=0;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
idx = (unsigned int) phase;
|
||||||
|
x[i] = h->tab[idx];
|
||||||
|
phase += phase_inc;
|
||||||
|
if (phase >= (float) h->size) {
|
||||||
|
phase -= (float) h->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cexptab_gen_direct(cf_t *x, float freq, int len) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
x[i] = cexpf(_Complex_I * 2 * M_PI * freq * i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,131 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* \section COPYRIGHT
|
|
||||||
*
|
|
||||||
* Copyright 2013-2014 The libLTE Developers. See the
|
|
||||||
* COPYRIGHT file at the top-level directory of this distribution.
|
|
||||||
*
|
|
||||||
* \section LICENSE
|
|
||||||
*
|
|
||||||
* This file is part of the libLTE library.
|
|
||||||
*
|
|
||||||
* libLTE is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* libLTE 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 Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* A copy of the GNU Lesser 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 <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <complex.h>
|
|
||||||
|
|
||||||
#include "lte/utils/nco.h"
|
|
||||||
|
|
||||||
void nco_init(nco_t *nco, int size) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
nco->size=size;
|
|
||||||
nco->cost=malloc(size*sizeof(float));
|
|
||||||
nco->sint=malloc(size*sizeof(float));
|
|
||||||
assert(nco->cost && nco->sint);
|
|
||||||
|
|
||||||
for (i=0;i<size;i++) {
|
|
||||||
nco->cost[i] = cosf(2*M_PI*i/size);
|
|
||||||
nco->sint[i] = sinf(2*M_PI*i/size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nco_destroy(nco_t *nco) {
|
|
||||||
if (nco->cost) {
|
|
||||||
free(nco->cost);
|
|
||||||
}
|
|
||||||
if (nco->sint) {
|
|
||||||
free(nco->sint);
|
|
||||||
}
|
|
||||||
nco->size=0;
|
|
||||||
bzero(nco, sizeof(nco_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int nco_idx(float phase, int size) {
|
|
||||||
while(phase>=2*M_PI) {
|
|
||||||
phase-=2*M_PI;
|
|
||||||
}
|
|
||||||
unsigned int idx = (unsigned int) (phase*size/(2*M_PI));
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float nco_sin(nco_t *nco, float phase) {
|
|
||||||
return nco->sint[nco_idx(phase,nco->size)];
|
|
||||||
}
|
|
||||||
inline float nco_cos(nco_t *nco, float phase) {
|
|
||||||
return nco->cost[nco_idx(phase,nco->size)];
|
|
||||||
}
|
|
||||||
inline void nco_sincos(nco_t *nco, float phase, float *sin, float *cos) {
|
|
||||||
unsigned int idx = nco_idx(phase,nco->size);
|
|
||||||
*sin = nco->sint[idx];
|
|
||||||
*cos = nco->cost[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline _Complex float nco_cexp(nco_t *nco, float arg) {
|
|
||||||
float s,c;
|
|
||||||
nco_sincos(nco,arg,&s,&c);
|
|
||||||
return c+I*s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nco_sin_f(nco_t *nco, float *x, float freq, int len) {
|
|
||||||
int i;
|
|
||||||
unsigned int idx;
|
|
||||||
|
|
||||||
idx=0;
|
|
||||||
for (i=0;i<len;i++) {
|
|
||||||
idx=((unsigned int) (freq*i*nco->size/len))%nco->size;
|
|
||||||
x[i] = nco->sint[idx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void nco_cos_f(nco_t *nco, float *x, float freq, int len) {
|
|
||||||
int i;
|
|
||||||
unsigned int idx;
|
|
||||||
|
|
||||||
idx=0;
|
|
||||||
for (i=0;i<len;i++) {
|
|
||||||
idx=((unsigned int) (freq*i*nco->size/len))%nco->size;
|
|
||||||
x[i] = nco->cost[idx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void nco_cexp_f(nco_t *nco, _Complex float *x, float freq, int len) {
|
|
||||||
int i;
|
|
||||||
unsigned int idx;
|
|
||||||
|
|
||||||
idx=0;
|
|
||||||
for (i=0;i<len;i++) {
|
|
||||||
idx=((unsigned int) (freq*i*nco->size/len))%nco->size;
|
|
||||||
x[i] = nco->cost[idx] + I*nco->sint[idx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nco_cexp_f_direct(_Complex float *x, float freq, int len) {
|
|
||||||
int i;
|
|
||||||
for (i=0;i<len;i++) {
|
|
||||||
x[i] *= cexpf(_Complex_I * 2 * M_PI * freq * i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue