Improved framing and unit test; fixed header issue in cohpsk
authorbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 12 Apr 2016 00:05:28 +0000 (00:05 +0000)
committerbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 12 Apr 2016 00:05:28 +0000 (00:05 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2784 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/codec2_cohpsk.h
codec2-dev/src/freedv_vhf_framing.c
codec2-dev/src/freedv_vhf_framing.h
codec2-dev/unittest/tdeframer.c

index 42f6d18bfeb8e23c8476af7e0f09dcc862c013b7..3a0217200bb06c7e883f54b891e3c5ed921daf86 100644 (file)
@@ -53,7 +53,7 @@ void cohpsk_get_demod_stats(struct COHPSK *cohpsk, struct MODEM_STATS *stats);
 void cohpsk_set_verbose(struct COHPSK *coh, int verbose);
 void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[]);
 void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[],
-                          int *bit_errors, float rx_bits_sd[]);
+                          int *bit_errors, char rx_bits_sd[]);
 int cohpsk_error_pattern_size(void);
 void cohpsk_set_frame(struct COHPSK *coh, int frame);
 void fdmdv_freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs,
index 6b6161f56a8e2631f0ab0d148d22cf3b1cdf287f..14f54c1b8bc923bf4e1c5d9be4a0aee63da2638b 100644 (file)
@@ -207,14 +207,17 @@ struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type, int enabl
     struct freedv_vhf_deframer * deframer;
     uint8_t *bits,*invbits;
     int frame_size;
+    int uw_size;
     
     assert( (frame_type == FREEDV_VHF_FRAME_A) || (frame_type == FREEDV_HF_FRAME_B) );
     
     /* It's a Type A frame */
     if(frame_type == FREEDV_VHF_FRAME_A){
         frame_size = 96;
+        uw_size = 16;
     }else if(frame_type == FREEDV_HF_FRAME_B){
         frame_size = 64;
+        uw_size = 8;
     }else{
         return NULL;
     }
@@ -246,8 +249,9 @@ struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type, int enabl
     deframer->last_uw = 0;
     deframer->miss_cnt = 0;
     deframer->frame_size = frame_size;
+    deframer->uw_size = uw_size;
     deframer->on_inv_bits = 0;
-
+    deframer->ber_est = 0;
     deframer->fdc = NULL;
 
     return deframer;
@@ -302,13 +306,13 @@ int fvhff_synchronized(struct freedv_vhf_deframer * def){
 }
 
 /* See if the UW is where it should be, to within a tolerance, in a bit buffer */
