/* Modnumlib Scicos interfacing function * Copyright (C) 2009 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); } } } }