testframes working in freedv API, and tested with freedv_tx and freedv_rx
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 18 Jun 2015 23:37:49 +0000 (23:37 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 18 Jun 2015 23:37:49 +0000 (23:37 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2207 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/CMakeLists.txt
codec2-dev/src/codec2_cohpsk.h
codec2-dev/src/cohpsk.c
codec2-dev/src/cohpsk_get_test_bits.c
codec2-dev/src/cohpsk_internal.h
codec2-dev/src/cohpsk_mod.c
codec2-dev/src/cohpsk_put_test_bits.c
codec2-dev/src/freedv_api.c
codec2-dev/src/freedv_api.h
codec2-dev/src/freedv_rx.c
codec2-dev/src/freedv_tx.c

index b64f4fd08a157465c233240c7a6b1b91fee5964b..f74643f278faaa539dc14934f94dbb6d1ff1b73a 100644 (file)
@@ -48,7 +48,7 @@ message(STATUS "codec2 version: ${CODEC2_VERSION}")
 
 # Set default build type
 if(NOT CMAKE_BUILD_TYPE)
-    set(CMAKE_BUILD_TYPE "Release")
+    set(CMAKE_BUILD_TYPE "Debug")
 endif()
 
 # Set default C++ flags.
index cea97ab69253b4ac4be6b40d38a987af0035d574..c8d6d2501fe9b19f72034dd1a928df0de79a4e26 100644 (file)
@@ -42,6 +42,8 @@
 
 struct COHPSK;
 
+extern const int test_bits_coh[];
+
 struct COHPSK *cohpsk_create(void);
 void cohpsk_destroy(struct COHPSK *coh);
 void cohpsk_mod(struct COHPSK *cohpsk, COMP tx_fdm[], int tx_bits[]);
@@ -49,5 +51,8 @@ void cohpsk_clip(COMP tx_fdm[]);
 void cohpsk_demod(struct COHPSK *cohpsk, float rx_bits[], int *sync, COMP rx_fdm[], int *nin_frame);
 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[]);
 
 #endif
index c8ed48df79f95cb54cd6f083734e41701dc93f60..cda8a727763c13d54ff26d35ffeaf19dc1d6747e 100644 (file)
@@ -46,6 +46,7 @@
 #include "kiss_fft.h"
 #include "linreg.h"
 #include "rn_coh.h"
+#include "test_bits_coh.h"
 
 static COMP qpsk_mod[] = {
     { 1.0, 0.0},
@@ -178,6 +179,11 @@ struct COHPSK *cohpsk_create(void)
     coh->rx_timing_log = NULL;
     coh->rx_timing_log_index = 0;
 
+    /* test frames */
+
+    coh->ptest_bits_coh_tx = coh->ptest_bits_coh_rx = (int*)test_bits_coh;
+    coh->ptest_bits_coh_end = (int*)test_bits_coh + sizeof(test_bits_coh)/sizeof(int);
+    
     return coh;
 }
 
@@ -1136,3 +1142,73 @@ void cohpsk_set_verbose(struct COHPSK *coh, int verbose)
 }
 
 
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: cohpsk_get_test_bits()      
+  AUTHOR......: David Rowe                           
+  DATE CREATED: June 2015
+
+  Returns a frame of known test bits.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[])
+{
+    memcpy(rx_bits, coh->ptest_bits_coh_tx, sizeof(int)*COHPSK_BITS_PER_FRAME);
+    coh->ptest_bits_coh_tx += COHPSK_BITS_PER_FRAME;
+    if (coh->ptest_bits_coh_tx >=coh->ptest_bits_coh_end) {
+        coh->ptest_bits_coh_tx = (int*)test_bits_coh;
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: cohpsk_put_test_bits()      
+  AUTHOR......: David Rowe                           
+  DATE CREATED: June 2015
+
+  Accepts bits from demod and attempts to sync with the known
+  test_bits sequence.  When synced measures bit errors.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[],
+                        int *bit_errors, float rx_bits_sd[])
+{
+    int i, next_state, anerror;
+    int rx_bits[COHPSK_BITS_PER_FRAME];
+
+    for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
+        rx_bits[i] = rx_bits_sd[i] < 0.0;
+    }
+
+    *bit_errors = 0;
+    for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
+        anerror = (rx_bits[i] & 0x1) ^ coh->ptest_bits_coh_rx[i];
+        *bit_errors += anerror;
+        error_pattern[i] = anerror;
+    }
+
+    /* state logic */
+
+    next_state = *state;
+
+    if (*state == 0) {
+        if (*bit_errors < 4) {
+            next_state = 1;
+            coh->ptest_bits_coh_rx += COHPSK_BITS_PER_FRAME;
+        }
+    }
+
+    if (*state == 1) {
+        coh->ptest_bits_coh_rx += COHPSK_BITS_PER_FRAME;
+        if (coh->ptest_bits_coh_rx >= coh->ptest_bits_coh_end) {
+            coh->ptest_bits_coh_rx = (int*)test_bits_coh;
+        }
+    }
+
+    *state = next_state;
+}
+
+
index d54be81f60ed148ac3977f833954944452260641..ed4f54733926d175f594c736d044c7267b3a5820 100644 (file)
@@ -40,11 +40,12 @@ int main(int argc, char *argv[])
 {
     FILE         *fout;
     int           tx_bits[COHPSK_BITS_PER_FRAME];
+    float         sd_tx_bits[COHPSK_BITS_PER_FRAME];
     int           numBits, nFrames, n;
-    int           *ptest_bits_coh, *ptest_bits_coh_end;
+    int           *ptest_bits_coh, *ptest_bits_coh_end, i;
 
     if (argc < 2) {
-       printf("usage: %s OutputOneBitPerIntFile numBits\n", argv[0]);
+       printf("usage: %s OutputOneFloatPerBitFile numBits\n", argv[0]);
        exit(1);
     }
 
@@ -68,7 +69,10 @@ int main(int argc, char *argv[])
             ptest_bits_coh = (int*)test_bits_coh;
         }
 
