Computational routine
eng


gensymb

File content


/* Modnumlib Scicos interfacing function
 * Copyright (C) 2009-2011 Alan Layec
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
 
/* genmsymb Scicos Generic Symbol Generator
 * Type 4 simulation function ver 1.0 - scilab-3.0
 * 5 janvier 2005 - IRCOM GROUP - Author : A.Layec
 */

/* REVISION HISTORY :
 * $Log$
 */

#include <math.h>

#include "modnum_lib.h"
#include "machine.h"
#include "scicos_block.h"

#if WIN32
#define NULL    0
#endif

extern  integer C2F(dcopy)();

/* entrées régulières      : u[0..insz[0]-1]  : vecteur des numéros symboles
 * sorties régulières      : y1[0..nech*insz[0]-1] : vecteur des composantes I
 *                           y2[0..nech*insz[0]-1] : vecteur des composantes Q
 * entrée évènementielles  : instants de déclenchement.
 * sortie évènementielle   : néant
 * paramètres entiers      : ipar[0] :nombre de symbole à générer
 *                           ipar[1] :longueur en bit des symboles
 *                           ipar[2] :m nombre d'états
 *                           ipar[3] :nech nombre d'échantillons
 *                           ipar[4] :compteur initial du suréchantillonneur
 *                           ipar[5] :nbr de coef du filtre
 *                           ipar[6] :taille du vecteur en puissance de 2 (pour filtre avec fft842)
 *                           ipar[7] :flag générateur séquentiel(0:scalaire/1:Vectoriel)
 *
 * paramètres réels        : rpar[0..nb_coef-1] : vecteur de la réponse impulsionnelle
 * état discret            : flag_seq=0
 *                            z[0..nb_coef-1]         : vecteur du mot mémoire voie I
 *                            z[nb_coef..2*nb_coef-1] : vecteur du mot mémoire voie Q
 *                           flag_seq=1
 *                            z[0] : compteur sur-échantillonneur
 *                            z[1..nb_coef]         : vecteur du mot mémoire voie I
 *                            z[nb_coef+1..2*nb_coef] : vecteur du mot mémoire voie Q
 */

