Clean up; re-worked tfsk.c to run mod/demod and run untethered
authorbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 22 Jan 2016 23:32:51 +0000 (23:32 +0000)
committerbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 22 Jan 2016 23:32:51 +0000 (23:32 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2644 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/tfsk.m
codec2-dev/src/CMakeLists.txt
codec2-dev/src/fsk.c
codec2-dev/src/fsk_demod.c
codec2-dev/src/fsk_mod.c
codec2-dev/unittest/tfsk.c

index 9271213256de351344c4870bce93272fe841bb9d..55f1c1c9eb0e5a3b77ac8e5bdf0b26479cd27d42 100644 (file)
@@ -36,7 +36,7 @@
 % FSK Modem test instructions --
 % 1 - Compile tfsk.c and fm_mod.c
 %     - tfsk.c is in unittest/, so build must not be configured for release
-% 2 - Change tfsk_location and fsk_mod_location to point to tfsk and fsk_mod
+% 2 - Change tfsk_location and fsk_mod_location to point to tfsk
 % 3 - Ensure octave packages signal and parallel are installed
 % 4 - run tfsk.m. It will take care of the rest.
 %
@@ -44,8 +44,6 @@
 %tfsk executable path/file
 global tfsk_location = '../build/unittest/tfsk';
 
-%fsk_mod path/file
-global fsk_mod_location = '../build/src/fsk_mod';
 
 
 fsk_horus_as_a_lib = 1; % make sure calls to test functions at bottom are disabled
@@ -58,11 +56,9 @@ graphics_toolkit('gnuplot');
 global mod_pass_fail_maxdiff = 1e-3/50000;
 
 function mod = fsk_mod_c(Fs,Rs,f1,f2,bits)
-    
-    global fsk_mod_location;
+    global tfsk_location;
     %command to be run by system to launch the modulator
-    command = sprintf('%s %d %d %d %d fsk_mod_ut_bitvec fsk_mod_ut_modvec',fsk_mod_location,Fs,Rs,f1,f2);
-    
+    command = sprintf('%s M %d %d %d %d fsk_mod_ut_bitvec fsk_mod_ut_modvec fsk_mod_ut_log.txt',tfsk_location,f1,f2,Fs,Rs);
     %save input bits into a file
     bitvecfile = fopen('fsk_mod_ut_bitvec','wb+');
     fwrite(bitvecfile,bits,'uint8');
@@ -119,7 +115,7 @@ function test_stats = fsk_demod_xt(Fs,Rs,f1,f2,mod,tname)
     tvecfilename = sprintf('fsk_demod_ut_tracevec_%d.txt',getpid());
     
     %command to be run by system to launch the demod
-    command = sprintf('%s %d %d %d %d %s %s %s',tfsk_location,Fs,Rs,f1,f2,modvecfilename,bitvecfilename,tvecfilename);
+    command = sprintf('%s D %d %d %d %d %s %s %s',tfsk_location,f1,f2,Fs,Rs,modvecfilename,bitvecfilename,tvecfilename);
     
     %save modulated input into a file
     modvecfile = fopen(modvecfilename,'wb+');
@@ -406,4 +402,4 @@ function pass = test_fsk_battery()
     end
 endfunction
 
-test_fsk_battery
+%test_fsk_battery
index 6fe28f9df32fb6d6f8e0ec89536a68f56c7b111b..94a49c9a47eb346ef9f4a121c7343bfa1b01affe 100644 (file)
@@ -238,7 +238,7 @@ target_link_libraries(freedv_rx ${CMAKE_REQUIRED_LIBRARIES} codec2)
 add_executable(fsk_mod fsk_mod.c)
 target_link_libraries(fsk_mod ${CMAKE_REQUIRED_LIBRARIES} codec2)
 
-add_executable(fsk_demod fsk_demod.c)
+add_executable(fsk_demod fsk_demod.c modem_probe.c octave.c)
 target_link_libraries(fsk_demod ${CMAKE_REQUIRED_LIBRARIES} codec2)
 
 add_executable(fm_demod fm_demod.c fm.c)
index 77db4a17fbf35d41af5eb34c38dc2d8fb1608296..eb12d4e2f48b02ef044aa384b653462fb4253444 100644 (file)
@@ -511,6 +511,11 @@ void fsk_demod(struct FSK *fsk, uint8_t rx_bits[], float fsk_in[]){
         /* THE BIT! */
         rx_bits[i] = comp_mag_gt(t2,t1)?1:0;
         /* Soft output goes here */
+        
+        /* Log the bit */
+        /* We must do some bit monkeying here, as rx_bits is uint8 while samp_i expects an int32 */
+        j = rx_bits[i]>0;
+        modem_probe_samp_i("t_rxbit",&j,1);
     }
     
     #ifdef EST_EBNO
@@ -567,17 +572,22 @@ void fsk_mod(struct FSK *fsk,float fsk_out[],uint8_t tx_bits[]){
     for(i=0; i<fsk->Nsym; i++){
         /* select current bit phase shift */
         dph = tx_bits[i]==0?dosc_f1:dosc_f2;
+        
+        /* Log the bit being modulated */
+        j = tx_bits[i]>0;
+        modem_probe_samp_i("t_txbit",&j,1);
+        
         for(j=0; j<Ts; j++){
             tx_phase_c = cmult(tx_phase_c,dph);
             fsk_out[i*Ts+j] = 2*tx_phase_c.real;
         }
     }
     
-    /* Normalize TX phase to prevent drift */
-    tx_phase_c = comp_normalize(tx_phase_c);
+    /* Log the modulated samples */
+    modem_probe_samp_f("t_txmod",fsk_out,fsk->N);
     
     /* save TX phase */
-    fsk->tx_phase_c = tx_phase_c;
+    fsk->tx_phase_c = comp_normalize(tx_phase_c);
     
 }
 
index 29e35c3c8e5bc4504c6560a35da7cd8c4f9f58f1..56679f3531161c805d0b422314ce29d067b1ebf4 100644 (file)
@@ -29,6 +29,8 @@
 
 #include <stdio.h>
 #include "fsk.h"
+
+#define MODEMPROBE_ENABLE
 #include "modem_probe.h"
 
 int main(int argc,char *argv[]){
@@ -38,26 +40,24 @@ int main(int argc,char *argv[]){
     uint8_t *bitbuf;
     float *modbuf;
     
-    if(argc<7){
-        printf("Usage: %s samplerate bitrate f1 f2 rffile bitfile [probefile]\n",argv[0]);
+    if(argc<5){
+        printf("usage: %s SampleFreq SymbolFreq InputModemRawFile OutputOneBitPerCharFile [OctaveLogFile]\n",argv[0]);
         exit(1);
     }
     
     /* Extract parameters */
     Fs = atoi(argv[1]);
     Rs = atoi(argv[2]);
-    f1 = atoi(argv[3]);
-    f2 = atoi(argv[4]);
     
     /* Open files */
-    fin = fopen(argv[5],"r");
-    fout = fopen(argv[6],"w");
+    fin = fopen(argv[3],"r");
+    fout = fopen(argv[4],"w");
     
-    if(argc>7)
-               modem_probe_init("fsk2",argv[7]);
+    if(argc>5)
+               modem_probe_init("fsk2",argv[5]);
        
     /* set up FSK */
-    fsk = fsk_create(Fs,Rs,f1,f2);
+    fsk = fsk_create(Fs,Rs,0,0);
     
     if(fin==NULL || fout==NULL || fsk==NULL){
         printf("Couldn't open test vector files\n");
index 2fafbde374af5a7b9fcafb7aa8f685c4802e2c88..8cfb51496a84c32d8c2e12a365575e9f8664ab9f 100644 (file)
@@ -39,7 +39,7 @@ int main(int argc,char *argv[]){
     float *modbuf;
     
     if(argc<7){
-        printf("Usage: %s samplerate bitrate f1 f2 bitfile modfile\n",argv[0]);
+        printf("usage: %s SampleFreq SymbolFreq TxFreq1 TxFreq2 InputOneBitPerCharFile OutputModFloatFile\n",argv[0]);
         exit(1);
     }
     
index c31996c1836e85696ccf2bf82c93ef41e33472a6..52195f69896682a9a36c2ce1ccd23c6adf85a80a 100644 (file)
 /* Note: This is a dirty hack to force fsk.c to compile with modem probing enabled */
 #include "fsk.c"
 
+#define ST_BITS 10000
+#define ST_FS 8000
+#define ST_RS 100
+#define ST_F1 1200
+#define ST_F2 1600
+#define ST_EBNO 8
+
+#define TEST_SELF_FULL 1    /* No-arg self test */
+#define TEST_MOD 2          /* Test modulator using in and out file */
+#define TEST_DEMOD 3        /* Test demodulator using in and out file */
+
 
 int main(int argc,char *argv[]){
     struct FSK *fsk;
     int Fs,Rs,f1,f2;
     FILE *fin,*fout;
-    uint8_t *bitbuf;
-    float *modbuf;
+
+    uint8_t *bitbuf = NULL;
+    float *modbuf = NULL;
+    uint8_t *bitbufp;
+    float *modbufp;
+
+    size_t bitbufsize = 0;
+    size_t modbufsize = 0;
+
+    int test_type;
     
-    if(argc<7){
-        printf("Usage: %s samplerate bitrate f1 f2 infile outfile [probefile]\n",argv[0]);
+    int i;
+    
+    fin = NULL;
+    fout = NULL;
+    
+    /* Set up full self-test */
+    if(argc == 1){
+        test_type = TEST_SELF_FULL;
+        modem_probe_init("fsk2","fsk2_tfsk_log.txt");
+        Fs = ST_FS;
+        Rs = ST_RS;
+        f1 = ST_F1;
+        f2 = ST_F2;
+        
+    } else if (argc<8){
+    /* Not running any test */
+        printf("Usage: %s [(M|D) TXFreq1 TXFreq2 SampleRate BitRate InputFile OutputFile OctaveLogFile]\n",argv[0]);
         exit(1);
+    } else {
+    /* Running stim-drivin test */
+        /* Mod test */
+        if(strcmp(argv[1],"M")==0 || strcmp(argv[1],"m")==0) {
+            test_type = TEST_MOD;
+        /* Demod test */
+        } else if(strcmp(argv[1],"D")==0 || strcmp(argv[1],"d")==0) {
+            test_type = TEST_DEMOD;
+        } else {
+            printf("Must specify mod or demod test with M or D\n");
+            exit(1);
+        }
+        /* Extract parameters */
+        Fs = atoi(argv[4]);
+        Rs = atoi(argv[5]);
+        f1 = atoi(argv[2]);
+        f2 = atoi(argv[3]);
+        
+        /* Open files */
+        fin = fopen(argv[6],"r");
+        fout = fopen(argv[7],"w");
+        
+        if(fin == NULL || fout == NULL){
+            printf("Couldn't open test vector files\n");
+            exit(1);
+        }
+        /* Init modem probing */
+        modem_probe_init("fsk2",argv[8]);
+        
     }
     
-    /* Extract parameters */
-    Fs = atoi(argv[1]);
-    Rs = atoi(argv[2]);
-    f1 = atoi(argv[3]);
-    f2 = atoi(argv[4]);
-    
-    /* Open files */
-    fin = fopen(argv[5],"r");
-    fout = fopen(argv[6],"w");
+       srand(1);
     
-    if(argc>7)
-               modem_probe_init("fsk2",argv[7]);
-       
     /* set up FSK */
     fsk = fsk_create(Fs,Rs,f1,f2);
     
-    if(fin==NULL || fout==NULL || fsk==NULL){
-        printf("Couldn't open test vector files\n");
-        goto cleanup;
+    /* Modulate! */
+    if(test_type == TEST_MOD || test_type == TEST_SELF_FULL){
+        /* Generate random bits for self test */
+        if(test_type == TEST_SELF_FULL){
+            bitbufsize = ST_BITS;
+            bitbuf = (uint8_t*) malloc(sizeof(uint8_t)*ST_BITS);
+            for(i=0; i<ST_BITS; i++){
+                /* Generate a randomish bit */
+                bitbuf[i] = (uint8_t)(rand()&0x01);
+            }
+        } else { /* Load bits from a file */
+            /* Figure out how many bits are in the input file */
+            fseek(fin, 0L, SEEK_END);
+            bitbufsize = ftell(fin);
+            fseek(fin, 0L, SEEK_SET);
+            bitbuf = malloc(sizeof(uint8_t)*bitbufsize);
+            i = 0;
+            /* Read in some bits */
+            bitbufp = bitbuf;
+            while( fread(bitbufp,sizeof(uint8_t),fsk->Nsym,fin) == fsk->Nsym){
+                i++;
+                bitbufp+=fsk->Nsym;
+                /* Make sure we don't break the buffer */
+                if(i*fsk->Nsym > bitbufsize){
+                    bitbuf = realloc(bitbuf,sizeof(uint8_t)*(bitbufsize+fsk->Nsym));
+                    bitbufsize += fsk->Nsym;
+                }
+            }
+        }
+        /* Allocate modulation buffer */
+        modbuf = (float*)malloc(sizeof(float)*(bitbufsize/fsk->Nsym)*fsk->N*4);
+        modbufsize = (bitbufsize*fsk->Ts);
+        /* Do the modulation */
+        modbufp = modbuf;
+        bitbufp = bitbuf;
+        while( bitbufp < bitbuf+bitbufsize){
+            fsk_mod(fsk, modbufp, bitbufp);
+            modbufp += fsk->N;
+            bitbufp += fsk->Nsym;
+        }
+        /* For a mod-only test, write out the result */
+        if(test_type == TEST_MOD){
+            fwrite(modbuf,sizeof(float),modbufsize,fout);
+            free(modbuf);
+        }
+        /* Free bit buffer */
+        free(bitbuf);
     }
     
-    /* allocate buffers for processing */
-    bitbuf = (uint8_t*)alloca(sizeof(uint8_t)*fsk->Nsym);
-    modbuf = (float*)alloca(sizeof(float)*(fsk->N+fsk->Ts*2));
+    /* Add channel imp here */
     
-    /* Demodulate! */
-    while( fread(modbuf,sizeof(float),fsk_nin(fsk),fin) == fsk_nin(fsk) ){
-        fsk_demod(fsk,bitbuf,modbuf);
-        fwrite(bitbuf,sizeof(uint8_t),fsk->Nsym,fout);
+    
+    /* Now test the demod */
+    if(test_type == TEST_DEMOD || test_type == TEST_SELF_FULL){
+        free(modbuf);
+        modbuf = malloc(sizeof(float)*(fsk->N+fsk->Ts*2));
+        bitbuf = malloc(sizeof(uint8_t)*fsk->Nsym);
+        /* Demod-only test */
+        if(test_type == TEST_DEMOD){
+            while( fread(modbuf,sizeof(float),fsk_nin(fsk),fin) == fsk_nin(fsk) ){
+                fsk_demod(fsk,bitbuf,modbuf);
+                fwrite(bitbuf,sizeof(uint8_t),fsk->Nsym,fout);
+            }
+        }
+        /* Demod after channel imp. and mod */
+        else{
+            bitbufp = bitbuf;
+            modbufp = modbuf;
+            while( modbufp < modbuf + modbufsize){
+                fsk_demod(fsk,bitbuf,modbuf);
+                modbufp += fsk_nin(fsk);
+            }
+        }
+        free(bitbuf);
     }
     
     modem_probe_close();
-    cleanup:
-    fclose(fin);
-    fclose(fout);
+    if(test_type == TEST_DEMOD || test_type == TEST_MOD){
+        fclose(fin);
+        fclose(fout);
+    }
     fsk_destroy(fsk);
     exit(0);
 }