Added new frame format. Extended vhf_deframe_c2 to support new format. Added vhf_fram...
authorbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 11 Apr 2016 00:19:30 +0000 (00:19 +0000)
committerbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 11 Apr 2016 00:19:30 +0000 (00:19 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2782 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/CMakeLists.txt
codec2-dev/src/freedv_vhf_framing.c
codec2-dev/src/freedv_vhf_framing.h
codec2-dev/src/fsk_mod.c
codec2-dev/src/vhf_deframe_c2.c

index acac63a822f26ec5fb4be071ef1cbbde3a75ba53..df845fed6a85c851562e66850547feb11038192e 100644 (file)
@@ -265,6 +265,9 @@ target_link_libraries(fmfsk_demod ${CMAKE_REQUIRED_LIBRARIES} codec2)
 add_executable(vhf_deframe_c2 vhf_deframe_c2.c)
 target_link_libraries(vhf_deframe_c2  ${CMAKE_REQUIRED_LIBRARIES} codec2)
 
+add_executable(vhf_frame_c2 vhf_frame_c2.c)
+target_link_libraries(vhf_frame_c2  ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
 add_executable(cohpsk_demod cohpsk_demod.c octave.c)
 target_link_libraries(cohpsk_demod ${CMAKE_REQUIRED_LIBRARIES} codec2)
 
index 19905bf6bc7e6200664f18fa5ebb39517777272c..6b6161f56a8e2631f0ab0d148d22cf3b1cdf287f 100644 (file)
@@ -39,7 +39,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-
+#include <assert.h>
 #include "freedv_vhf_framing.h"
 
 /* The voice UW of the VHF type A frame */
@@ -64,6 +64,19 @@ static const uint8_t A_blank[] =   {1,0,1,0,0,1,1,1, /* Padding[0:3] Proto[0:3]
                                     0,0,0,0,0,0,1,0, /* Voice[48:51] Proto[12:15] */
                                     0,1,1,1,0,0,1,0};/* Proto[16:19] Padding[4:7] */
 
+/* HF Type B UW */
+static const uint8_t B_uw_v[] =    {0,1,1,0,0,1,1,1};
+                                    
+/* Blank HF type B frame */
+static const uint8_t B_blank[] =   {0,1,1,0,0,1,1,1, /* UW[0:7]                                          */
+                                                                       0,0,0,0,0,0,0,0, /* Voice1[0:7]                           */
+                                                                       0,0,0,0,0,0,0,0, /* Voice1[8:15]                          */
+                                                                       0,0,0,0,0,0,0,0, /* Voice1[16:23]                         */
+                                                                       0,0,0,0,0,0,0,0, /* Voice1[24:28] Voice2[0:3] */
+                                                                       0,0,0,0,0,0,0,0, /* Voice2[4:11]                          */
+                                                                       0,0,0,0,0,0,0,0, /* Voice2[12:19]                         */
+                                                                       0,0,0,0,0,0,0,0};/* Voice2[20:28]                         */
+
 /* States */
 #define ST_NOSYNC 0 /* Not synchronized */
 #define ST_SYNC 1   /* Synchronized */
@@ -120,6 +133,26 @@ void fvhff_frame_bits(  int frame_type,
             bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
             ibit++;
         }
+    }else if(frame_type == FREEDV_HF_FRAME_B){
+        /* Pointers to both c2 frames so the bit unpack macro works */
+        uint8_t * codec2_in1 = &codec2_in[0];
+        uint8_t * codec2_in2 = &codec2_in[4];
+        /* Fill out frame with blank prototype */
+        for(i=0; i<64; i++)
+            bits_out[i] = B_blank[i];
+        
+        /* Fill out first codec2 block */
+        ibit=0;
+        for(i=8; i<36; i++){
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in1,ibit);
+            ibit++;
+        }
+        /* Fill out second codec2 block */
+        ibit=0;
+        for(i=36; i<64; i++){
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in2,ibit);
+            ibit++;
+        }
     }
 }
 
@@ -159,7 +192,7 @@ void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,
             bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit);
             ibit++;
         }