/*prototype*/
void gensymb(scicos_block *block,int flag)
{
 /*Déclaration des variables*/
 double *y1,*y2;
 /*double *u;*/
 double *z;
 int ny;
 int i,k;
 int nu,n,m,m1,nech,init_c,nb_coef;
 int mu=1;
 int opt,nflag;
 int flag_seq;
 double *z__;
 double *zi1_r, *zi1_i, *zi2_r, *zi2_i, *yi_r, *yi_i;
 double *zq1_r, *zq1_i, *zq2_r, *zq2_i, *yq_r, *yq_i;

 /*fft variables*/
 fft_pr_struct fft_pr;

 /*Récupération des valeurs des variables*/
 ny=block->outsz[0];
 nu=block->ipar[0];
 n=block->ipar[1];
 m=block->ipar[2];
 nech=block->ipar[3];
 init_c=block->ipar[4];
 nb_coef=block->ipar[5];
 m1=block->ipar[6];
 flag_seq=block->ipar[7];

 /*Récupération des adresses des ports réguliers*/
 y1=(double *)block->outptr[0];
 if (n>1) y2=(double *)block->outptr[1];
 z=block->z;

 /* init : fait l'allocation de work */
 if (flag==4) {
  if(!flag_seq) {
   /*fprintf(stderr,"n=%d\n",n);*/
   /*fait un test sur filtre*/
   if(m1!=0) {
    /*fait un test sur nombre d'état*/
    if(n>1) {
     /*Allocation de 2*(3*2) vecteurs de taille m1*/
     if ((*block->work=scicos_malloc(sizeof(double)*(m1*2*(2*3))))== NULL) {
      set_block_error(-16);
      return;
     }
    }
    /*Allocation de (3*2) vecteurs de taille m1*/
    else {
     if ((*block->work=scicos_malloc(sizeof(double)*(m1*(2*3))))== NULL) {
      set_block_error(-16);
      return;
     }
    }
   }
  }
 }
 /* Le flag 1 calcule la valeur de I et de Q en fonction
  * du numéro symbole u[] et du nombre du nombre d'état m
  */
 else if (flag==1) {

  /********/
  /*Scalar*/
  /********/
  if(flag_seq)
  {
   /*fprintf(stderr,"flag_seq=%d,n=%d,nu=%d,nb_coef=%d,nz=%d\n",flag_seq,n,nu,nb_coef,block->nz);*/
   if((int)block->z[0]==nech)
   {
    block->z[0]=1; /*RAZ compteur*/
    if (nu>0)
    {
     if (n>1)
     {
      /*Appel genint*/
      genint_c(&nu,&mu,&n,(k=1,&k),&y1[0]);

      /*Appel routine modpsk*/
      modpsk_c(&nu,&mu,&m,&y1[0],&y1[0],&y2[0]);
     }
     else genint_c(&nu,&mu,&n,(k=0,&k),&y1[0]);
    }
    else
    {
     /*déclaration*/
     double *u;
     /*Récupération de l'adresse du port d'entrée*/
     u=(double *)block->inptr[0];
     /*récupération de la taille du port d'entrée*/
     nu=block->insz[0];
     /*Recopie u[] dans y1[]*/
     y1[0]=u[0];
     if (n>1)
      /*Appel routine modpsk*/
      modpsk_c(&nu,&mu,&m,&y1[0],&y1[0],&y2[0]);
    }
   }
   else
   {
    y1[0]=0;
    if(n>1) y2[0]=0;

    block->z[0]++; /*incrémente compteur*/
   }
   if (nu<=0)
    /*récupération de la taille du port d'entrée*/
    nu=block->insz[0];

   if (nb_coef!=0)
   {
    /*Appel nfilter : TODO correction flag1/2*/
    nfilter_c(&nu,&mu,&nb_coef,&y1[0],&block->rpar[0],&y1[0],&block->z[1]);
    if (n>1) {
      nfilter_c(&nu,&mu,&nb_coef,&y2[0],&block->rpar[0],&y2[0],&block->z[nb_coef+1]);
    }
   }
  }
  /********/
  /*Vector*/
  /********/
  else
  {
   /*fprintf(stderr,"n=%d\n",n);*/
   if(m1!=0) /*fait un test sur filtre*/
   {
    if(n>1) /*fait un test sur nombre d'état*/
    {
     /*Allocation de 2*(3*2) vecteurs de taille m1*/
     if ((*block->work=scicos_malloc(sizeof(double)*(m1*2*(2*3))))== NULL)
     {
      set_block_error(-16);
      return;
     }
    }
    else
    {
     /*Allocation de (3*2) vecteurs de taille m1*/
     if ((*block->work=scicos_malloc(sizeof(double)*(m1*(2*3))))== NULL)
     {
      set_block_error(-16);
      return;
     }
    }
    /*Récupération de l'adresse de départ du vecteur alloué*/
    z__=*block->work;

    /*Déclaration de pointeurs auxiliaires*/
    zi1_r = &(z__[0])   ; zi1_i = &(z__[m1]);   /*vecteur voie i du complexe 1*/
    zi2_r = &(z__[2*m1]); zi2_i = &(z__[3*m1]); /*vecteur voie i du complexe 2*/
    yi_r  = &(z__[4*m1]); yi_i  = &(z__[5*m1]); /*vecteur voie i du complexe résultat*/
    if(n>1)
    {
     zq1_r = &(z__[6*m1]); zq1_i = &(z__[7*m1]);   /*vecteur voie q du complexe 1*/
     zq2_r = &(z__[8*m1]); zq2_i = &(z__[9*m1]); /*vecteur voie q du complexe 2*/
     yq_r  = &(z__[10*m1]); yq_i  = &(z__[11*m1]); /*vecteur voie q du complexe résultat*/
    }
   }
   else
   {
    zi1_r = &(y1[0]); yi_r  = &(z[0]); /*vecteur voie i*/
    if(n>1)
    {
     zq1_r = &(y2[0]); yq_r  = &(z[nb_coef]); /*vecteur voie q*/
    }
   }
   if (nu>0) /*fait un test sur présence port entrée*/
   {
    /*Appel genint_c*/
    if(n>1) genint_c(&nu,&mu,&n,(k=1,&k),&zi1_r[0]);
    else genint_c(&nu,&mu,&n,(k=0,&k),&zi1_r[0]);
   }
   else if(nu==0)
   {
    /*déclaration*/
    double *u;
    /*Récupération de l'adresse du port d'entrée*/
    u=(double *)block->inptr[0];
    /*récupération de la taille du port d'entrée*/
    nu=block->insz[0];
    /*Recopie u[] dans zi1_r[]*/
    C2F(dcopy)(&nu,&u[0],(k=1,&k),&zi1_r[0],(k=1,&k));
   }

   if(n>1)
   /*Appel routine modpsk*/
    modpsk_c(&nu,&mu,&m,&zi1_r[0],&yi_r[0],&yq_r[0]);
   else
    /*Recopie zi1_r[] dans yi_r[]*/
    C2F(dcopy)(&nu,&zi1_r[0],(i=1,&i),&yi_r[0],(k=1,&k));

   /*Appel routine surecht_c*/
   surecht_c((opt=1,&opt),&nu,&mu,&nech,&init_c,&yi_r[0],&zi1_r[0]);
   if(n>1) surecht_c((opt=1,&opt),&nu,&mu,&nech,&init_c,&yq_r[0],&zq1_r[0]);

   if(m1!=0)
   {
    /*Recopie rpar[] dans zi2_r[] et zq2_r*/
    C2F(dcopy)(&nb_coef,&(block->rpar[0]),(k=1,&k),&zi2_r[0],(k=1,&k));
    if(n>1) C2F(dcopy)(&nb_coef,&(block->rpar[0]),(i=1,&i),&zq2_r[0],(k=1,&k));

    /* initialize fft_pr*/
    fft_pr.lfft   = m1;
    fft_pr.ffttyp = 0;

    /*Appel convolr_c*/
    convolr_c((k=nu*nech,&k),&nb_coef,&m1,&zi1_r[0],&zi1_i[0],&zi2_r[0],&zi2_i[0],&yi_r[0],&yi_i[0],&z[0],&fft_pr);
    if(n>1) convolr_c((k=nu*nech,&k),&nb_coef,&m1,&zq1_r[0],&zq1_i[0],&zq2_r[0],&zq2_i[0],&yq_r[0],&yq_i[0],&z[nb_coef],&fft_pr);

    /*Recopie y_r[] dans y[]*/
    C2F(dcopy)(&ny,&yi_r[0],(k=1,&k),&y1[0],(k=1,&k));
    if(n>1) C2F(dcopy)(&ny,&yq_r[0],(i=1,&i),&y2[0],(k=1,&k));
   }
  }
 }
 /*Terminaison */
 else if (flag==5) {
  if(!flag_seq) {
   /*fait un test sur filtre*/
   if(m1!=0) {
    /*Libère mémoire allouée*/
    scicos_free(*block->work);
   }
  }
 }
}