summaryrefslogtreecommitdiff
path: root/cesar/cp/spoc/src/spoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/cp/spoc/src/spoc.c')
-rw-r--r--cesar/cp/spoc/src/spoc.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/cesar/cp/spoc/src/spoc.c b/cesar/cp/spoc/src/spoc.c
new file mode 100644
index 0000000000..ef258570a0
--- /dev/null
+++ b/cesar/cp/spoc/src/spoc.c
@@ -0,0 +1,175 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/spoc.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "hal/phy/defs.h"
+#include "cp/spoc/spoc.h"
+#include "math.h"
+
+#define SPOC_PMIN PHY_CARRIER_OFFSET
+#define SPOC_PMAX (PHY_CARRIER_NB + SPOC_PMIN - 1)
+#define SPOC_DIAGONAL_LENGTH PHY_CARRIER_NB
+
+spoc_prec_t kaiser[10] = { 0.9905, 0.9622, 0.9164, 0.8546, 0.7792, 0.6929, 0.5989, 0.5005, 0.4011, 0.304 };
+
+void
+spoc_CG (spoc_prec_t rho, int N, spoc_prec_t *reg)
+{
+ spoc_prec_t arg_p = N*M_PI*rho;
+ spoc_prec_t arg_n = arg_p;
+ spoc_prec_t sinus = sin (arg_p);
+ if (arg_p == 0) reg[10] = 1;
+ else reg[10] = sinus/arg_p;
+ int k;
+ spoc_prec_t kk;
+ for(k=1;k<=10; k++)
+ {
+ sinus = -sinus;
+ kk = kaiser[k-1]*sinus;
+ arg_p+=M_PI;
+ arg_n-=M_PI;
+ /* Remarque sur la division par arg_p = pi(k-N*rho).
+ * si |rho|<300ppm, N<3072, |k|<=1 alors arg_p != 0
+ * et lalors arg_p=0 que si rho=0 et k=0. voir au dessus. */
+ reg[k+10] = kk/arg_p;
+ reg[10-k] = kk/arg_n;
+ }
+}
+
+void
+spoc_MCoeff (spoc_prec_t rho)
+{
+ int k;
+ spoc_prec_t xi,xe;
+ spoc_prec_t sin_xi,sin_xe;
+ spoc_prec_t cos_xi,cos_xe;
+ spoc_prec_t pirho = M_PI * rho;
+ spoc_prec_t SIN_PIRHO = sin(pirho);
+ spoc_prec_t COS_PIRHO = cos(pirho);
+ spoc_prec_t delta;
+ uint len;
+ spoc_prec_t sin_prev;
+
+ spoc_prec_t rho_abs = rho;
+ if (rho < 0) rho_abs = -rho;
+ if (rho_abs >= 1e-8)
+ {
+ //printf ("normal computation\n");
+ xi = pirho * SPOC_PMIN;
+ xe = pirho * SPOC_PMAX;
+ sin_xi = sin(xi);
+ sin_xe = sin(xe);
+ cos_xi = cos(xi);
+ len = SPOC_DIAGONAL_LENGTH - 1; // interval nb in the diagonal.
+
+#ifdef SPOC_COMPARE_SCILAB
+ args_haut[20] = xi;
+ args_bas[20] = xe;
+ sinc_haut[20] = sin_xi/xi;
+ sinc_bas[20] = sin_xe/xe;
+ divisor[20] = len*len;
+ args_haut_rx[20] = -xi;
+ args_bas_rx[20] = -xe;
+ sinc_haut_rx[20] = sin_xi/xi;
+ sinc_bas_rx[20] = sin_xe/xe;
+#endif
+ if (xi == 0 )
+ {
+ reg_ordo_tx[20] = reg_ordo_rx[20] = 1;
+ reg_pente_tx[20] = reg_pente_rx[20] = 0;
+ }
+ else
+ {
+ reg_ordo_tx[20] = reg_ordo_rx[20] = sin_xi/xi;
+ reg_pente_tx[20] = reg_pente_rx[20] = (sin_xe/xe - reg_ordo_tx[20])/(len*len);
+ }
+
+ delta = 0;
+ /* Diagonales superieures */
+ for (k=1; k<=20; k++)
+ {
+ xi += (M_PI + pirho);
+ xe += M_PI;
+ delta += 2*M_PI;
+ sin_prev = sin_xi;
+ sin_xi = -sin_prev * COS_PIRHO - cos_xi * SIN_PIRHO;
+ cos_xi = sin_prev * SIN_PIRHO - cos_xi * COS_PIRHO;
+ sin_xe = -sin_xe;
+ sin_xi = sin(xi);
+ len -= 1;
+ spoc_prec_t mux = 1.0/len;
+ reg_ordo_tx[k+20] = sin_xi/xi;
+ reg_ordo_rx[k+20] = -sin_xi/(-xi+delta);
+ reg_pente_tx[k+20] = (sin_xe/xe - reg_ordo_tx[k+20])*mux;
+ reg_pente_rx[k+20] = (-sin_xe/(-xe+delta) - reg_ordo_rx[k+20])*mux;
+#ifdef SPOC_COMPARE_SCILAB
+ divisor[k+20] = len;
+ args_haut[k+20] = xi;
+ args_bas[k+20] = xe;
+ sinc_haut[k+20] = sin_xi/xi;
+ sinc_bas[k+20] = sin_xe/xe;
+ args_haut_rx[k+20] = -xi+delta;
+ args_bas_rx[k+20] = -xe+delta;
+ sinc_haut_rx[k+20] = -sin_xi/(-xi+delta);
+ sinc_bas_rx[k+20] = -sin_xe/(-xe+delta);
+#endif
+ }
+ xi = pirho * SPOC_PMIN;
+ xe = pirho * SPOC_PMAX;
+ sin_xi = reg_ordo_tx[20] * xi;
+ sin_xe = sin(xe);
+ cos_xe = cos(xe);
+ len = SPOC_DIAGONAL_LENGTH - 1;
+ delta=0;
+ /* Diagonales inferieures */
+ for (k=1; k<=20; k++)
+ {
+ xe -= (M_PI + pirho);
+ xi -= M_PI;
+ delta -= 2*M_PI;
+ sin_prev = sin_xe;
+ sin_xe = -sin_prev * COS_PIRHO + cos_xe * SIN_PIRHO;
+ cos_xe = -sin_prev * SIN_PIRHO - cos_xe * COS_PIRHO;
+ sin_xi = -sin_xi;
+ len -= 1;
+ spoc_prec_t mux = 1.0/len;
+ reg_ordo_tx[20-k] = sin_xi/xi;
+ reg_ordo_rx[20-k] = -sin_xi/(-xi+delta);
+ reg_pente_tx[20-k] = (sin_xe/xe - reg_ordo_tx[20-k])*mux;
+ reg_pente_rx[20-k] = (-sin_xe/(-xe+delta) - reg_ordo_rx[20-k])*mux;
+#ifdef SPOC_COMPARE_SCILAB
+ divisor[20-k] = len;
+ args_haut[20-k] = xi;
+ args_bas[20-k] = xe;
+ sinc_haut[20-k] = sin_xi/xi;
+ sinc_bas[20-k] = sin_xe/xe;
+ args_haut_rx[20-k] = -xi+delta;
+ args_bas_rx[20-k] = -xe+delta;
+ sinc_haut_rx[20-k] = -sin_xi/(-xi+delta);
+ sinc_bas_rx[20-k] = -sin_xe/(-xe+delta);
+#endif
+ }
+ }
+ else
+ {
+ //printf ("fast computation\n");
+ for (k=1; k<=20; k++)
+ {
+ reg_ordo_tx[k+20] = reg_ordo_tx[20-k] = reg_ordo_rx[k+20] = reg_ordo_rx [20-k] = 0;
+ reg_pente_tx[k+20] = reg_pente_tx[20-k]= reg_pente_rx[k+20] = reg_pente_rx [20-k] = 0;
+ }
+ reg_ordo_tx[20] = reg_ordo_rx[20] = 1;
+ reg_pente_tx[20] = reg_pente_rx[20] = 0;
+ }
+}