/**************************************************************************** This is a MSK ( Minimum Shift Keying ) Modulator and Demodulator in C. It comes with an additional test framework. version 0.2 no cosf, sinf, some integer calc version 0.1 It is using two tones ( 1200Hz, 2400Hz ) for a datarate of 2400 Bit/s at a samplerate of 14.4ks/s . It is performing close to theory in terms of bit error rate ( BER ) versus signal to noise ratio (SNR). This is a work sample, it demonstrates some of my signal processing skills. Feel free to inspect it, learn from it and use it for your private purposes. If you find it useful to serve your commercial needs or if you have similar problems to solve pls. contact me: detlef.schuecker@gmx.de Cheers, have fun Detlef *****************************************************************************/ #include #include #include #include #include typedef struct fcomplex { float re; float im; } fcomplex_t; typedef struct i16complex { int16_t re; int16_t im; } i16complex_t; typedef struct i32complex { int32_t re; int32_t im; } i32complex_t; #define PI (3.14159265358979f) #define ZWOPI (2.0f*PI) #define F1200 (ZWOPI*(1200.0f/14400.0f)) #define F2400 (ZWOPI*(2400.0f/14400.0f)) #define F2600 (ZWOPI*(2600.0f/14400.0f)) #define F1800 (ZWOPI*(1800.0f/14400.0f)) #define NSH (14) #define NORM ((int16_t)(1<>NSH;hi.im=hh.im>>NSH;\ hh.re=hi.re*hi.re+hi.im*hi.im; \ if(hh.re > (uint32_t)(1.01f*((int32_t)NORM*(int32_t) NORM))) {\ hi.re = (hi.re*((int32_t)((1.0f-0.001f)*NORM)))>>NSH;\ hi.im = (hi.im*((int32_t)((1.0f-0.001f)*NORM)))>>NSH;\ }\ if(hh.re < (uint32_t)(0.99f*((int32_t)NORM*(int32_t) NORM))){ \ hi.re = (hi.re*((int32_t)((1.0f+0.001f)*NORM)))>>NSH;\ hi.im = (hi.im*((int32_t)((1.0f+0.001f)*NORM)))>>NSH;\ }\ _a.re=hi.re;\ _a.im=hi.im;\ } #define RECEIVERLOCKED (0x00000001) #define RECEIVERLOSTLOCK (0x00000002) uint32_t bb; // random Bitgenerator variable, only for testing FILE * fo; // debug file /******************************************************************/ float myatan2(float y, float x){ /******************************************************************/ //http://pubs.opengroup.org/onlinepubs/009695399/functions/atan2.html //Volkan SALMA float ONEQTR_PI = PI / 4.0f; float THRQTR_PI = 3.0f * PI / 4.0f; float aangle,r; float abs_y = abs(y) + 1e-10; // kludge to prevent 0/0 condition if ( x < 0.0f ){ r = (x + abs_y) / (abs_y - x); aangle = THRQTR_PI; } else { r = (x - abs_y) / (x + abs_y); aangle = ONEQTR_PI; } aangle = aangle+ (0.1963f * r * r - 0.9817f) * r; if ( y < 0.0f ) return -aangle; else return aangle; } /******************************************************************/ void transmitter( int16_t * samples, // Pointer to samples, Output uint8_t * data , // bits to be transmitted, MSB first,Input uint32_t n , // Number of !! BITS !! to be transmitted uint16_t amp , // amplitude uint8_t reset , // give it a fresh start int16_t carrieroffset // Hertz ) /*****************************************************************/ { static fcomplex_t phase = {1.0f, 0.0f}; /* not much offset allowed */ #define FFAK (1.00f) fcomplex_t slow = {cosf(FFAK*ZWOPI*1200.0f/(14400.0f+carrieroffset)), sinf(FFAK*ZWOPI*1200.0f/(14400.0f+carrieroffset))}; fcomplex_t fast = {cosf(FFAK*ZWOPI*2400.0f/(14400.0f+carrieroffset)), sinf(FFAK*ZWOPI*2400.0f/(14400.0f+carrieroffset))}; uint32_t k,m; uint8_t ui; if(reset){ phase.re=1.0f; phase.im=0.0f; } for(k=0;k>(7-(k%8)))&1); //fprintf(fo,"%d\n",ui); for(m=0;m<6;m++){ if(ui) // CCIR Rec 623 "1" Mark, 1200,"0" Space, 2400, CROT(phase,slow) else CROT(phase,fast) samples[6*k+m]=(int16_t)(phase.re*amp); } } } /******************************************************************/ void itransmitter( int16_t * samples, // Pointer to samples, Output uint8_t * data , // bits to be transmitted, MSB first,Input uint32_t n , // Number of !! BITS !! to be transmitted uint16_t amp , // amplitude uint8_t reset , // give it a fresh start int16_t carrieroffset // Hertz ) /*****************************************************************/ { static i16complex_t phase = {(int16_t)(NORM*1.0f), 0}; i16complex_t slow = {(int16_t)(NORM*cosf(ZWOPI*1200.0f/(14400.0f+carrieroffset))), (int16_t)(NORM*sinf(ZWOPI*1200.0f/(14400.0f+carrieroffset)))} ; i16complex_t fast = {(int16_t)(NORM*cosf(ZWOPI*2400.0f/(14400.0f+carrieroffset))), (int16_t)(NORM*sinf(ZWOPI*2400.0f/(14400.0f+carrieroffset)))} ; uint32_t k,m; uint8_t ui; if(reset){ phase.re=(int16_t)(NORM*1.0f); phase.im=0; } for(k=0;k>(7-(k%8)))&1); //fprintf(fo,"%d\n",ui); for(m=0;m<6;m++){ if(ui) // CCIR Rec 623 "1" Mark, 1200,"0" Space, 2400, iCROT(phase,slow) else iCROT(phase,fast) samples[6*k+m]=(int16_t)(((int32_t)phase.re*amp)>>NSH); } } } /******************************************************************/ void receiver_workingcopy( int16_t * samples, // Pointer to samples, Input uint8_t * data , // received bits , MSB first,Output uint32_t n , // Number of samples, input uint32_t * nbit , // Number of received Bits, Output uint32_t * receiverstatus , // Output uint8_t reset // give it a fresh start ) /*****************************************************************/ { // static stuff static int32_t T4i =0; static int32_t T4alti=0; static int32_t T11i=0; static int32_t T10i=0; static i32complex_t T2i={16384,0}; // 2400 Hz local osc. static i32complex_t T3i={16384,0}; // 1800 Hz local osc. static int32_t eei=0; static int32_t stelli=0; static int32_t T1i=232647260; // PLL Integrator, ini to 2400Hz static float T1 = F2400; // PLL Integrator static fcomplex_t T2 = {1.0f, 0.0f}; // PLL 2400 phase static fcomplex_t T3 = {1.0f, 0.0f}; // PLL 1800 phase static float Exx = 0.0f; // mean x squared static float Ex = 0.0f; // mean x static uint8_t locked = 0; // PLL locked // carrier recovery filter static float tub0=0.0f,tub1=0.0f,tua0=0.0f,tua1=0.0f; // Symbol recovery complex filter static float tvrb0=0.0f,tvrb1=0.0f,tvrb2=0.0f,tvrb3=0.0f; static float tvra0=0.0f,tvra1=0.0f,tvra2=0.0f,tvra3=0.0f; static float tvib0=0.0f,tvib1=0.0f,tvib2=0.0f,tvib3=0.0f; static float tvia0=0.0f,tvia1=0.0f,tvia2=0.0f,tvia3=0.0f; #define fslica1 1.000000000000000.0f #define fslica2 -2.4142708770418880f #define fslica3 2.385881722014404f #define fslica4 -1.098144662819239f #define fslica5 0.196653281037087f #define fslicb1 0.004382466449398f #define fslicb2 0.017529865797591f #define fslicb3 0.026294798696386f #define fslicb4 (fslicb2) #define fslicb5 (fslicb1) static uint32_t samplecnt =0; // symbol slicer static fcomplex_t oldsam[7] = // oldsamples {{1.0f,0.0f},{1.0f,0.0f},{1.0f,0.0f},{1.0f,0.0f}, {1.0f,0.0f},{1.0f,0.0f},{1.0f,0.0f}}; static float oldang[6] = // old angles {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f}; static float Exxslice[6] = // energy symbol offset {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f}; static float maxxslice = 0.0f; static uint8_t maxxindslice ; // ************** // local stuff int32_t rri; float rrf ; uint32_t k,m; int32_t rr1i; uint8_t ui; float fx,rr18,rr19,r,s; float sfak,fak,x,varvar; float rrr16,rri16,rrr22,rri22; fcomplex_t hilraus; fcomplex_t cpl1,cpl2,cpl3,cpl4,cpl5; // ************** // reset the machine if(reset){ T4i =0; T4alti=0; T11i=0; T10i=0; T2i.re=16384; // 2400 Hz local osc. T2i.im=0; // 2400 Hz local osc. T3i.re=16384; // 1800 Hz local osc. T3i.im=0; // 1800 Hz local osc. eei=0; stelli=0; T1i=232647260; // PLL Integrator, ini to 2400Hz T1 = F2400; // PLL Integrator T2.re = 1.0f; // PLL 2400 phase T2.im = 0.0f; // PLL 2400 phase T3.re = 1.0f; // PLL 1800 phase T3.im = 0.0f; // PLL 1800 phase Exx = 0.0f; // mean x squared Ex = 0.0f; // mean x locked = 0; // PLL locked // carrier recovery filter tub0=0.0f;tub1=0.0f;tua0=0.0f;tua1=0.0f; // Symbol recovery complex filter tvrb0=0.0f;tvrb1=0.0f;tvrb2=0.0f;tvrb3=0.0f; tvra0=0.0f;tvra1=0.0f;tvra2=0.0f;tvra3=0.0f; tvib0=0.0f;tvib1=0.0f;tvib2=0.0f;tvib3=0.0f; tvia0=0.0f;tvia1=0.0f;tvia2=0.0f;tvia3=0.0f; samplecnt =0; // symbol slicer for(m=0;m<6;m++){ oldsam[m].re = 1.0f; oldsam[m].im = 0.0f; oldang[m] = 0.0f; Exxslice[m] = 0.0f; } maxxslice = 0.0f; } // reset the machine // ************** // receiver start nbit[0]=0; for(k=0;k>9)- (((((int32_t)( 0.970225f*16384.0f)*T11i))+ (((int32_t)(-0.985f *16384.0f)*T10i)))>>14); T4i=T10i-T11i; T11i=T10i; T10i=rri; eei= ((T4alti-T4i)*T2i.re-T4i*T2i.im)>>14; T1i+=eei; T4alti=T4i; stelli=((6*10*49*eei)>>17)+(T1i>>15); // rotieren 2400Hz LO cpl4.re=(float)4096.0f; cpl4.im=(float)stelli; rrf=sqrtf((float)(cpl4.re)*(cpl4.re)+(float)(cpl4.im)*(cpl4.im)); if(rrf>0.0)rrf=1.0/rrf; cpl4.re *= rrf; cpl4.im *= rrf; CROT(T2,cpl4) T2i.re = (int32_t)(T2.re*16384.0); T2i.im = (int32_t)(T2.im*16384.0); // rotieren 1800Hz LO cpl3.re = cpl4.re; // normiert cpl3.im = cpl4.im; cpl4.re=sqrtf((1.0f+cpl3.re)/2.0f); cpl4.im=sqrtf((1.0f-cpl3.re)/2.0f); cpl5.re=sqrtf((1.0f+cpl4.re)/2.0f); cpl5.im=sqrtf((1.0f-cpl4.re)/2.0f); CMUL(cpl5,cpl5,cpl4); CMUL(cpl4,cpl5,cpl3); CROT(T3,cpl3); // Todo /* sfak = T1i; fak = (1.0f/128.0f); Exx=Exx+sfak*sfak-Exx*fak; Ex =Ex +sfak -Ex*fak; varvar=Exx*fak-(Ex*fak)*(Ex*fak); */ receiverstatus[0] |= RECEIVERLOCKED; // Mix with carrier //rr16= smk15(k)*rr32; cpl1.re=(float)samples[k]; cpl1.im=0.0f; CMUL(cpl1,T3,cpl2); //fprintf(fo,"%.5f %.5f ",cpl2.re,cpl2.im); // symbol filter, complex rrr16=cpl2.re; rrr22 = rrr16*fslicb1 + tvrb0*fslicb2 + tvrb1*fslicb3 + tvrb2*fslicb4 + tvrb3*fslicb5 - tvra0*fslica2 - tvra1*fslica3 - tvra2*fslica4 - tvra3*fslica5 ; tvra3=tvra2;tvra2=tvra1;tvra1=tvra0;tvra0=rrr22; tvrb3=tvrb2;tvrb2=tvrb1;tvrb1=tvrb0;tvrb0=rrr16; rri16=cpl2.im; rri22 = rri16*fslicb1 + tvib0*fslicb2 + tvib1*fslicb3 + tvib2*fslicb4 + tvib3*fslicb5 - tvia0*fslica2 - tvia1*fslica3 - tvia2*fslica4 - tvia3*fslica5 ; tvia3=tvia2;tvia2=tvia1;tvia1=tvia0;tvia0=rri22; tvib3=tvib2;tvib2=tvib1;tvib1=tvib0;tvib0=rri16; // symbol slicer m=samplecnt%6; oldsam[m].re=rrr22; oldsam[m].im=rri22; cpl1.re = rrr22; cpl1.im = rri22; cpl2.re = oldsam[((samplecnt+6-5)%6)].re; cpl2.im = -oldsam[((samplecnt+6-5)%6)].im; CMUL(cpl1,cpl2,cpl3); oldang[m]=myatan2(cpl3.im,cpl3.re); //fprintf(fo," %.5f \n",oldang[m+1]); Exxslice[m] = Exxslice[m]+oldang[m]*oldang[m]- Exxslice[m]*(1.0f/256.0f); if(Exxslice[m] > maxxslice){ // keep track of max energy maxxslice=Exxslice[m]; maxxindslice=m; } if(m==0){ // a Bit ! if(oldang[((samplecnt+5+maxxindslice)%6)]>0.0f){ //fprintf(fo,"1\n"); data[nbit[0]/8] |= ((uint8_t)(1 << (7-(nbit[0]%8)))); }else{ //fprintf(fo,"0\n"); data[nbit[0]/8] &= ~((uint8_t)(1 << (7-(nbit[0]%8)))); } nbit[0]++; }; samplecnt ++; // stay in 6-pace, no overflow if(samplecnt == 6*1000*1000) samplecnt -= 6*1000*1000; } // for loop //printf("maxindslice %d \n",maxxindslice); //printf("Exxslice %.2f %.2f %.2f %.2f %.2f %.2f \n", // Exxslice[0],Exxslice[1],Exxslice[2],Exxslice[3],Exxslice[4],Exxslice[5]); //fprintf(fo,"%.2f %.2f %.2f %.2f %.2f %.2f \n", // Exxslice[0],Exxslice[1],Exxslice[2],Exxslice[3],Exxslice[4],Exxslice[5]); } /********************************************/ /* Test helper functions */ /********************************************/ /********************************************/ uint8_t rndbit(void) /********************************************/ { //uint32_t bb=0x82ad6fb3; // random bits, LFSR maximum length sequence bb=((bb<<1)&0xfffffffe)| (~(((bb>>31)&1)^((bb>>22)&1)^((bb>>2)&1)^((bb>>1)&1)))&1; return (uint8_t)(bb&1); } /********************************************/ void fill_bits(uint8_t * bits, uint32_t n) /********************************************/ { uint32_t k; uint8_t bb; for(k=0;k1.0) return rndnormal(); c = sqrt(-2 * log(r) / r); c=u*c; // variance 1, almost return 0.013021*(1/sqrtf(1.03))*c; } /********************************************/ double filter( double * in, double * out, uint32_t n, double * forwardcoeff, double * backwardcoeff ) /********************************************/ // straight, 8th order, Matlab style //a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb) // - a(2)*y(n-1) - ... - a(na+1)*y(n-na) { static double x[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; static double y[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; //static uint16_t p=0; uint32_t m,k; double rr; for(k=0;k<8;k++) x[k]=0.0; for(k=0;k<8;k++) y[k]=0.0; for(m=0;mnb) {nn=na;na=nb;nb=nn;p=na;na=nb;nb=p;}; fmin=0x7fffffff; for(shift=-20;shift<20;shift++){ fehl=0; for(k=0;k>(7-(inda%8)))&1; bitb=(b[indb/8]>>(7-(indb%8)))&1; if(bita != bitb) fehl++; } if(fehl < fmin) fmin=fehl; } return fmin; } /******************************************/ int singletest(int32_t testn) /******************************************/ { uint32_t k,dev; double Esignal, Enoise; uint32_t nbitrec, receiverstatus; #define NBITS (100*1000) uint8_t * bits; uint8_t * bitsrec; int16_t * samples; double * dsamples; double * noise; double rr,rate; time_t t; double forwthru[9]={1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; double backthru[9]={1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; // Butterworth 200..3500Hz double forwbutter200[9]={ 7.151050071839755e-02,-0.000000000000000e+00,-2.860420028735902e-01,-0.000000000000000e+00, 4.290630043103853e-01,-0.000000000000000e+00,-2.860420028735902e-01,-0.000000000000000e+00, 7.151050071839755e-02}; double backbutter200[9]={ 1.000000000000000e+00,-3.978426671710780e+00,6.666849886878365e+00,-6.588601757555979e+00, 4.664599456204638e+00,-2.433350468434350e+00,7.858807726499508e-01,-1.366010436862025e-01 , 1.973000759266953e-02}; // Butterworth 0.3500Hz double forwbutter0[9]={ 7.763957595700134e-03,6.211166076560107e-02,2.173908126796038e-01,4.347816253592075e-01, 5.434770316990093e-01,4.347816253592075e-01,2.173908126796038e-01,6.211166076560107e-02, 7.763957595700134e-03 }; double backbutter0[9]={ 1.000000000000000e+00,-2.208266808777384e-01,1.080618168397128e+00,-1.651928879789531e-01, 3.007030646117298e-01,-2.834904302438379e-02,2.137351743894164e-02,-9.344604601704970e-04, 1.814663926804723e-04}; // Cauer 200..3500, 0.5dB ripple, 30dB att double forwcauer[9]={ 1.336054380095904e-01,-2.615253501102702e-01,8.586622226348152e-02,-1.214367821758216e-01, 3.269856188670165e-01,-1.214367821758223e-01,8.586622226348172e-02,-2.615253501102707e-01, 1.336054380095908e-01}; double backcauer[9]={ 1.000000000000000e+00,-4.338323362349132e+00,8.596720322660358e+00,-1.108827431446386e+01, 1.068615198920599e+01,-7.588975531115502e+00,3.729592811826362e+00,-1.205078704442726e+00, 2.083346201303393e-01}; // double forwband[9]={ 1.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0}; double backband[9]={ 1.0,-1.1314,0.64,0.0,0.0, 0.0,0.0,0.0,0.0}; //prerequisites printf("Test # %d\r\n",testn); // Ini random srand((unsigned) time(&t)); bb=rand(); //bb=1234; bits=malloc((NBITS/8+1)*sizeof(uint8_t)); if(bits==NULL) { printf("EEEEEEEEEE 1 \n"); return; } samples=malloc((NBITS*6+1000)*sizeof(int16_t)); if(samples==NULL) { printf("EEEEEEEEEE 2 \n"); return; } dsamples=malloc((NBITS*6+1000)*sizeof(double)); if(dsamples==NULL) { printf("EEEEEEEEEE 3 \n"); return; } noise=malloc((NBITS*6+1000)*sizeof(double)); if(noise==NULL) { printf("EEEEEEEEEE 4 \n"); return; } bitsrec=malloc((NBITS/8+1)*sizeof(uint8_t)); if(bitsrec==NULL) { printf("EEEEEEEEEE 5 \n"); return; } if((fo=fopen("t2t.txt","w"))==NULL){ printf("EEEEEEEEEE 6 \n");return(0);} fill_bits(bits,NBITS); /* for(k=0;k0.0) printf("SNR %.1f dB\n",10.0*log10(Esignal/Enoise)); else printf("no noise \n"); // no noise for(k=0;k<6*NBITS;k++){ dsamples[k]+=noise[k]; } // simulate channel; if(testn>=1)if(testn<=6) filter( dsamples,noise,6*NBITS,forwthru,backthru); if(testn==7) filter( dsamples,noise,6*NBITS,forwbutter0,backbutter0); if(testn==8) filter( dsamples,noise,6*NBITS,forwband,backband); if(testn==9) filter( dsamples,noise,6*NBITS,forwthru,backthru); if(testn==10) filter( dsamples,noise,6*NBITS,forwthru,backthru); for(k=0;k<6*NBITS;k++) dsamples[k]=noise[k]; //for(k=0;k<6*NBITS;k++) // fprintf(fo,"%.3e \n",dsamples[k]); // normalize rr=0.0; for(k=0;k<6*NBITS;k++) if(fabs(dsamples[k]>rr)) rr=fabs(dsamples[k]); //printf("maxx %f\n",rr); for(k=0;k<6*NBITS;k++) { samples[k]= (int16_t)((2047.0/rr)*dsamples[k]); //fprintf(fo,"%d %d \n",k,samples[k]); } //for(k=0;k<6*NBITS;k++) // fprintf(fo,"%d \n",samples[k]); receiverstatus = 0; receiver_workingcopy( samples, // Pointer to samples, Input bitsrec , // received bits , MSB first,Output 6*NBITS , // Number of samples, input & nbitrec , // Number of received Bits, Output & receiverstatus , // Output 1 // give it a fresh start ); dev=deviation( bitsrec, bits,NBITS,NBITS); rate=20*log10((double)dev/NBITS+1e-15); if(testn==1){ printf("Test 1 baseline %.1f / %d %.5f errors exspected 0.3\r\n", log10((double)dev+1.0),dev,(double)dev/NBITS); } if(testn==2){ printf("Test 2 baseline %.1f / %d errors exspected 1.0\r\n", log10((double)dev+1.0),dev); } if(testn==3){ printf("Test 3 baseline %.1f / %d errors exspected 1.9\r\n", log10((double)dev+1.0),dev); } if(testn==4){ printf("Test 4 baseline %.1f / %d errors exspected 2.3\r\n", log10((double)dev+1.0),dev); } if(testn==5){ printf("Test 5 baseline %.1f / %d errors exspected 2.7\r\n", log10((double)dev+1.0),dev); } if(testn==6){ printf("Test 6 baseline %.1f / %d errors exspected 3.8\r\n", log10((double)dev+1.0),dev); } if(testn==7){ printf("Test 7 cauer %.1f / %d errors exspected 2.5\r\n", log10((double)dev+1.0),dev); } if(testn==8){ printf("Test 8 no bandwidth %.1f / %d errors exspected 2.9\r\n", log10((double)dev+1.0),dev); } if(testn==9){ printf("Test carrier offset %.1f / %d errors exspected 3.1\r\n", log10((double)dev+1.0),dev); } if(testn==10){ printf("Test integer transmitter %.1f / %d errors exspected 2.9\r\n", log10((double)dev+1.0),dev); } //for(k=0;k>(7-(1<>(7-(1<0.0) printf("SNR %.1f dB\n",10.0*log10(Esignal/Enoise)); else printf("no noise \n"); // no noise for(k=0;k<6*NBITS;k++){ dsamples[k]+=noise[k]; //fprintf(fo,"%.2e \n",dsamples[k]); } // simulate channel; // Thru //double forw[9]={1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; //double back[9]={1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; // Butterworth 200..3500Hz /* double forw[9]={ 7.151050071839755e-02,-0.000000000000000e+00,-2.860420028735902e-01,-0.000000000000000e+00, 4.290630043103853e-01,-0.000000000000000e+00,-2.860420028735902e-01,-0.000000000000000e+00, 7.151050071839755e-02}; double back[9]={ 1.000000000000000e+00,-3.978426671710780e+00,6.666849886878365e+00,-6.588601757555979e+00, 4.664599456204638e+00,-2.433350468434350e+00,7.858807726499508e-01,-1.366010436862025e-01 , 1.973000759266953e-02}; */ // Butterworth 0.3500Hz /* double forw[9]={ 7.763957595700134e-03,6.211166076560107e-02,2.173908126796038e-01,4.347816253592075e-01, 5.434770316990093e-01,4.347816253592075e-01,2.173908126796038e-01,6.211166076560107e-02, 7.763957595700134e-03 }; double back[9]={ 1.000000000000000e+00,-2.208266808777384e-01,1.080618168397128e+00,-1.651928879789531e-01, 3.007030646117298e-01,-2.834904302438379e-02,2.137351743894164e-02,-9.344604601704970e-04, 1.814663926804723e-04}; */ // Cauer 200..3500, 0.5dB ripple, 30dB att double forw[9]={ 1.336054380095904e-01,-2.615253501102702e-01,8.586622226348152e-02,-1.214367821758216e-01, 3.269856188670165e-01,-1.214367821758223e-01,8.586622226348172e-02,-2.615253501102707e-01, 1.336054380095908e-01}; double back[9]={ 1.000000000000000e+00,-4.338323362349132e+00,8.596720322660358e+00,-1.108827431446386e+01, 1.068615198920599e+01,-7.588975531115502e+00,3.729592811826362e+00,-1.205078704442726e+00, 2.083346201303393e-01}; filter( dsamples,noise,6*NBITS,forw,back); for(k=0;k<6*NBITS;k++) dsamples[k]=noise[k]; //for(k=0;k<6*NBITS;k++) // fprintf(fo,"%.3e \n",dsamples[k]); // normalize rr=0.0; for(k=0;k<6*NBITS;k++) if(fabs(dsamples[k]>rr)) rr=fabs(dsamples[k]); printf("maxx %f\n",rr); for(k=0;k<6*NBITS;k++) samples[k]= (int16_t)((2047.0/rr)*dsamples[k]); //for(k=0;k<6*NBITS;k++) // fprintf(fo,"%d \n",samples[k]); receiverstatus = 0; receiver( samples, // Pointer to samples, Input bitsrec , // received bits , MSB first,Output 6*NBITS , // Number of samples, input & nbitrec , // Number of received Bits, Output & receiverstatus , // Output 1 // give it a fresh start ); dev=deviation( bitsrec, bits,NBITS,NBITS); //for(k=0;k>(7-(1<>(7-(1<