Started getting framer ready for TDMA and added 2FSK soft decision output
authorbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 12 Sep 2016 03:33:28 +0000 (03:33 +0000)
committerbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 12 Sep 2016 03:33:28 +0000 (03:33 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2853 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/freedv_vhf_framing.c
codec2-dev/src/freedv_vhf_framing.h
codec2-dev/src/fsk.c
codec2-dev/src/fsk.h

index 7ead03430191bcca8357ec034370127140dab135..a7a2c62a914c338c85fce9a9151d4f1d682d452d 100644 (file)
@@ -63,6 +63,20 @@ 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,0,0, /* Voice[40:47]              */
                                     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] */
+                    
+/* Blank VHF type AT (A for TDMA; padding bits not transmitted) frame */
+static const uint8_t AT_blank[] =  {        0,1,1,1, /*              Proto[0:3]   */
+                                    1,0,1,0,0,1,1,1, /* Proto[4:11]               */
+                                    0,0,0,0,0,0,0,0, /* Voice[0:7]                */
+                                    0,0,0,0,0,0,0,0, /* Voice[8:15]               */
+                                    0,0,0,0,0,0,0,0, /* Voice[16:23]              */
+                                    0,1,1,0,0,1,1,1, /* UW[0:7]                   */
+                                    1,0,1,0,1,1,0,1, /* UW[8:15]                  */
+                                    0,0,0,0,0,0,0,0, /* Voice[24:31]              */
+                                    0,0,0,0,0,0,0,0, /* Voice[32:39]              */
+                                    0,0,0,0,0,0,0,0, /* Voice[40:47]              */
+                                    0,0,0,0,0,0,1,0, /* Voice[48:51] Proto[12:15] */
+                                    0,1,1,1        };/* Proto[16:19]              */
 
 /* HF Type B voice UW */
 static const uint8_t B_uw_v[] =    {0,1,1,0,0,1,1,1};
@@ -156,6 +170,43 @@ void fvhff_frame_bits(  int frame_type,
             bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in2,ibit);
             ibit++;
         }
+    }else if(frame_type == FREEDV_VHF_FRAME_AT){
+        /* Fill out frame with blank frame prototype */
+        for(i=0; i<88; i++)
+            bits_out[i] = AT_blank[i];
+        
+        /* Fill in protocol bits, if present */
+        if(proto_in!=NULL){
+            ibit = 0;
+            /* First half of protocol bits */
+            /* Extract and place in frame, MSB first */
+            for(i=0 ; i<12; i++){
+                bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
+                ibit++;
+            }
+            /* Last set of protocol bits */
+            for(i=80; i<88; i++){
+                bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
+                ibit++;
+            }
+        }
+        
+        /* Fill in varicode bits, if present */
+        if(vc_in!=NULL){
+            bits_out[86] = vc_in[0];
+            bits_out[87] = vc_in[1];
+        }
+        
+        /* Fill in codec2 bits, present or not */
+        ibit = 0;
+        for(i=12; i<36; i++){   /* First half */
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
+            ibit++;
+        }
+        for(i=52; i<80; i++){   /* Second half */
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
+            ibit++;
+        }
     }
 }
 
@@ -168,7 +219,7 @@ void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,
         int end_bits;
         int from_bit;
         int bcast_bit;
-       int crc_bit;
+        int crc_bit;
 
         /* Fill out frame with blank frame prototype */
         for(i=0; i<4; i++)
@@ -208,7 +259,7 @@ void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,
         int end_bits;
         int from_bit;
         int bcast_bit;
-       int crc_bit;
+        int crc_bit;
 
         /* Fill out frame with blank prototype */
         for(i=0; i<64; i++)
@@ -219,7 +270,7 @@ void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,
             bits_out[0 + i] = B_uw_d[i];
         
         if (def->fdc)
-                freedv_data_channel_tx_frame(def->fdc, data, 6, &from_bit, &bcast_bit, &crc_bit, &end_bits);
+            freedv_data_channel_tx_frame(def->fdc, data, 6, &from_bit, &bcast_bit, &crc_bit, &end_bits);
         else
             return;
 
@@ -489,6 +540,59 @@ static void fvhff_extract_frame_voice(struct freedv_vhf_deframer * def,uint8_t b
             iframe++;
             if(iframe >= frame_size) iframe=0;
         }