-        for(i=56; i<88; i++){   /* Second half */
+        for(i=56; i<88; i++){  /* Second half */
             bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit);
             ibit++;
         }
@@ -173,42 +206,89 @@ void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,
 struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type, int enable_bit_flip){
     struct freedv_vhf_deframer * deframer;
     uint8_t *bits,*invbits;
+    int frame_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){
-        /* Allocate memory for the thing */
-        deframer = malloc(sizeof(struct freedv_vhf_deframer));
-        if(deframer == NULL)
-            return NULL;
-            
-        /* Allocate the not-bit buffer */
-        if(enable_bit_flip){
-            invbits = malloc(sizeof(uint8_t)*96);
-            if(invbits == NULL)
-                return NULL;
-        }else{
-            invbits = NULL;
-        }
+        frame_size = 96;
+    }else if(frame_type == FREEDV_HF_FRAME_B){
+        frame_size = 64;
+    }else{
+        return NULL;
+    }
+    
+    /* Allocate memory for the thing */
+    deframer = malloc(sizeof(struct freedv_vhf_deframer));
+    if(deframer == NULL)
+        return NULL;
         
-        /* Allocate the bit buffer */
-        bits = malloc(sizeof(uint8_t)*96);
-        if(bits == NULL)
+    /* Allocate the not-bit buffer */
+    if(enable_bit_flip){
+        invbits = malloc(sizeof(uint8_t)*frame_size);
+        if(invbits == NULL)
             return NULL;
-        
-        deframer->bits = bits;
-        deframer->invbits = invbits;
-        deframer->ftype = frame_type;
-        deframer->state = ST_NOSYNC;
-        deframer->bitptr = 0;
-        deframer->last_uw = 0;
-        deframer->miss_cnt = 0;
-        deframer->frame_size = 96;
-        deframer->on_inv_bits = 0;
-
-        deframer->fdc = NULL;
-
-        return deframer;
+    }else{
+        invbits = NULL;
+    }
+    
+    /* Allocate the bit buffer */
+    bits = malloc(sizeof(uint8_t)*frame_size);
+    if(bits == NULL)
+        return NULL;
+    
+    deframer->bits = bits;
+    deframer->invbits = invbits;
+    deframer->ftype = frame_type;
+    deframer->state = ST_NOSYNC;
+    deframer->bitptr = 0;
+    deframer->last_uw = 0;
+    deframer->miss_cnt = 0;
+    deframer->frame_size = frame_size;
+    deframer->on_inv_bits = 0;
+
+    deframer->fdc = NULL;
+
+    return deframer;
+}
+
+/* Get size of frame in bits */
+int fvhff_get_frame_size(struct freedv_vhf_deframer * def){
+    return def->frame_size;
+}
+
+/* Codec2 size in bytes */
+int fvhff_get_codec2_size(struct freedv_vhf_deframer * def){
+    if(def->ftype == FREEDV_VHF_FRAME_A){
+        return 7;
+    } else if(def->ftype == FREEDV_HF_FRAME_B){
+        return 8;
+    } else{
+        return 0;
+    }
+}
+
+/* Protocol bits in bits */
+int fvhff_get_proto_size(struct freedv_vhf_deframer * def){
+    if(def->ftype == FREEDV_VHF_FRAME_A){
+        return 20;
+    } else if(def->ftype == FREEDV_HF_FRAME_B){
+        return 0;
+    } else{
+        return 0;
+    }
+}
+
+/* Varicode bits in bits */
+int fvhff_get_varicode_size(struct freedv_vhf_deframer * def){
+    if(def->ftype == FREEDV_VHF_FRAME_A){
+        return 2;
+    } else if(def->ftype == FREEDV_HF_FRAME_B){
+        return 0;
+    } else{
+        return 0;
     }
-    return NULL;
 }
 
 void fvhff_destroy_deframer(struct freedv_vhf_deframer * def){
@@ -229,6 +309,7 @@ static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int to
     int iuw,ibit;
     const uint8_t * uw[2];
     int uw_len;
+    int can_be_data;
     int uw_offset;
     int diff[2] = { 0, 0 };
     int i;
@@ -238,9 +319,16 @@ static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int to
     /* Set up parameters for the standard type of frame */
     if(frame_type == FREEDV_VHF_FRAME_A){
         uw[0] = A_uw_v;
-    uw[1] = A_uw_d;
+               uw[1] = A_uw_d;
         uw_len = 16;
         uw_offset = 40;
+        can_be_data = 1;
+    } else if(frame_type == FREEDV_HF_FRAME_B){
+        uw[0] = B_uw_v;
+        uw[1] = B_uw_v;
+        uw_len = 8;
+        uw_offset = 0;
+        can_be_data = 0;
     } else {
         return 0;
     }
@@ -259,7 +347,7 @@ static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int to
         match[i] = diff[i] <= tol;
     }
     /* Pick the best matching UW */