-       fwrite(tx_bits, sizeof(int), COHPSK_BITS_PER_FRAME, fout);
+        for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+            sd_tx_bits[i] = 1.0 - 2.0*tx_bits[i];
+
+       fwrite(sd_tx_bits, sizeof(float), COHPSK_BITS_PER_FRAME, fout);
  
        /* if this is in a pipeline, we probably don't want the usual
           buffering to occur */
index 6740b4b2548943402f57eb414ce54f241d45fffb..ca2304cffcb57a7c269a6e1109489f596d57debb 100644 (file)
@@ -72,6 +72,10 @@ struct COHPSK {
     
     int           verbose;
 
+    int          *ptest_bits_coh_tx;
+    int          *ptest_bits_coh_rx;
+    int          *ptest_bits_coh_end;
+
     /* optional log variables used for testing Octave to C port */
 
     COMP          *rx_baseband_log;
index c47f0de50a05a176412f916f42f98d2f6d64de2d..3678d27300294fe076e13728c9c0ca89e75fd1fd 100644 (file)
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
     int           i;
 
     if (argc < 3) {
-       printf("usage: %s InputOneBitPerIntFile OutputModemRawFile\n", argv[0]);
+       printf("usage: %s InputOneFloatPerBitFile OutputModemRawFile\n", argv[0]);
        exit(1);
     }
 
index 9164977a59fd1947f1fafa21884fb5acdf3d1da2..f11fa16cab870c3caf119eea780c4e4eb67c4dea 100644 (file)
@@ -35,7 +35,6 @@
 #include <errno.h>
 
 #include "codec2_cohpsk.h"
-#include "test_bits_coh.h"
 #include "octave.h"
 
 #define LOG_FRAMES 100
@@ -44,17 +43,17 @@ int main(int argc, char *argv[])
 {
     FILE         *fin, *foct;
     float         rx_bits_sd[COHPSK_BITS_PER_FRAME];
-    int           rx_bits[COHPSK_BITS_PER_FRAME];
-    int          *ptest_bits_coh, *ptest_bits_coh_end;
-    int           state, next_state, i, nbits, errors, nerrors;
+    int           state, i, nbits, bit_errors, nerrors;
+    short         error_pattern[COHPSK_BITS_PER_FRAME];
     int           error_positions_hist[COHPSK_BITS_PER_FRAME], logframes;
     int           nerr_log[LOG_FRAMES];
+    struct COHPSK *coh;
 
     for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
         error_positions_hist[i] = 0;
 
     if (argc < 2) {
-       fprintf(stderr, "usage: %s InputOneBitPerIntFile [OctaveLogFile]\n", argv[0]);
+       fprintf(stderr, "usage: %s InputOneFloatPerBitFile [OctaveLogFile]\n", argv[0]);
        exit(1);
     }
 
@@ -65,6 +64,8 @@ int main(int argc, char *argv[])
        exit(1);
     }
 
+    coh = cohpsk_create();
+
     foct = NULL;
     logframes = 0;
     if (argc == 3) {
@@ -78,54 +79,19 @@ int main(int argc, char *argv[])
     for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
         error_positions_hist[i] = 0;
 
-    ptest_bits_coh = (int*)test_bits_coh;
-    ptest_bits_coh_end = (int*)test_bits_coh + sizeof(test_bits_coh)/sizeof(int);
-
     state = 0; nbits = 0; nerrors = 0;
     while (fread(rx_bits_sd, sizeof(float), COHPSK_BITS_PER_FRAME, fin) ==  COHPSK_BITS_PER_FRAME) {
-        for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
-            rx_bits[i] = rx_bits_sd[i] < 0.0;
-            //fprintf(stderr,"%f %d\n", rx_bits_sd[i], rx_bits[i]);
-        }
-
-        errors = 0;
-        for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
-            errors += (rx_bits[i] & 0x1) ^ ptest_bits_coh[i];
-            if (state == 1) {
-                if ((state == 1 ) && (rx_bits[i] & 0x1) ^ ptest_bits_coh[i])
-                    error_positions_hist[i]++;
-            }
-        }
-        //printf("state: %d errors: %d nerrors: %d\n", state, errors, nerrors);
-
-        /* state logic */
-
-        next_state = state;
-
-        if (state == 0) {
-            if (errors < 4) {
-                next_state = 1;
-                ptest_bits_coh += COHPSK_BITS_PER_FRAME;
-                nerrors = errors;
-                nbits = COHPSK_BITS_PER_FRAME;
-                if (logframes < LOG_FRAMES)
-                    nerr_log[logframes++] = errors;
-            }
-        }
 
+        cohpsk_put_test_bits(coh, &state, error_pattern, &bit_errors, rx_bits_sd);
         if (state == 1) {
-            nerrors += errors;
+            for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                error_positions_hist[i] += error_pattern[i];
+           if (logframes < LOG_FRAMES)
+                nerr_log[logframes++] = bit_errors;
+            nerrors += bit_errors;
             nbits   += COHPSK_BITS_PER_FRAME;
-            ptest_bits_coh += COHPSK_BITS_PER_FRAME;
-            if (ptest_bits_coh >= ptest_bits_coh_end) {
-                ptest_bits_coh = (int*)test_bits_coh;
-            }
-            if (logframes < LOG_FRAMES)
-                nerr_log[logframes++] = errors;
         }
 
-        state = next_state;
-
         if (fin == stdin) fflush(stdin);
     }
 