+    }else if(frame_type == FREEDV_VHF_FRAME_AT){
+        /* Extract codec2 bits */
+        memset(codec2_out,0,7);
+        ibit = 0;
+        /* Extract and pack first half, MSB first */
+        iframe = bitptr+12;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<24;ibit++){
+            codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+        
+        /* Extract and pack last half, MSB first */
+        iframe = bitptr+52;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<52;ibit++){
+            codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+        /* Extract varicode bits, if wanted */
+        if(vc_out!=NULL){
+            iframe = bitptr+86;
+            if(iframe >= frame_size) iframe-=frame_size;
+            vc_out[0] = bits[iframe];
+            iframe++;
+            vc_out[1] = bits[iframe];
+        }
+        /* Extract protocol bits, if proto is passed through */
+        if(proto_out!=NULL){
+            /* Clear protocol bit array */
+            memset(proto_out,0,3);
+            ibit = 0;
+            /* Extract and pack first half, MSB first */
+            iframe = bitptr+4;
+            if(iframe >= frame_size) iframe-=frame_size;
+            for(;ibit<12;ibit++){
+                proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+                iframe++;
+                if(iframe >= frame_size) iframe=0;
+            }
+            
+            /* Extract and pack last half, MSB first */
+            iframe = bitptr+84;
+            if(iframe >= frame_size) iframe-=frame_size;
+            for(;ibit<20;ibit++){
+                proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+                iframe++;
+                if(iframe >= frame_size) iframe=0;
+            }
+        }
+
     }
 }
 
index 877d6bfe9a8fd7b633102133407cdb296fd54a08..85f6e7b933a8f999ddcdcdf867410503627fe6eb 100644 (file)
@@ -39,8 +39,9 @@
 #include "freedv_data_channel.h"\r
 \r
 /* Standard frame type */\r
-#define FREEDV_VHF_FRAME_A 1
-#define FREEDV_HF_FRAME_B 2\r
+#define FREEDV_VHF_FRAME_A 1    /* 2400A/B Frame */
+#define FREEDV_HF_FRAME_B 2     /* 800XA Frame */
+#define FREEDV_VHF_FRAME_AT 3   /* 4800T Frame */\r
 \r
 struct freedv_vhf_deframer {
     int ftype;          /* Type of frame to be looking for */
index e073a994e8281f71bb34fe7d50bdedc3f1987d49..468175bce15a062e3410fcd2cb1eeac1e447b5f0 100644 (file)
@@ -543,7 +543,7 @@ void fsk_demod_freq_est(struct FSK *fsk, float fsk_in[],float *freqs,int M){
     #endif
 }
 
-void fsk2_demod(struct FSK *fsk, uint8_t rx_bits[], float fsk_in[]){
+void fsk2_demod(struct FSK *fsk, uint8_t rx_bits[], float rx_sd[], float fsk_in[]){
     int N = fsk->N;
     int Ts = fsk->Ts;
     int Rs = fsk->Rs;
@@ -768,8 +768,15 @@ void fsk2_demod(struct FSK *fsk, uint8_t rx_bits[], float fsk_in[]){
         /* Figure mag^2 of each resampled fx_int */
         tmax[0] = (t1.real*t1.real) + (t1.imag*t1.imag);
         tmax[1] = (t2.real*t2.real) + (t2.imag*t2.imag);
-        rx_bits[i] = (tmax[1]>tmax[0])?1:0;
         
+        /* Get the actual bit */
+        if(rx_bits != NULL){
+            rx_bits[i] = (tmax[1]>tmax[0])?1:0;
+        }
+        /* Produce soft decision symbols */
+        if(rx_sd != NULL){
+            rx_sd[i] = sqrtf(tmax[1]) - sqrtf(tmax[0]);
+        }
         /* Accumulate resampled int magnitude for EbNodB estimation */
         /* Standard deviation is calculated by algorithm devised by crafty soviets */
         #ifdef EST_EBNO
@@ -1279,7 +1286,16 @@ void fsk_demod(struct FSK *fsk, uint8_t rx_bits[], float fsk_in[]){
        if(fsk->mode == 4){
                fsk4_demod(fsk,rx_bits,fsk_in);
        }else{
-               fsk2_demod(fsk,rx_bits,fsk_in);
+               fsk2_demod(fsk,rx_bits,NULL,fsk_in);
+       }
+}
+
+void fsk_demod_sd(struct FSK *fsk, float rx_sd[],float fsk_in[]){
+       if(fsk->mode == 4){
+               //TODO: Add 4FSK soft decision
+        //fsk4_demod(fsk,rx_bits,fsk_in);
+       }else{
+               fsk2_demod(fsk,NULL,rx_sd,fsk_in);
        }
 }
 
index 4b9d3a7370505fee38a96a6445f8a60b260d60c4..9058fd5ad0b78faef2ffb81215a08dbd624cc7fc 100644 (file)
@@ -165,6 +165,14 @@ uint32_t fsk_nin(struct FSK *fsk);
  */
 void fsk_demod(struct FSK *fsk, uint8_t rx_bits[],float fsk_in[]);
 
-
+/*
+ * Demodulate some number of FSK samples. The number of samples to be 
+ *  demodulated can be found by calling fsk_nin().
+ * 
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * float rx_bits[] - Buffer for Nbits soft decision bits to be written
+ * float fsk_in[] - nin samples of modualted FSK
+ */
+void fsk_demod_sd(struct FSK *fsk, float rx_bits[],float fsk_in[]);
 
 #endif