refactored stats handling for fsk and fmfsk to be consistent with other modems, freed...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 15 Jan 2017 00:12:20 +0000 (00:12 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 15 Jan 2017 00:12:20 +0000 (00:12 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2974 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/fmfsk.c
codec2-dev/src/fmfsk.h
codec2-dev/src/fmfsk_demod.c
codec2-dev/src/freedv_api.c
codec2-dev/src/fsk.c
codec2-dev/src/fsk.h
codec2-dev/src/fsk_demod.c

index 1c89179cf4ef6c0cb4bd12a6a494fe4a23f55ef0..ab56945fbba0a446cc50752b617d95d2d48adac1 100644 (file)
@@ -82,7 +82,13 @@ struct FMFSK * fmfsk_create(int Fs,int Rb){
     }
     
     fmfsk->oldsamps = oldsamps;
-    fmfsk->stats = NULL;
+
+    fmfsk->stats = (struct MODEM_STATS*)malloc(sizeof(struct MODEM_STATS));
+    if (fmfsk->stats == NULL) {
+        free(oldsamps);
+        free(fmfsk);
+        return NULL;
+    }
     
     return fmfsk;
 }
@@ -103,8 +109,26 @@ uint32_t fmfsk_nin(struct FMFSK *fmfsk){
     return (uint32_t)fmfsk->nin;
 }
 
-void fmfsk_setup_modem_stats(struct FMFSK *fmfsk,struct MODEM_STATS *stats){
-    fmfsk->stats = stats;
+void fmfsk_get_demod_stats(struct FMFSK *fmfsk,struct MODEM_STATS *stats){
+    /* copy from internal stats, note we can't overwrite stats completely
+       as it has other states rqd by caller, also we want a consistent
+       interface across modem types for the freedv_api.
+    */
+
+    stats->clock_offset = fmfsk->stats->clock_offset;
+    stats->snr_est = fmfsk->stats->snr_est;           // TODO: make this SNR not Eb/No
+    stats->rx_timing = fmfsk->stats->rx_timing;
+    stats->foff = fmfsk->stats->foff;
+
+    stats->neyesamp = fmfsk->stats->neyesamp;
+    stats->neyetr = fmfsk->stats->neyetr;
+    memcpy(stats->rx_eye, fmfsk->stats->rx_eye, sizeof(stats->rx_eye));
+
+    /* these fields not used for FSK so set to something sensible */
+
+    stats->sync = 0;
+    stats->nr = fmfsk->stats->nr;
+    stats->Nc = fmfsk->stats->Nc;
 }
 
 /*
@@ -306,48 +330,46 @@ void fmfsk_demod(struct FMFSK *fmfsk, uint8_t rx_bits[],float fmfsk_in[]){
     fmfsk->lodd = lastv;
     
     /* Save demod statistics */
-    if(fmfsk->stats != NULL){
-        fmfsk->stats->Nc = 0;
-        fmfsk->stats->nr = 0;
+    fmfsk->stats->Nc = 0;
+    fmfsk->stats->nr = 0;
         
-        /* Clock offset and RX timing are all we know here */
-        fmfsk->stats->clock_offset = fmfsk->ppm;
-        fmfsk->stats->rx_timing = (float)rx_timing;
+    /* Clock offset and RX timing are all we know here */
+    fmfsk->stats->clock_offset = fmfsk->ppm;
+    fmfsk->stats->rx_timing = (float)rx_timing;
         
-        /* Zero out all of the other things */
-        fmfsk->stats->foff = 0;
+    /* Zero out all of the other things */
+    fmfsk->stats->foff = 0;
 
-        #ifdef EST_EBNO
-        amp_bit = fabsf(amp_bit - amp_noise);
-        fmfsk->snr_mean *= .9;
-        fmfsk->snr_mean += (amp_bit+1e-6)/(amp_noise+1e-6);
-        fmfsk->stats->snr_est = 20+20*log10f(fmfsk->snr_mean); 
-        #else
-        fmfsk->stats->snr_est = 0;
-        #endif
+#ifdef EST_EBNO
+    amp_bit = fabsf(amp_bit - amp_noise);
+    fmfsk->snr_mean *= .9;
+    fmfsk->snr_mean += (amp_bit+1e-6)/(amp_noise+1e-6);
+    fmfsk->stats->snr_est = 20+20*log10f(fmfsk->snr_mean); 
+#else
+    fmfsk->stats->snr_est = 0;
+#endif
         
-        /* Collect an eye diagram */
-        /* Take a sample for the eye diagrams */
-        neyesamp = fmfsk->stats->neyesamp = Ts*4;
-        neyeoffset = sample_offset+(Ts*2*28);
+    /* Collect an eye diagram */
+    /* Take a sample for the eye diagrams */
+    neyesamp = fmfsk->stats->neyesamp = Ts*4;
+    neyeoffset = sample_offset+(Ts*2*28);
         
-        fmfsk->stats->neyetr = 8;
-        for(k=0; k<fmfsk->stats->neyetr; k++)
-            for(j=0; j<neyesamp; j++)                                 
-                fmfsk->stats->rx_eye[k][j] = rx_filt[k*neyesamp+neyeoffset+j];
-               //fmfsk->stats->rx_eye[k][j] = fmfsk_in[k*neyesamp+neyeoffset+j];
-        eye_max = 0;
+    fmfsk->stats->neyetr = 8;
+    for(k=0; k<fmfsk->stats->neyetr; k++)
+        for(j=0; j<neyesamp; j++)                                 
+            fmfsk->stats->rx_eye[k][j] = rx_filt[k*neyesamp+neyeoffset+j];
+    //fmfsk->stats->rx_eye[k][j] = fmfsk_in[k*neyesamp+neyeoffset+j];
+    eye_max = 0;
         
-        /* Normalize eye to +/- 1 */
-        for(i=0; i<fmfsk->stats->neyetr; i++)
-            for(j=0; j<neyesamp; j++)
-                if(fabsf(fmfsk->stats->rx_eye[i][j])>eye_max)
-                    eye_max = fabsf(fmfsk->stats->rx_eye[i][j]);
+    /* Normalize eye to +/- 1 */
+    for(i=0; i<fmfsk->stats->neyetr; i++)
+        for(j=0; j<neyesamp; j++)
+            if(fabsf(fmfsk->stats->rx_eye[i][j])>eye_max)
+                eye_max = fabsf(fmfsk->stats->rx_eye[i][j]);
         
-        for(i=0; i<fmfsk->stats->neyetr; i++)
-            for(j=0; j<neyesamp; j++)
-                fmfsk->stats->rx_eye[i][j] = (fmfsk->stats->rx_eye[i][j]/(2*eye_max))+.5;
-    }
+    for(i=0; i<fmfsk->stats->neyetr; i++)
+        for(j=0; j<neyesamp; j++)
+            fmfsk->stats->rx_eye[i][j] = (fmfsk->stats->rx_eye[i][j]/(2*eye_max))+.5;
     
     modem_probe_samp_f("t_norm_rx_timing",&norm_rx_timing,1);
     modem_probe_samp_f("t_rx_filt",rx_filt,(nsym+1)*Ts);
index dd04ccd75d3e79ff43dd3978e5960e2143b8c074..9ec6418b03c0e237f192839144ac44c449cf3263 100644 (file)
 #ifndef __C2FMFSK_H
 #define __C2FMFSK_H
 #include <stdint.h>
-#include "comp.h"\r
-#include "modem_stats.h"\r
-\r
-#define FMFSK_SCALE 16383\r
-\r
-/* \r
- * fm-me-2fsk state\r
- */\r
+#include "comp.h"
+#include "modem_stats.h"
+
+#define FMFSK_SCALE 16383
+
+/* 
+ * fm-me-2fsk state
+ */
 struct FMFSK{
     /* Static fmfsk parameters */
     int Rb;             /* Manchester-encoded bitrate */
@@ -77,9 +77,9 @@ struct FMFSK * fmfsk_create(int Fs,int Rb);
 void fmfsk_destroy(struct FMFSK *fmfsk);
 
 /*
- * Set a MODEM_STATS struct in which to deposit demod statistics
+ * Deposit demod statistics into a MODEM_STATS struct
  */
-void fmfsk_setup_modem_stats(struct FMFSK *fmfsk,struct MODEM_STATS *stats);
+void fmfsk_get_demod_stats(struct FMFSK *fmfsk,struct MODEM_STATS *stats);
 
 /*
  * Returns the number of samples that must be fed to fmfsk_demod the next
index 63785143c79f44e1446e1e7188906421b17b2e04..1421c8755e435043d47c782a352ed282bbbaecbd 100644 (file)
@@ -76,7 +76,6 @@ int main(int argc,char *argv[]){
     if(argc>5){
        if(strcmp(argv[5],"S")==0){
            enable_stats = 1;
-           fmfsk_setup_modem_stats(fmfsk,&stats);
            loop_time = ((float)fmfsk_nin(fmfsk))/((float)Fs);
            stats_loop = (int)(.125/loop_time);
            stats_ctr = 0;
@@ -110,6 +109,7 @@ int main(int argc,char *argv[]){
        fwrite(bitbuf,sizeof(uint8_t),fmfsk->nbit,fout);
         
        if(enable_stats && stats_ctr <= 0){
+           fmfsk_get_demod_stats(fmfsk,&stats);
            fprintf(stderr,"{\"EbNodB\": %2.2f,\t\"ppm\": %d,",stats.snr_est,(int)stats.clock_offset);
            fprintf(stderr,"\t\"f1_est\":%.1f,\t\"f2_est\":%.1f",0.0,0.0);
            fprintf(stderr,",\t\"eye_diagram\":[");
index b81827b27e0c73c69c825bb56585dd7d2b0e4810..071e5bc3caf1759de7e49c89ef1c3609f78ac95b 100644 (file)
@@ -183,9 +183,6 @@ struct freedv *freedv_open(int mode) {
         f->modem_sample_rate = 48000;
         /* Malloc something to appease freedv_init and freedv_destroy */
         f->codec_bits = malloc(1);
-        
-        /* Set up the stats */
-        fsk_setup_modem_stats(f->fsk,&(f->stats));
     }
     
     if (mode == FREEDV_MODE_2400B) {
@@ -210,9 +207,6 @@ struct freedv *freedv_open(int mode) {
         f->modem_sample_rate = 48000;
         /* Malloc something to appease freedv_init and freedv_destroy */
         f->codec_bits = malloc(1);
-        
-        /* Set up the stats */
-        fmfsk_setup_modem_stats(f->fmfsk,&(f->stats));
     }
     
     if (mode == FREEDV_MODE_800XA) {
@@ -242,9 +236,6 @@ struct freedv *freedv_open(int mode) {
         
         f->n_protocol_bits = 0;
         codec2_mode = CODEC2_MODE_700C;
-        
-        /* Set up the stats */
-        fsk_setup_modem_stats(f->fsk,&(f->stats));
     }
     
 
@@ -1578,8 +1569,14 @@ void freedv_get_modem_extended_stats(struct freedv *f, struct MODEM_STATS *stats
 {
     if (f->mode == FREEDV_MODE_1600)
         fdmdv_get_demod_stats(f->fdmdv, stats);
-    if ((f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || (f->mode == FREEDV_MODE_800XA))
-        memcpy(stats,&(f->stats),sizeof(struct MODEM_STATS));
+
+    if ((f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_800XA)) {
+        fsk_get_demod_stats(f->fsk, stats);
+    }
+
+    if (f->mode == FREEDV_MODE_2400B) {
+        fmfsk_get_demod_stats(f->fmfsk, stats);
+    }
     
 #ifndef CORTEX_M4
     if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C))
index 9a805d2f55059631f919c22ebf939f70468208b0..3b510b85416d939c4a72dbc88e017fe110e137fe 100644 (file)
@@ -238,8 +238,15 @@ struct FSK * fsk_create_hbr(int Fs, int Rs,int P,int M, int tx_f1, int tx_fs)
     
     fsk->ppm = 0;
 
-    fsk->stats = NULL;
-    
+    fsk->stats = (struct MODEM_STATS*)malloc(sizeof(struct MODEM_STATS));
+    if(fsk->stats == NULL){
+        free(fsk->fft_est);
+        free(fsk->samp_old);
+        free(fsk->fft_cfg);
+        free(fsk);
+        return NULL;
+    }
+
     return fsk;
 }
 
@@ -364,9 +371,16 @@ struct FSK * fsk_create(int Fs, int Rs,int M, int tx_f1, int tx_fs)
         fsk->f_est[i] = 0; 
     
     fsk->ppm = 0;
-
-    fsk->stats = NULL;
     
+    fsk->stats = (struct MODEM_STATS*)malloc(sizeof(struct MODEM_STATS));
+    if(fsk->stats == NULL){
+        free(fsk->fft_est);
+        free(fsk->samp_old);
+        free(fsk->fft_cfg);
+        free(fsk);
+        return NULL;
+    }
+
     return fsk;
 }
 
@@ -419,11 +433,30 @@ uint32_t fsk_nin(struct FSK *fsk){
 void fsk_destroy(struct FSK *fsk){
     free(fsk->fft_cfg);
     free(fsk->samp_old);
+    free(fsk->stats);
     free(fsk);
 }
 
-void fsk_setup_modem_stats(struct FSK *fsk,struct MODEM_STATS *stats){
-    fsk->stats = stats;
+void fsk_get_demod_stats(struct FSK *fsk, struct MODEM_STATS *stats){
+    /* copy from internal stats, note we can't overwrite stats completely
+       as it has other states rqd by caller, also we want a consistent
+       interface across modem types for the freedv_api.
+    */
+
+    stats->clock_offset = fsk->stats->clock_offset;
+    stats->snr_est = fsk->stats->snr_est;           // TODO: make this SNR not Eb/No
+    stats->rx_timing = fsk->stats->rx_timing;
+    stats->foff = fsk->stats->foff;
+
+    stats->neyesamp = fsk->stats->neyesamp;
+    stats->neyetr = fsk->stats->neyetr;
+    memcpy(stats->rx_eye, fsk->stats->rx_eye, sizeof(stats->rx_eye));
+
+    /* these fields not used for FSK so set to something sensible */
+
+    stats->sync = 0;
+    stats->nr = fsk->stats->nr;
+    stats->Nc = fsk->stats->Nc;
 }
 
 /*
@@ -893,50 +926,49 @@ void fsk2_demod(struct FSK *fsk, uint8_t rx_bits[], float rx_sd[], COMP fsk_in[]
     fsk->EbNodB = 1;
     #endif
     
-    /* Write some statistics out to the stats struct, if present */
-    if( fsk->stats != NULL ){
-        /* Save clock offset in ppm */
-        fsk->stats->clock_offset = fsk->ppm;
+    /* Write some statistics to the stats struct */
+
+    /* Save clock offset in ppm */
+    fsk->stats->clock_offset = fsk->ppm;
         
-        /* Calculate and save SNR from EbNodB estimate */
-        fsk->stats->snr_est = .5*fsk->stats->snr_est + .5*fsk->EbNodB;//+ 10*log10f(((float)Rs)/((float)Rs*M));
+    /* Calculate and save SNR from EbNodB estimate */
+    fsk->stats->snr_est = .5*fsk->stats->snr_est + .5*fsk->EbNodB;//+ 10*log10f(((float)Rs)/((float)Rs*M));
         
-        /* Save rx timing */
-        fsk->stats->rx_timing = (float)rx_timing;
+    /* Save rx timing */
+    fsk->stats->rx_timing = (float)rx_timing;
         
-        /* Estimate and save frequency offset */
-        fc_avg = (f_est[0]+f_est[1])/2;
-        fc_tx = (fsk->f1_tx+fsk->f1_tx+fsk->fs_tx)/2;
-        fsk->stats->foff = fc_tx-fc_avg;
-    
-        /* Take a sample for the eye diagrams */
-        neyesamp = fsk->stats->neyesamp = P*2;
-        neyeoffset = high_sample+1+(P*28);
+    /* Estimate and save frequency offset */
+    fc_avg = (f_est[0]+f_est[1])/2;
+    fc_tx = (fsk->f1_tx+fsk->f1_tx+fsk->fs_tx)/2;
+    fsk->stats->foff = fc_tx-fc_avg;
+    
+    /* Take a sample for the eye diagrams */
+    neyesamp = fsk->stats->neyesamp = P*2;
+    neyeoffset = high_sample+1+(P*28);
         
-        int eye_traces = MODEM_STATS_ET_MAX/M;
+    int eye_traces = MODEM_STATS_ET_MAX/M;
         
-        fsk->stats->neyetr = fsk->mode*eye_traces;
-        for( i=0; i<eye_traces; i++){
-            for ( m=0; m<M; m++){
-                for(j=0; j<neyesamp; j++)
-                    fsk->stats->rx_eye[i*M+m][j] = cabsolute(f_int[m][neyesamp*i+neyeoffset+j]);
-            }
+    fsk->stats->neyetr = fsk->mode*eye_traces;
+    for( i=0; i<eye_traces; i++){
+        for ( m=0; m<M; m++){
+            for(j=0; j<neyesamp; j++)
+                fsk->stats->rx_eye[i*M+m][j] = cabsolute(f_int[m][neyesamp*i+neyeoffset+j]);
         }
+    }
         
-        eye_max = 0;
-        /* Normalize eye to +/- 1 */
-        for(i=0; i<M*eye_traces; i++)
-            for(j=0; j<neyesamp; j++)
-                if(fabsf(fsk->stats->rx_eye[i][j])>eye_max)
-                    eye_max = fabsf(fsk->stats->rx_eye[i][j]);
+    eye_max = 0;
+    /* Normalize eye to +/- 1 */
+    for(i=0; i<M*eye_traces; i++)
+        for(j=0; j<neyesamp; j++)
+            if(fabsf(fsk->stats->rx_eye[i][j])>eye_max)
+                eye_max = fabsf(fsk->stats->rx_eye[i][j]);
         
-        for(i=0; i<M*eye_traces; i++)
-            for(j=0; j<neyesamp; j++)
-                fsk->stats->rx_eye[i][j] = fsk->stats->rx_eye[i][j]/eye_max;
+    for(i=0; i<M*eye_traces; i++)
+        for(j=0; j<neyesamp; j++)
+            fsk->stats->rx_eye[i][j] = fsk->stats->rx_eye[i][j]/eye_max;
         
-        fsk->stats->nr = 0;
-        fsk->stats->Nc = 0;
-    }
+    fsk->stats->nr = 0;
+    fsk->stats->Nc = 0;
     
     /* Dump some internal samples */
     modem_probe_samp_f("t_EbNodB",&(fsk->EbNodB),1);
index b84d802b9f827205577dc79ebeee2208ed9903d1..470121b1f1a7b1116130c6fd5204cc566be77dd9 100644 (file)
 #include "kiss_fftr.h"
 #include "modem_stats.h"
 
-#define MODE_2FSK 2\r
-#define MODE_4FSK 4\r
+#define MODE_2FSK 2
+#define MODE_4FSK 4
 
 #define MODE_M_MAX 4
-\r
-#define FSK_SCALE 16383\r
-\r
-struct FSK {\r
+
+#define FSK_SCALE 16383
+
+struct FSK {
     /*  Static parameters set up by fsk_init */\r
     int Ndft;               /* buffer size for freq offset est fft */\r
     int Fs;                 /* sample freq */
@@ -83,7 +83,7 @@ struct FSK {
     /*  Parameters used by mod/demod and driving code */
     int nin;                /* Number of samples to feed the next demod cycle */
     
-    /*  Pointer to modem statistic struct */
+    /*  modem statistic struct */
     struct MODEM_STATS *stats;
 };
 
@@ -123,9 +123,9 @@ void fsk_set_est_limits(struct FSK *fsk,int fmin, int fmax);
 void fsk_clear_estimators(struct FSK *fsk);
 
 /*
- * Set a MODEM_STATS struct in which to deposit demod statistics
+ * Fills MODEM_STATS struct with demod statistics
  */
-void fsk_setup_modem_stats(struct FSK *fsk,struct MODEM_STATS *stats);
+void fsk_get_demod_stats(struct FSK *fsk, struct MODEM_STATS *stats);
 
 /*
  * Destroy an FSK state struct and free it's memory
index a89249f1b22e202170dcebf86cf1a5e3bd880716..06bad87446aa11eebf71a3c0151b8ee86d4ed92e 100644 (file)
@@ -181,7 +181,6 @@ int main(int argc,char *argv[]){
     }
     
     if(enable_stats){
-        fsk_setup_modem_stats(fsk,&stats);
         loop_time = ((float)fsk_nin(fsk))/((float)Fs);
         stats_loop = (int)(1/(stats_rate*loop_time));
         stats_ctr = 0;
@@ -232,6 +231,7 @@ int main(int argc,char *argv[]){
         }
         
         if(enable_stats && stats_ctr <= 0){
+            fsk_get_demod_stats(fsk,&stats);
            /* Print standard 2FSK stats */
             fprintf(stderr,"{\"EbNodB\": %2.2f,\t\"ppm\": %d,",stats.snr_est,(int)fsk->ppm);
             fprintf(stderr,"\t\"f1_est\":%.1f,\t\"f2_est\":%.1f",fsk->f_est[0],fsk->f_est[1]);