-    if (diff[0] < diff[1]) {
+    if (diff[0] < diff[1] || !can_be_data) {
         r = match[0];
         *pt = FRAME_PAYLOAD_TYPE_VOICE;
     } else {
@@ -329,6 +417,33 @@ static void fvhff_extract_frame_voice(struct freedv_vhf_deframer * def,uint8_t b
             }
         }
 
+    }else if(frame_type == FREEDV_HF_FRAME_B){
+        /* Pointers to both c2 frames */
+        uint8_t * codec2_out1 = &codec2_out[0];
+        uint8_t * codec2_out2 = &codec2_out[4];
+        
+        /* Extract codec2 bits */
+        memset(codec2_out,0,8);
+        ibit = 0;
+        
+        /* Extract and pack first c2 frame, MSB first */
+        iframe = bitptr+8;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<28;ibit++){
+            codec2_out1[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+        
+        /* Extract and pack second c2 frame, MSB first */
+        iframe = bitptr+36;
+        ibit = 0;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<28;ibit++){
+            codec2_out2[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
     }
 }
 
@@ -425,6 +540,10 @@ int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uin
         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 */
+    }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 */
     }else{
         return 0;
     }
index a3843ef32e4835d238a8eefaff4865cabf421bee..66f0e8e5c5ce907c1478e822f6f43e0bd4cb3fab 100644 (file)
@@ -39,7 +39,8 @@
 #include "freedv_data_channel.h"\r
 \r
 /* Standard frame type */\r
-#define FREEDV_VHF_FRAME_A 1\r
+#define FREEDV_VHF_FRAME_A 1
+#define FREEDV_HF_FRAME_B 2\r
 \r
 struct freedv_vhf_deframer {
     int ftype;          /* Type of frame to be looking for */
@@ -59,12 +60,22 @@ struct freedv_vhf_deframer {
 /* Init and allocate memory for a freedv-vhf framer/deframer */\r
 struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type,int enable_bit_flip);
 
+/* Get size of various frame parameters */
+/* Frame size in bits */
+int fvhff_get_frame_size(struct freedv_vhf_deframer * def);
+/* Codec2 size in bytes */
+int fvhff_get_codec2_size(struct freedv_vhf_deframer * def);
+/* Protocol bits in bits */
+int fvhff_get_proto_size(struct freedv_vhf_deframer * def);
+/* Varicode bits in bits */
+int fvhff_get_varicode_size(struct freedv_vhf_deframer * def);
+
 /* Free the memory used by a freedv-vhf framer/deframer */
 void fvhff_destroy_deframer(struct freedv_vhf_deframer * def);
 \r
 /* Place codec and other bits into a frame */\r
 void fvhff_frame_bits(int frame_type,uint8_t bits_out[],uint8_t codec2_in[],uint8_t proto_in[],uint8_t vc_in[]);\r
-void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,uint8_t bits_out[]);\r
+void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,uint8_t bits_out[]);
 \r
 /* Find and extract frames from a stream of bits */\r
 int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uint8_t proto_out[],uint8_t vc_out[],uint8_t bits_in[]);\r