index 5d672beb98ccda45f207a9faa8739eb654bd104c..04726d873db4b3ddb9d492958f0398ab51d3c2be 100644 (file)
@@ -58,7 +58,7 @@
 
 struct freedv *freedv_open(int mode) {
     struct freedv *f;
-    int            Nc, codec2_mode, nbit, nbyte, i;
+    int            Nc, codec2_mode, nbit, nbyte;
     
     if ((mode != FREEDV_MODE_1600) && (mode != FREEDV_MODE_700))
         return NULL;
@@ -68,6 +68,7 @@ struct freedv *freedv_open(int mode) {
         return NULL;
     
     f->mode = mode;
+    f->test_frames = 0;
     
     if (mode == FREEDV_MODE_1600) {
         Nc = 16;
@@ -107,6 +108,10 @@ struct freedv *freedv_open(int mode) {
             return NULL;
     }
 
+    f->test_frame_sync_state = 0;
+    f->total_bits = 0;
+    f->total_bit_errors = 0;
+
     f->codec2 = codec2_create(codec2_mode);
     if (f->codec2 == NULL)
         return NULL;
@@ -284,6 +289,14 @@ void freedv_comptx(struct freedv *f, COMP mod_out[], short speech_in[]) {
         }
         f->tx_bits[i] = 0; /* spare bit */
  
+        /* optionally overwrite with test frames */
+
+        if (f->test_frames) {
+            fdmdv_get_test_bits(f->fdmdv, f->tx_bits);
+            fdmdv_get_test_bits(f->fdmdv, &f->tx_bits[bits_per_modem_frame]);
+            //fprintf(stderr, "test frames on tx\n");
+        }
+
         /* modulate even and odd frames */
 
         fdmdv_mod(f->fdmdv, tx_fdm, f->tx_bits, &f->tx_sync_bit);
@@ -344,6 +357,12 @@ void freedv_comptx(struct freedv *f, COMP mod_out[], short speech_in[]) {
 
         }
             
+        /* optionally ovwerwrite the codec bits with test frames */
+
+        if (f->test_frames) {
+            cohpsk_get_test_bits(f->cohpsk, f->codec_bits);
+        }
+
         /* cohpsk modulator */
 
         cohpsk_mod(f->cohpsk, tx_fdm, f->codec_bits);
@@ -435,7 +454,7 @@ int freedv_floatrx(struct freedv *f, short speech_out[], float demod_in[]) {
 int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) {
     assert(f != NULL);
     int                 bits_per_codec_frame, bytes_per_codec_frame, bits_per_fdmdv_frame;
-    int                 sync, i, j, bit, byte, nin_prev, nout, k;
+    int                 i, j, bit, byte, nin_prev, nout, k;
     int                 recd_codeword, codeword1, data_flag_index, n_ascii;
     short               abit[1];
     char                ascii_out;
@@ -467,7 +486,7 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) {
             else {
                 memcpy(&f->rx_bits[bits_per_fdmdv_frame], f->fdmdv_bits, bits_per_fdmdv_frame*sizeof(int));
    
-                if (f->mode == FREEDV_MODE_1600) {
+                if (f->test_frames == 0) {
                     recd_codeword = 0;
                     for(i=0; i<8; i++) {
                         recd_codeword <<= 1;
@@ -496,41 +515,69 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) {
                     for(i=8,j=11; i<12; i++,j++) {
                         f->codec_bits[j] = (codeword1 >> (22-i)) & 0x1;
                     }
-                }
+                    // extract txt msg data bit ------------------------------------------------------------
 
-                // extract txt msg data bit ------------------------------------------------------------
+                    data_flag_index = codec2_get_spare_bit_index(f->codec2);
+                    abit[0] = f->codec_bits[data_flag_index];
 
-                data_flag_index = codec2_get_spare_bit_index(f->codec2);
-                abit[0] = f->codec_bits[data_flag_index];
+                    n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
+                    if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
+                        (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+                    }
 
-                n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
-                if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
-                    (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+                    // reconstruct missing bit we steal for data bit and decode speech
+
+                    codec2_rebuild_spare_bit(f->codec2, f->codec_bits);
+
+                    // pack bits, MSB received first
+
+                    bit  = 7;
+                    byte = 0;
+                    memset(f->packed_codec_bits, 0,  bytes_per_codec_frame);
+                    for(i=0; i<bits_per_codec_frame; i++) {
+                        f->packed_codec_bits[byte] |= (f->codec_bits[i] << bit);
+                        bit--;
+                        if(bit < 0) {
+                            bit = 7;
+                            byte++;
+                        }
+                    }
+
+                    codec2_decode(f->codec2, speech_out, f->packed_codec_bits);
                 }
+                else {
+                    int   test_frame_sync, bit_errors, ntest_bits, k;
+                    short error_pattern[fdmdv_error_pattern_size(f->fdmdv)];
 
-                // reconstruct missing bit we steal for data bit and decode speech
+                    for(k=0; k<2; k++) {
+                        /* test frames, so lets sync up to the test frames and count any errors */
+                        fdmdv_put_test_bits(f->fdmdv, &test_frame_sync, error_pattern, &bit_errors, &ntest_bits, &f->rx_bits[k*bits_per_fdmdv_frame]);
 
-                codec2_rebuild_spare_bit(f->codec2, f->codec_bits);
+                        if (test_frame_sync == 1) {
+                            f->test_frame_sync_state = 1;
+                            f->test_frame_count = 0;
+                        }
 
-                // pack bits, MSB received first
+                        if (f->test_frame_sync_state) {
+                            if (f->test_frame_count == 0) {
+                                f->total_bit_errors += bit_errors;
+                                f->total_bits += ntest_bits;
+                            }
+                            f->test_frame_count++;
+                            if (f->test_frame_count == 4)
+                                f->test_frame_count = 0;
+                        }
 
-                bit  = 7;
-                byte = 0;
-                memset(f->packed_codec_bits, 0,  bytes_per_codec_frame);
-                for(i=0; i<bits_per_codec_frame; i++) {
-                    f->packed_codec_bits[byte] |= (f->codec_bits[i] << bit);
-                    bit--;
-                    if(bit < 0) {
-                        bit = 7;
-                        byte++;
+                        //fprintf(stderr, "test_frame_sync: %d test_frame_sync_state: %d bit_errors: %d ntest_bits: %d\n",
+                        //        test_frame_sync, f->test_frame_sync_state, bit_errors, ntest_bits);
                     }
                 }
 
-                codec2_decode(f->codec2, speech_out, f->packed_codec_bits);
 
-                /* squelch if beneath SNR threshold */
+                /* squelch if beneath SNR threshold or test frames enabled */
 
-                if (f->stats.snr_est < f->snr_thresh) {
+                if ((f->stats.snr_est < f->snr_thresh) || f->test_frames) {
                     for(i=0; i<f->n_speech_samples; i++)
                         speech_out[i] = 0;
                 }
@@ -561,40 +608,58 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) {
 
        if (sync) {
 
-            data_flag_index = codec2_get_spare_bit_index(f->codec2);
+            if (f->test_frames == 0) {
+                data_flag_index = codec2_get_spare_bit_index(f->codec2);
 
-            for (j=0; j<COHPSK_BITS_PER_FRAME; j+=bits_per_codec_frame) {
+                for (j=0; j<COHPSK_BITS_PER_FRAME; j+=bits_per_codec_frame) {
                 
-                /* extract txt msg data bits */
+                    /* extract txt msg data bits */
                 
-                for(k=0; k<2; k++)  {
-                    abit[0] = rx_bits[data_flag_index+j+k] < 0.0;
+                    for(k=0; k<2; k++)  {
+                        abit[0] = rx_bits[data_flag_index+j+k] < 0.0;
                     
-                    n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
-                    if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
-                        (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+                        n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
+                        if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
+                            (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+                        }
                     }
-                }
 
-                /* pack bits, MSB received first */
+                    /* pack bits, MSB received first */
 
-                bit = 7; byte = 0;
-                memset(f->packed_codec_bits, 0, bytes_per_codec_frame);
-                for(i=0; i<bits_per_codec_frame; i++) {
-                    f->packed_codec_bits[byte] |= ((rx_bits[j+i] < 0.0) << bit);
-                    bit--;
-                    if (bit < 0) {
-                        bit = 7;
-                        byte++;
+                    bit = 7; byte = 0;
+                    memset(f->packed_codec_bits, 0, bytes_per_codec_frame);
+                    for(i=0; i<bits_per_codec_frame; i++) {
+                        f->packed_codec_bits[byte] |= ((rx_bits[j+i] < 0.0) << bit);
+                        bit--;
+                        if (bit < 0) {
+                            bit = 7;
+                            byte++;
+                        }
                     }
+
+                    codec2_decode(f->codec2, speech_out, f->packed_codec_bits);
+                    speech_out += codec2_samples_per_frame(f->codec2);
                 }
+                nout = f->n_speech_samples;
+            }
+            else {
+                short error_pattern[COHPSK_BITS_PER_FRAME];
+                int   bit_errors;
+
+                /* test data, lets see if we can sync to the test data sequence */
 
-                codec2_decode(f->codec2, speech_out, f->packed_codec_bits);
-                speech_out += codec2_samples_per_frame(f->codec2);
+                cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state, error_pattern, &bit_errors, rx_bits);
+                if (f->test_frame_sync_state == 1) {
+                    //for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                    //    error_positions_hist[i] += error_pattern[i];
+                    f->total_bit_errors += bit_errors;
+                    f->total_bits       += COHPSK_BITS_PER_FRAME;
+                }
             }
-            nout = f->n_speech_samples;
+            
         }
-        else {
+
+        if ((sync == 0) || f->test_frames) {
             float t,a,b,s;
             int   t1,t2;
 
@@ -612,59 +677,8 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) {
             nout = f->n_speech_samples;
             //fprintf(stderr, "%d %d %d\n", f->n_speech_samples, speech_out[0], speech_out[nin_prev-1]);
         }
-     }
-
+    }
+    
     return nout;
 }
 
-
-#ifdef TODO
-                if (g_testFrames) {
-                    int bit_errors, ntest_bits, test_frame_sync;
-
-                    // test frame processing, g_test_frame_sync will be asserted when we detect a
-                    // valid test frame.
-
-                    fdmdv_put_test_bits(g_pFDMDV, &test_frame_sync, g_error_pattern, &bit_errors, &ntest_bits, codec_bits);
-
-                    if (test_frame_sync == 1) {
-                        g_test_frame_sync_state = 1;
-                        g_test_frame_count = 0;
-                    }
-
-                    if (g_test_frame_sync_state) {
-                        if (g_test_frame_count == 0) {
-                            //printf("bit_errors: %d ntest_bits: %d\n", bit_errors, ntest_bits);
-                            g_total_bit_errors += bit_errors;
-                            g_total_bits       += ntest_bits;
-                            fifo_write(g_errorFifo, g_error_pattern, g_sz_error_pattern);
-                        }
-                        g_test_frame_count++;
-                        if (g_test_frame_count == 4)
-                            g_test_frame_count = 0;
-                    }
-
-                    fdmdv_put_test_bits(g_pFDMDV, &test_frame_sync, g_error_pattern, &bit_errors, &ntest_bits, &codec_bits[bits_per_fdmdv_frame]);
-
-                    if (test_frame_sync == 1) {
-                        g_test_frame_sync_state = 1;
-                        g_test_frame_count = 0;
-                    }
-
-                    if (g_test_frame_sync_state) {
-                        if (g_test_frame_count == 0) {
-                            //printf("bit_errors: %d ntest_bits: %d\n", bit_errors, ntest_bits);
-                            g_total_bit_errors += bit_errors;
-                            g_total_bits       += ntest_bits;
-                            fifo_write(g_errorFifo, g_error_pattern, g_sz_error_pattern);
-                        }
-                        g_test_frame_count++;
-                        if (g_test_frame_count == 4)
-                            g_test_frame_count = 0;
-                    }
-
-                    // silent audio
-
-                    for(i=0; i<2*N8; i++)
-                        output_buf[i] = 0;
-#endif
index 70463ea576771c058e119952ee0f16956fe82c67..d4aa18755c810c12c4c1b2ef22fc327fc4eb0f9a 100644 (file)
@@ -62,6 +62,14 @@ struct freedv {
     int                 *fdmdv_bits;
     int                 *rx_bits;
     int                  tx_sync_bit;
+
+    int                 *ptest_bits_coh;
+    int                 *ptest_bits_coh_end;
+
+    int                  test_frames;            // set this baby for 1 to tx/rx test frames to look at bit error stats
+    int                  test_frame_sync_state;
+    int                  test_frame_count;
+    int                  total_bits;
     int                  total_bit_errors;
 
     int                  sync;
index 285b619ebf7ade128b3978b4e0788a834835ff8d..ffc499b611b01b1e10342e6664c3731b37fd98b8 100644 (file)
@@ -42,7 +42,7 @@ struct my_callback_state {
 void my_put_next_rx_char(void *callback_state, char c) {
     struct my_callback_state* pstate = (struct my_callback_state*)callback_state;
     if (pstate->ftxt != NULL) {
-        fprintf(stderr, "%c", c);
+        fprintf(pstate->ftxt, "%c", c);
     }
 }
 
@@ -51,12 +51,12 @@ int main(int argc, char *argv[]) {
     short                     *speech_out;
     short                     *demod_in;
     struct freedv             *freedv;
-    int                        nin, nout, frame;
+    int                        nin, nout, frame = 0;
     struct my_callback_state   my_cb_state;
     int                        mode;
 
     if (argc < 4) {
-       printf("usage: %s 1600|700 InputModemSpeechFile OutputSpeechawFile txtLogFile\n", argv[0]);
+       printf("usage: %s 1600|700 InputModemSpeechFile OutputSpeechRawFile [--test_frames]\n", argv[0]);
        printf("e.g    %s 1600 hts1a_fdmdv.raw hts1a_out.raw txtLogFile\n", argv[0]);
        exit(1);
     }
@@ -82,24 +82,21 @@ int main(int argc, char *argv[]) {
        exit(1);
     }
     
-    ftxt = NULL;
-    if ( (argc > 4) && (strcmp(argv[4],"|") != 0) ) {
-        if ((ftxt = fopen(argv[4],"wt")) == NULL ) {
-            fprintf(stderr, "Error opening txt Log File: %s: %s.\n",
-                    argv[4], strerror(errno));
-            exit(1);
-        }
-    }
-    
     freedv = freedv_open(mode);
-    cohpsk_set_verbose(freedv->cohpsk, 1);
+    if (mode == FREEDV_MODE_700)
+        cohpsk_set_verbose(freedv->cohpsk, 1);
     assert(freedv != NULL);
 
+    if ( (argc > 4) && (strcmp(argv[4], "--testframes") == 0) ) {
+        freedv->test_frames = 1;
+    }
+    
     speech_out = (short*)malloc(sizeof(short)*freedv->n_speech_samples);
     assert(speech_out != NULL);
     demod_in = (short*)malloc(sizeof(short)*freedv->n_max_modem_samples);
     assert(demod_in != NULL);
 
+    ftxt = stderr;
     my_cb_state.ftxt = ftxt;
     freedv->callback_state = (void*)&my_cb_state;
     freedv->freedv_put_next_rx_char = &my_put_next_rx_char;
@@ -117,13 +114,20 @@ int main(int argc, char *argv[]) {
         fwrite(speech_out, sizeof(short), nout, fout);
         nin = freedv_nin(freedv);
 
+        if (freedv->mode == FREEDV_MODE_1600)
+            fdmdv_get_demod_stats(freedv->fdmdv, &freedv->stats);
+        if (freedv->mode == FREEDV_MODE_700)
+            cohpsk_get_demod_stats(freedv->cohpsk, &freedv->stats);
+
         /* log some side info to the txt file */
         
         frame++;
+        /*
         if (ftxt != NULL) {
             fprintf(ftxt, "frame: %d  demod sync: %d  demod snr: %3.2f dB  bit errors: %d\n", frame, 
                     freedv->stats.sync, freedv->stats.snr_est, freedv->total_bit_errors);
         }
+        */
 
        /* if this is in a pipeline, we probably don't want the usual
            buffering to occur */
@@ -132,6 +136,10 @@ int main(int argc, char *argv[]) {
         if (fin == stdin) fflush(stdin);         
     }
 
+    if (freedv->test_frames) {
+        fprintf(stderr, "bits: %d errors: %d BER: %3.2f\n", freedv->total_bits, freedv->total_bit_errors, (float)freedv->total_bit_errors/freedv->total_bits);
+    }
+
     free(speech_out);
     free(demod_in);
     freedv_close(freedv);
index c13303c727eebc7e7f83fcce502bb27e468cbd8f..80e4c4798d2f5de5a0e653ff89c9cd9c4aed24b7 100644 (file)
@@ -58,7 +58,7 @@ int main(int argc, char *argv[]) {
     int                       mode;
 
     if (argc < 4) {
-       printf("usage: %s 1600|700 InputRawSpeechFile OutputModemRawFile\n", argv[0]);
+       printf("usage: %s 1600|700 InputRawSpeechFile OutputModemRawFile [--testframes]\n", argv[0]);
        printf("e.g    %s 1600 hts1a.raw hts1a_fdmdv.raw\n", argv[0]);
        exit(1);
     }
@@ -87,6 +87,10 @@ int main(int argc, char *argv[]) {
     freedv = freedv_open(mode);
     assert(freedv != NULL);
 
+    if ((argc > 4) && (strcmp(argv[4], "--testframes") == 0)) {
+        freedv->test_frames = 1;
+    }
+
     speech_in = (short*)malloc(sizeof(short)*freedv->n_speech_samples);
     assert(speech_in != NULL);
     mod_out = (short*)malloc(sizeof(short)*freedv->n_nom_modem_samples);