-static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int tol, enum frame_payload_type *pt){
+static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int tol,int *rdiff, enum frame_payload_type *pt){
     int frame_type  = def->ftype;
     int bitptr      = def->bitptr;
     int frame_size  = def->frame_size;
+    int uw_len      = def->uw_size;
     int iuw,ibit;
     const uint8_t * uw[2];
-    int uw_len;
     int can_be_data;
     int uw_offset;
     int diff[2] = { 0, 0 };
@@ -349,9 +353,11 @@ static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int to
     /* Pick the best matching UW */
     if (diff[0] < diff[1] || !can_be_data) {
         r = match[0];
+        *rdiff = diff[0];
         *pt = FRAME_PAYLOAD_TYPE_VOICE;
     } else {
         r = match[1];
+        *rdiff = diff[1];
         *pt = FRAME_PAYLOAD_TYPE_DATA;
     }
     
@@ -528,6 +534,8 @@ int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uin
     int last_uw     = def->last_uw;
     int miss_cnt    = def->miss_cnt;
     int frame_size  = def->frame_size;
+    int uw_size     = def->uw_size;
+    int uw_diff;
     int i;
     int uw_first_tol;   
     int uw_sync_tol;
@@ -539,11 +547,11 @@ int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uin
     if(frame_type == FREEDV_VHF_FRAME_A){
         uw_first_tol = 1;   /* The UW bit-error tolerance for the first frame */
         uw_sync_tol = 3;    /* The UW bit error tolerance for frames after sync */
-        miss_tol = 5;       /* How many UWs may be missed before going into the de-synced state */
+        miss_tol = 4;       /* How many UWs may be missed before going into the de-synced state */
     }else if(frame_type == FREEDV_HF_FRAME_B){
-        uw_first_tol = 1;   /* The UW bit-error tolerance for the first frame */
-        uw_sync_tol = 3;    /* The UW bit error tolerance for frames after sync */
-        miss_tol = 5;       /* How many UWs may be missed before going into the de-synced state */
+        uw_first_tol = 0;   /* The UW bit-error tolerance for the first frame */
+        uw_sync_tol = 1;    /* The UW bit error tolerance for frames after sync */
+        miss_tol = 3;       /* How many UWs may be missed before going into the de-synced state */
     }else{
         return 0;
     }
@@ -572,7 +580,7 @@ int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uin
             if(last_uw == frame_size){
                 last_uw = 0;
                 
-                if(!fvhff_match_uw(def,bits,uw_sync_tol, &pt))
+                if(!fvhff_match_uw(def,bits,uw_sync_tol,&uw_diff, &pt))
                     miss_cnt++;
                 else
                     miss_cnt=0;
@@ -584,27 +592,34 @@ int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uin
                 /* Extract the bits */
                 extracted_frame = 1;
                 fvhff_extract_frame(def,bits,codec2_out,proto_out,vc_out,pt);
+                
+                /* Update BER estimate */
+                def->ber_est = (.99*def->ber_est) + (.01*((float)uw_diff)/((float)uw_size));
             }
         /* Not yet sunk */
         }else{
             /* It's a sync!*/
             if(invbits!=NULL){
-                if(fvhff_match_uw(def,invbits,uw_first_tol, &pt)){
+                if(fvhff_match_uw(def,invbits,uw_first_tol, &uw_diff, &pt)){
                     state = ST_SYNC;
                     last_uw = 0;
                     miss_cnt = 0;
                     extracted_frame = 1;
                     on_inv_bits = 1;
                     fvhff_extract_frame(def,invbits,codec2_out,proto_out,vc_out,pt);
+                    /* Update BER estimate */
+                    def->ber_est = (.99*def->ber_est) + (.01*((float)uw_diff)/((float)uw_size));
                 }
             }
-            if(fvhff_match_uw(def,strbits,uw_first_tol, &pt)){
+            if(fvhff_match_uw(def,strbits,uw_first_tol, &uw_diff, &pt)){
                 state = ST_SYNC;
                 last_uw = 0;
                 miss_cnt = 0;
                 extracted_frame = 1;
                 on_inv_bits = 0;
                 fvhff_extract_frame(def,strbits,codec2_out,proto_out,vc_out,pt);
+                /* Update BER estimate */
+                def->ber_est = (.98*def->ber_est) + (.02*((float)uw_diff)/((float)uw_size));
             }
         }
     }
index 66f0e8e5c5ce907c1478e822f6f43e0bd4cb3fab..c41e801b1caca70c382d40d1057d2debda53d8d7 100644 (file)
@@ -51,8 +51,11 @@ struct freedv_vhf_deframer {
     int bitptr;         /* Pointer into circular bit buffer */
     int miss_cnt;       /* How many UWs have been missed */
     int last_uw;        /* How many bits since the last UW? */\r
-    int frame_size;     /* How big is a frame? */\r
+    int frame_size;     /* How big is a frame? */
+    int uw_size;        /* How big is the UW */\r
     int on_inv_bits;    /* Are we using the inverted bits? */\r
+
+    float ber_est;      /* Bit error rate estimate */
 \r
     struct freedv_data_channel *fdc;\r
 };\r
index 3cad1d4b6c60a64c8cd69e0b53bcf1997f2146dd..b1fe759765cc2b57a52c7274211bcdb31d03ece4 100644 (file)
 #define TESTBER 0.01
 
 /* Frame count */
-#define FRCNT 1500
+#define FRCNT 15000
 
 /* Random bits leading frame */
-#define LRCNT 142
+#define LRCNT 55
 
 #include <stdio.h>
 #include <math.h>
 #include <stdint.h>
 #include <freedv_vhf_framing.h>
 #include <golay23.h>
+#include <string.h>
 
 /* The main loop of the test driver */
 int main(int argc,char *argv[]){
     uint8_t * bit_buffer;
-    uint8_t c2_buffer[7] = {0,0,0,0,0,0,0};
+    uint8_t c2_buffer[10];
     struct freedv_vhf_deframer * fvd;
     int i,p,k;
-    int bitbufferlen = (LRCNT+96*FRCNT);
+    int bitbufferlen;
+    int fsize;
+    int ftype;
+    int first_tol;
+    
+    if(argc<2){
+        fprintf(stderr,"Usage: %s [A|B]\n",argv[0]);
+        exit(1);
+    }
+    
+    if(strcmp(argv[1],"A")==0){
+        ftype = FREEDV_VHF_FRAME_A;
+        first_tol = 2;
+    }else if(strcmp(argv[1],"B")==0){
+        ftype = FREEDV_HF_FRAME_B;
+        first_tol = 5;
+    }else{
+        fprintf(stderr,"Usage: %s [A|B]\n",argv[0]);
+        exit(1);
+    }
     
     srand(1);
     golay23_init();
     
     /* Set up the deframer */
-    fvd = fvhff_create_deframer(FREEDV_VHF_FRAME_A,1);
+    fvd = fvhff_create_deframer(ftype,1);
 
+    fsize = fvhff_get_frame_size(fvd);
+    bitbufferlen = (LRCNT+fsize*FRCNT);
+    
     /* Allocate bit buffer */
     bit_buffer = (uint8_t *) malloc(sizeof(uint8_t)*bitbufferlen);
     p = 0;
@@ -67,11 +90,11 @@ int main(int argc,char *argv[]){
     for(i=0; i<FRCNT; i++){
         /* Encode frame index into golay codeword to protect from test BER*/
         k = golay23_encode((i+1)&0x0FFF);
-        c2_buffer[0] = (k    )&0xFF;
+        c2_buffer[5] = (k    )&0xFF;
         c2_buffer[1] = (k>>8 )&0xFF;
-        c2_buffer[2] = (k>>16)&0x7F;
+        c2_buffer[0] = (k>>16)&0x7F;
         /* Frame the bits */
-        fvhff_frame_bits(FREEDV_VHF_FRAME_A, &bit_buffer[p+(i*96)], c2_buffer,NULL,NULL);
+        fvhff_frame_bits(ftype, &bit_buffer[p+(i*fsize)], c2_buffer,NULL,NULL);
     }
     
     /* Flip bits */
@@ -85,32 +108,35 @@ int main(int argc,char *argv[]){
     int first_extract = 0;
     int total_extract = 0;
     int err_count = 0;
+    printf("\n");
     /* Deframe some bits */
-    for(i=0; i<bitbufferlen; i+=96){
+    for(i=0; i<bitbufferlen; i+=fsize){
         if( fvhff_deframe_bits(fvd, c2_buffer, NULL, NULL, &bit_buffer[i])){
             /* Extract golay23 codeword */
-            k  = ((int)c2_buffer[0])    ;
+            k  = ((int)c2_buffer[5])    ;
             k |= ((int)c2_buffer[1])<<8 ;
-            k |= ((int)c2_buffer[2])<<16;
+            k |= ((int)c2_buffer[0])<<16;
             k = k & 0x7FFFFF;
             /* Decode frame index */
             p = golay23_decode(k);
             err_count += golay23_count_errors(k,p);
             p = p>>11;
-            printf("Got frame %d\n",p);
+
+            printf("%d,\t",p);
             total_extract++;
             if(first_extract==0)
                 first_extract=p;
         }
     }
-    
+    printf("\n");
     float measured_ber = (float)err_count/(float)(23*total_extract);
     
     printf("First extracted frame %d\n",first_extract);
     printf("Extracted %d frames of %d, %f hit rate\n",total_extract,FRCNT,((float)total_extract/(float)FRCNT));
-    printf("Bit error rate %f measured\n",measured_ber);
+    printf("Bit error rate %f measured from golay code\n",measured_ber);
+    printf("Bit error rate %f measured by deframer\n",fvd->ber_est);
     /* Check test condition */
-    if(first_extract<2){
+    if(first_extract<first_tol){
         printf("Test passed at test BER of %f!\n",TESTBER);
         exit(0);
     }else{