index cb890c4ce89d7871c844307f9a699ae6ae52b0e7..349380a027e6c59828a04802bd16adcff43f9a54 100644 (file)
@@ -37,6 +37,7 @@ int main(int argc,char *argv[]){
     struct FSK *fsk;
     int Fs,Rs,f1,fs,M;
     int i;
+    int p;
     FILE *fin,*fout;
     uint8_t *bitbuf;
     int16_t *rawbuf;
@@ -66,9 +67,10 @@ int main(int argc,char *argv[]){
                fout = fopen(argv[7],"w");
        }
     
+    p = Fs/Rs;
     
     /* set up FSK */
-    fsk = fsk_create(Fs,Rs,M,f1,fs);
+    fsk = fsk_create_hbr(Fs,Rs,p,M,f1,fs);
     
     if(fin==NULL || fout==NULL || fsk==NULL){
         fprintf(stderr,"Couldn't open test vector files\n");
index 1477bfbc2582e050c76a44d9c5f714ae22274cc1..207e819ad2e67b9cb260f48e47ae7f9df374db20 100644 (file)
@@ -38,44 +38,58 @@ int main(int argc,char *argv[]){
     FILE *fin,*fout;
     uint8_t *bitbuf;
     uint8_t *c2buf;
-    uint8_t zbuf[] = {0,0,0,0,0,0,0};
+    uint8_t zbuf[] = {0,0,0,0,0,0,0,0};
+    int frame_fmt = 0;
+    int fsize,c2size;
     
     if(argc<3){
-        fprintf(stderr,"usage: %s InputOneBitPerCharFile OutputC2File\n",argv[0]);
+        fprintf(stderr,"usage: %s (A|B) InputOneBitPerCharFile OutputC2File\n",argv[0]);
+        exit(1);
+    }
+    
+    if(strcmp(argv[1],"A")==0){
+        frame_fmt = FREEDV_VHF_FRAME_A;
+    } else if (strcmp(argv[1],"B")==0) {
+        frame_fmt = FREEDV_HF_FRAME_B;
+    } else {
+        fprintf(stderr,"usage: %s (A|B) InputOneBitPerCharFile OutputC2File\n",argv[0]);
         exit(1);
     }
     
     /* Open files */
-    if(strcmp(argv[1],"-")==0){
+    if(strcmp(argv[2],"-")==0){
         fin = stdin;
     }else{
-        fin = fopen(argv[1],"r");
+        fin = fopen(argv[2],"r");
     }
        
-    if(strcmp(argv[2],"-")==0){
+    if(strcmp(argv[3],"-")==0){
         fout = stdout;
     }else{
-        fout = fopen(argv[2],"w");
+        fout = fopen(argv[3],"w");
     }
 
     /* Set up deframer */
-    deframer = fvhff_create_deframer(FREEDV_VHF_FRAME_A,0);
+    deframer = fvhff_create_deframer(frame_fmt,0);
     
     if(fin==NULL || fout==NULL || deframer==NULL){
         fprintf(stderr,"Couldn't open test vector files\n");
         goto cleanup;
     }
     
+    c2size = fvhff_get_codec2_size(deframer);
+    fsize = fvhff_get_frame_size(deframer);
+    
     /* allocate buffers for processing */
-    bitbuf = (uint8_t*)malloc(sizeof(uint8_t)*96);
-    c2buf = (uint8_t*)malloc(sizeof(uint8_t)*7);
+    bitbuf = (uint8_t*)malloc(sizeof(uint8_t)*fsize);
+    c2buf = (uint8_t*)malloc(sizeof(uint8_t)*c2size);
     
     /* Deframe! */
-    while( fread(bitbuf,sizeof(uint8_t),96,fin) == 96 ){
+    while( fread(bitbuf,sizeof(uint8_t),fsize,fin) == fsize ){
         if(fvhff_deframe_bits(deframer,c2buf,NULL,NULL,bitbuf))
-            fwrite(c2buf,sizeof(uint8_t),7,fout);
+            fwrite(c2buf,sizeof(uint8_t),c2size,fout);
         else
-            fwrite(zbuf,sizeof(uint8_t),7,fout);
+            fwrite(zbuf,sizeof(uint8_t),c2size,fout);
         
         if(fin == stdin || fout == stdin){
             fflush(fin);