Jim's wonderful 7500-8000Hz sample rate changing code, tests out OK
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 7 Sep 2015 20:58:14 +0000 (20:58 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 7 Sep 2015 20:58:14 +0000 (20:58 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2300 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/freedv_api.c
codec2-dev/src/freedv_api_internal.h
codec2-dev/src/freedv_rx.c

index e8e62c8c09d6eac1f8ef5ba950a4efe9caedac39..4d4246744ea5e741f67c2a872e109abbe9b9cf7d 100644 (file)
 #include "freedv_api_internal.h"
 #include "comp_prim.h"
 
-#define VERSION     10 /* The API version number.  The first version
+#define VERSION     11    /* The API version number.  The first version
                            is 10.  Increment if the API changes in a
                            way that would require changes by the API
                            user. */
 /*
  * Version 10   Initial version August 2, 2015.
- * Version 11   September
- *              Changes go here.
- *
+ * Version 11   September 2015
+ *              Added: freedv_zero_total_bit_errors(), freedv_get_sync()
+ *              Changed all input and output sample rates to 8000 sps.  Rates for FREEDV_MODE_700 and 700B were 7500.
  */
 
 #define NORM_PWR  1.74   /* experimentally derived fudge factor so 1600 and 
@@ -94,6 +94,7 @@ struct freedv *freedv_open(int mode) {
         golay23_init();
         f->nin = FDMDV_NOM_SAMPLES_PER_FRAME;
         f->n_nom_modem_samples = 2*FDMDV_NOM_SAMPLES_PER_FRAME;
+        f->n_nat_modem_samples = f->n_nom_modem_samples;
         f->n_max_modem_samples = FDMDV_NOM_SAMPLES_PER_FRAME+FDMDV_MAX_SAMPLES_PER_FRAME;
         f->modem_sample_rate = FS;
         nbit = fdmdv_bits_per_frame(f->fdmdv);
@@ -119,8 +120,9 @@ struct freedv *freedv_open(int mode) {
             codec2_mode = CODEC2_MODE_700B;            
         f->cohpsk = cohpsk_create();
         f->nin = COHPSK_NOM_SAMPLES_PER_FRAME;
-        f->n_nom_modem_samples = COHPSK_NOM_SAMPLES_PER_FRAME;
-        f->n_max_modem_samples = COHPSK_MAX_SAMPLES_PER_FRAME;
+        f->n_nat_modem_samples = COHPSK_NOM_SAMPLES_PER_FRAME;          // native modem samples as used by the modem
+        f->n_nom_modem_samples = f->n_nat_modem_samples * 8000 / 7500;  // number of samples after native samples are interpolated to 8000 sps
+        f->n_max_modem_samples = COHPSK_MAX_SAMPLES_PER_FRAME * 8000 / 7500 + 1;
         f->modem_sample_rate = COHPSK_FS;                /* note wierd sample rate */
         f->clip = 1;
         nbit = COHPSK_BITS_PER_FRAME;
@@ -157,6 +159,17 @@ struct freedv *freedv_open(int mode) {
     if ((f->packed_codec_bits == NULL) || (f->codec_bits == NULL))
         return NULL;
 
+    if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B)) {        // change modem rates to 8000 sps
+        f->ptFilter7500to8000 = (struct quisk_cfFilter *)malloc(sizeof(struct quisk_cfFilter));
+        f->ptFilter8000to7500 = (struct quisk_cfFilter *)malloc(sizeof(struct quisk_cfFilter));
+        quisk_filt_cfInit(f->ptFilter8000to7500, quiskFilt120t480, sizeof(quiskFilt120t480)/sizeof(float));
+        quisk_filt_cfInit(f->ptFilter7500to8000, quiskFilt120t480, sizeof(quiskFilt120t480)/sizeof(float));
+    }
+    else {
+        f->ptFilter7500to8000 = NULL;
+        f->ptFilter8000to7500 = NULL;
+    }
+
     varicode_decode_init(&f->varicode_dec_states, 1);
     f->nvaricode_bits = 0;
     f->varicode_bit_index = 0;
@@ -192,6 +205,16 @@ void freedv_close(struct freedv *freedv) {
         cohpsk_destroy(freedv->cohpsk);
 #endif
     codec2_destroy(freedv->codec2);
+    if (freedv->ptFilter8000to7500) {
+        quisk_filt_destroy(freedv->ptFilter8000to7500);
+        free(freedv->ptFilter8000to7500);
+        freedv->ptFilter8000to7500 = NULL;
+    }
+    if (freedv->ptFilter7500to8000) {
+        quisk_filt_destroy(freedv->ptFilter7500to8000);
+        free(freedv->ptFilter7500to8000);
+        freedv->ptFilter7500to8000 = NULL;
+    }
     free(freedv);
 }
 
@@ -210,15 +233,10 @@ void freedv_close(struct freedv *freedv) {
   should be such that the peak speech level is between +/- 16384 and
   +/- 32767.
 
-  The FDM modem signal mod_out[] is sampled at
-  freedv_get_modem_sample_rate() Hz and is
+  The FDM modem signal mod_out[] is sampled at 8000 Hz and is
   freedv_get_n_nom_modem_samples() long.  mod_out[] will be scaled
   such that the peak level is just less than +/-32767.
 
-  Note that freedv_get_modem_sample_rate() is 8000 Hz for 1600 mode
-  but 7500 Hz for 700 and 700B mode. You must convert sample rates as
-  required.
-
   The complex-valued output can directly drive an I/Q modulator to
   produce a single sideband signal.  To generate the other sideband,
   take the complex conjugate of mod_out[].
@@ -258,7 +276,7 @@ void freedv_comptx(struct freedv *f, COMP mod_out[], short speech_in[]) {
     int    bit, byte, i, j, k;
     int    bits_per_codec_frame, bits_per_modem_frame;
     int    data, codeword1, data_flag_index, nspare;
-    COMP   tx_fdm[f->n_nom_modem_samples];
+    COMP   tx_fdm[f->n_nat_modem_samples];
      
     assert((f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B));
 
@@ -415,14 +433,22 @@ void freedv_comptx(struct freedv *f, COMP mod_out[], short speech_in[]) {
         cohpsk_mod(f->cohpsk, tx_fdm, f->codec_bits);
         if (f->clip)
             cohpsk_clip(tx_fdm);
-        for(i=0; i<f->n_nom_modem_samples; i++)
+        for(i=0; i<f->n_nat_modem_samples; i++)
             mod_out[i] = fcmult(FDMDV_SCALE*NORM_PWR, tx_fdm[i]);
+        i = quisk_cfInterpDecim(mod_out, f->n_nat_modem_samples, f->ptFilter7500to8000, 16, 15);
+        //assert(i == f->n_nom_modem_samples);
+        // Caution: assert fails if f->n_nat_modem_samples * 16.0 / 15.0 is not an integer
     }
 #endif
 }
 
 int freedv_nin(struct freedv *f) {
-    return f->nin;
+    if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B))
+        // For mode 700, the input rate is 8000 sps, but the modem rate is 7500 sps
+        // For mode 700, we request a larger number of Rx samples that will be decimated to f->nin samples
+        return (16 * f->nin + f->ptFilter8000to7500->decim_index) / 15;
+    else
+        return f->nin;
 }
 
 /*---------------------------------------------------------------------------*\
@@ -435,9 +461,8 @@ int freedv_nin(struct freedv *f) {
   decodes them, producing a frame of decoded speech samples.  See
   freedv_rx.c for an example.
 
-  demod_in[] is a variable length block of received samples at the
-  modem sample rate given by freedv_get_n_max_modem_samples().  To
-  account for difference in the transmit and receive sample clock
+  demod_in[] is a block of received samples sampled at 8000 Hz.
+  To account for difference in the transmit and receive sample clock
   frequencies, the number of demod_in[] samples is time varying. You
   MUST call freedv_nin() BEFORE each call to freedv_rx() and pass
   exactly that many samples to this function.
@@ -456,7 +481,7 @@ int freedv_nin(struct freedv *f) {
   freedv_get_n_speech_samples() and 0.
 
   700 and 700B mode: The number of output speech samples returned will
-  is always be freedv_get_n_speech_samples(), regardless of sync.
+  always be freedv_get_n_speech_samples(), regardless of sync.
 
   The peak level of demod_in[] is not critical, as the demod works
   well over a wide range of amplitude scaling.  However avoid clipping
@@ -478,10 +503,11 @@ int freedv_rx(struct freedv *f, short speech_out[], short demod_in[]) {
     assert(f != NULL);
     COMP rx_fdm[f->n_max_modem_samples];
     int i;
+    int nin = freedv_nin(f);
 
-    assert(f->nin <= f->n_max_modem_samples);
+    assert(nin <= f->n_max_modem_samples);
 
-    for(i=0; i<f->nin; i++) {
+    for(i=0; i<nin; i++) {
         rx_fdm[i].real = (float)demod_in[i];
         rx_fdm[i].imag = 0.0;
     }
@@ -496,10 +522,11 @@ int freedv_floatrx(struct freedv *f, short speech_out[], float demod_in[]) {
     assert(f != NULL);
     COMP rx_fdm[f->n_max_modem_samples];
     int  i;
+    int nin = freedv_nin(f);
 
-    assert(f->nin <= f->n_max_modem_samples);
+    assert(nin <= f->n_max_modem_samples);
 
-    for(i=0; i<f->nin; i++) {
+    for(i=0; i<nin; i++) {
         rx_fdm[i].real = demod_in[i];
         rx_fdm[i].imag = 0;
     }
@@ -520,15 +547,15 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) {
 
     assert(f->nin <= f->n_max_modem_samples);
 
-    for(i=0; i<f->nin; i++)
-        demod_in[i] = fcmult(1.0/FDMDV_SCALE, demod_in[i]);
-
     bits_per_codec_frame  = codec2_bits_per_frame(f->codec2);
     bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
     nout = f->n_speech_samples;
 
     if (f->mode == FREEDV_MODE_1600) {
 
+        for(i=0; i<f->nin; i++)
+            demod_in[i] = fcmult(1.0/FDMDV_SCALE, demod_in[i]);
+
         bits_per_fdmdv_frame  = fdmdv_bits_per_frame(f->fdmdv);
 
         nin_prev = f->nin;
@@ -688,13 +715,20 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) {
         float rx_bits[COHPSK_BITS_PER_FRAME];
         int   sync;
 
+        i = quisk_cfInterpDecim(demod_in, freedv_nin(f), f->ptFilter8000to7500, 15, 16);
+        //if (i != f->nin)
+        //    printf("freedv_comprx decimation: input %d output %d\n", freedv_nin(f), i);
+
+        for(i=0; i<f->nin; i++)
+            demod_in[i] = fcmult(1.0/FDMDV_SCALE, demod_in[i]);
+
         nin_prev = f->nin;
-       cohpsk_demod(f->cohpsk, rx_bits, &sync, demod_in, &f->nin);
+        cohpsk_demod(f->cohpsk, rx_bits, &sync, demod_in, &f->nin);
         f->sync = sync;
         cohpsk_get_demod_stats(f->cohpsk, &f->stats);
         f->snr_est = f->stats.snr_est;
 
-       if (sync) {
+        if (sync) {
 
             if (f->test_frames == 0) {
                 data_flag_index = codec2_get_spare_bit_index(f->codec2);
@@ -896,11 +930,11 @@ void freedv_get_modem_stats(struct freedv *f, int *sync, float *snr_est)
 \*---------------------------------------------------------------------------*/
 
 // Set integers
-void freedv_set_test_frames                            (struct freedv *f, int val) {f->smooth_symbols = val;}
-void freedv_set_squelch_en                             (struct freedv *f, int val) {f->squelch_en = val;}
-void freedv_zero_total_bit_errors                      (struct freedv *f) {f->total_bit_errors = 0;}
+void freedv_set_test_frames               (struct freedv *f, int val) {f->test_frames = val;}
+void freedv_set_squelch_en                (struct freedv *f, int val) {f->squelch_en = val;}
+void freedv_zero_total_bit_errors         (struct freedv *f) {f->total_bit_errors = 0;}
 // Set floats
-void freedv_set_snr_squelch_thresh             (struct freedv *f, float val) {f->snr_squelch_thresh = val;}
+void freedv_set_snr_squelch_thresh        (struct freedv *f, float val) {f->snr_squelch_thresh = val;}
 
 /*---------------------------------------------------------------------------*\
                                                        
@@ -914,13 +948,115 @@ void freedv_set_snr_squelch_thresh               (struct freedv *f, float val) {f->snr_squelc
 \*---------------------------------------------------------------------------*/
 
 // Get integers
-int freedv_get_test_frames                             (struct freedv *f) {return f->test_frames;}
-int freedv_get_n_speech_samples                        (struct freedv *f) {return f->n_speech_samples;}
-int freedv_get_modem_sample_rate               (struct freedv *f) {return f->modem_sample_rate;}
-int freedv_get_n_max_modem_samples             (struct freedv *f) {return f->n_max_modem_samples;}
-int freedv_get_n_nom_modem_samples             (struct freedv *f) {return f->n_nom_modem_samples;}
-int freedv_get_total_bits                              (struct freedv *f) {return f->total_bits;}
-int freedv_get_total_bit_errors                        (struct freedv *f) {return f->total_bit_errors;}
-int freedv_get_sync                            (struct freedv *f) {return  f->stats.sync;}
+int freedv_get_test_frames                (struct freedv *f) {return f->test_frames;}
+int freedv_get_n_speech_samples           (struct freedv *f) {return f->n_speech_samples;}
+//int freedv_get_modem_sample_rate        (struct freedv *f) {return f->modem_sample_rate;}
+int freedv_get_n_max_modem_samples        (struct freedv *f) {return f->n_max_modem_samples;}
+int freedv_get_n_nom_modem_samples        (struct freedv *f) {return f->n_nom_modem_samples;}
+int freedv_get_total_bits                 (struct freedv *f) {return f->total_bits;}
+int freedv_get_total_bit_errors           (struct freedv *f) {return f->total_bit_errors;}
+int freedv_get_sync                       (struct freedv *f) {return  f->stats.sync;}
 // Get floats
 
+
+/*--  Functions below this line are private, and not meant for public use  --*/
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTIONS...: quisk_filt_cfInit
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 27 August 2015
+
+  Initialize a FIR filter that will be used to change sample rates.  These rate
+  changing filters were copied from Quisk and modified for float samples.
+
+\*---------------------------------------------------------------------------*/
+
+static void quisk_filt_cfInit(struct quisk_cfFilter * filter, float * coefs, int taps)
+{    // Prepare a new filter using coefs and taps.  Samples are complex.
+    filter->dCoefs = coefs;
+    filter->cSamples = (COMP *)malloc(taps * sizeof(COMP));
+    memset(filter->cSamples, 0, taps * sizeof(COMP));
+    filter->ptcSamp = filter->cSamples;
+    filter->nTaps = taps;
+    filter->cBuf = NULL;
+    filter->nBuf = 0;
+    filter->decim_index = 0;
+}
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTIONS...: quisk_filt_destroy
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 27 August 2015
+
+  Destroy the FIR filter and free all resources.
+
+\*---------------------------------------------------------------------------*/
+
+static void quisk_filt_destroy(struct quisk_cfFilter * filter)
+{
+    if (filter->cSamples) {
+        free(filter->cSamples);
+        filter->cSamples = NULL;
+    }
+    if (filter->cBuf) {
+        free(filter->cBuf);
+        filter->cBuf = NULL;
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTIONS...: quisk_cfInterpDecim
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 27 August 2015
+
+  Take an array of samples cSamples of length count, multiply the sample rate
+  by interp, and then divide the sample rate by decim.  Return the new number
+  of samples.  Each specific interp and decim will require its own custom
+  FIR filter.
+
+\*---------------------------------------------------------------------------*/
+
+static int quisk_cfInterpDecim(COMP * cSamples, int count, struct quisk_cfFilter * filter, int interp, int decim)
+{   // Interpolate by interp, and then decimate by decim.
+    // This uses the float coefficients of filter (not the complex).  Samples are complex.
+    int i, k, nOut;
+    float * ptCoef;
+    COMP * ptSample;
+    COMP csample;
+
+    if (count > filter->nBuf) {    // increase size of sample buffer
+        filter->nBuf = count * 2;
+        if (filter->cBuf)
+            free(filter->cBuf);
+        filter->cBuf = (COMP *)malloc(filter->nBuf * sizeof(COMP));
+    }
+    memcpy(filter->cBuf, cSamples, count * sizeof(COMP));
+    nOut = 0;
+    for (i = 0; i < count; i++) {
+        // Put samples into buffer left to right.  Use samples right to left.
+        *filter->ptcSamp = filter->cBuf[i];
+        while (filter->decim_index < interp) {
+            ptSample = filter->ptcSamp;
+            ptCoef = filter->dCoefs + filter->decim_index;
+            csample.real = 0;
+            csample.imag = 0;
+            for (k = 0; k < filter->nTaps / interp; k++, ptCoef += interp) {
+                csample.real += (*ptSample).real * *ptCoef;
+                csample.imag += (*ptSample).imag * *ptCoef;
+                if (--ptSample < filter->cSamples)
+                    ptSample = filter->cSamples + filter->nTaps - 1;
+            }
+            cSamples[nOut].real = csample.real * interp;
+            cSamples[nOut].imag = csample.imag * interp;
+            nOut++;
+            filter->decim_index += decim;
+        }
+        if (++filter->ptcSamp >= filter->cSamples + filter->nTaps)
+            filter->ptcSamp = filter->cSamples;
+        filter->decim_index = filter->decim_index - interp;
+    }
+    return nOut;
+}
+
index ac486ea16b4aaed5782d581d8eee2d2662b34209..038d037e96b2873b3fa71cce2c48961207330dcf 100644 (file)
 #include "codec2_fdmdv.h"
 #include "codec2_cohpsk.h"
 
+struct quisk_cfFilter {        // Structure to hold the static data for FIR filters
+    float * dCoefs;    // filter coefficients
+    int nBuf;          // dimension of cBuf
+    int nTaps;         // dimension of dSamples, cSamples, dCoefs
+    int decim_index;   // index of next sample for decimation
+    COMP * cSamples;   // storage for old samples
+    COMP * ptcSamp;    // next available position in cSamples
+    COMP * cBuf;       // auxillary buffer for interpolation
+} ;
+
+static int quisk_cfInterpDecim(COMP *, int, struct quisk_cfFilter *, int, int);
+static void quisk_filt_cfInit(struct quisk_cfFilter *, float *, int);
+static void quisk_filt_destroy(struct quisk_cfFilter *);
+static float quiskFilt120t480[480];
+
 struct freedv {
     int                  mode;
 
@@ -49,9 +64,13 @@ struct freedv {
     struct MODEM_STATS   stats;
     struct COHPSK       *cohpsk;
 
+    struct quisk_cfFilter * ptFilter7500to8000;     // Filters to change to/from 7500 and 8000 sps
+    struct quisk_cfFilter * ptFilter8000to7500;
+
     int                  n_speech_samples;
     int                  n_nom_modem_samples;    // size of tx and most rx modem sample buffers
     int                  n_max_modem_samples;    // make your rx modem sample buffers this big
+    int                  n_nat_modem_samples;    // tx modem sample block length as used by the modem before interpolation to output
 
     int                  modem_sample_rate;      // ATM caller is responsible for meeting this (TBC)
     int                  clip;                   // non-zero for cohpsk modem output clipping for low PAPR
@@ -102,6 +121,105 @@ struct freedv {
 
 };
 
+// FIR filter suitable for changing rates 7500 to/from 8000
+// Sample 120000 Hz, pass 2700, stop 3730, ripple 0.1dB, atten 100 dB.  Stop 0.03108.
+static float quiskFilt120t480[480] = { -0.000005050567303837, -0.000000267011791999, 0.000000197734700398, 0.000001038946634000,
+ 0.000002322193058869, 0.000004115682735322, 0.000006499942123311, 0.000009551098482930, 0.000013350669444763,
+ 0.000017966192635412, 0.000023463361155584, 0.000029885221425020, 0.000037271082107518, 0.000045630720487935,
+ 0.000054970017069384, 0.000065233162392019, 0.000076360900545177, 0.000088271373315159, 0.000100818605854714,
+ 0.000113853476544409, 0.000127174196746337, 0.000140558396336177, 0.000153744508371709, 0.000166450784469067,
+ 0.000178368313347299, 0.000189176709991702, 0.000198541881389953, 0.000206128795372885, 0.000211604878787747,
+ 0.000214655997661182, 0.000214994859281552, 0.000212358734245594, 0.000206539880117977, 0.000197379393194548,
+ 0.000184780318878738, 0.000168719942655099, 0.000149250512353807, 0.000126511346757621, 0.000100726393185629,
+ 0.000072210925236429, 0.000041365841965015, 0.000008680571408025, -0.000025277165852799, -0.000059865389594949,
+-0.000094384355854646, -0.000128080670195777, -0.000160170174848483, -0.000189854272533545, -0.000216333899003825,
+-0.000238836419299503, -0.000256632149501508, -0.000269058714331757, -0.000275541485292432, -0.000275614059005332,
+-0.000268937472718753, -0.000255317038867589, -0.000234717772155001, -0.000207273956099563, -0.000173297342436372,
+-0.000133280012107173, -0.000087895370243821, -0.000037986085678081, 0.000015440388211825, 0.000071232572821451,
+ 0.000128114399130489, 0.000184710477990398, 0.000239577162514028, 0.000291234779803098, 0.000338204791740229,
+ 0.000379047713684221, 0.000412403761615261, 0.000437031818051652, 0.000451848709179591, 0.000455966225408344,
+ 0.000448726371643413, 0.000429729020814434, 0.000398857326863837, 0.000356297600912998, 0.000302547334727027,
+ 0.000238422248479072, 0.000165048886226905, 0.000083853091464077, -0.000003462782744354, -0.000094949813106744,
+-0.000188451833293202, -0.000281651282503015, -0.000372121907291206, -0.000457387566635848, -0.000534985542936898,
+-0.000602532044011899, -0.000657788245032425, -0.000698728981427767, -0.000723604675185869, -0.000731002305621048,
+-0.000719899536922384, -0.000689709694056092, -0.000640319946685634, -0.000572115873292030, -0.000485996080304965,
+-0.000383371840261246, -0.000266155252511831, -0.000136731311264191, 0.000002082667095075, 0.000147092077716480,
+ 0.000294790953130229, 0.000441441918072383, 0.000583164190168290, 0.000716029226064227, 0.000836164238172957,
+ 0.000939856052624227, 0.001023657909064450, 0.001084492755093968, 0.001119751426837743, 0.001127383039339373,
+ 0.001105974243787613, 0.001054815583369999, 0.000973950761085690, 0.000864209315714227, 0.000727219011746881,
+ 0.000565398080608305, 0.000381924396468366, 0.000180685902835315, -0.000033793183292569, -0.000256444114966522,
+-0.000481764526566339, -0.000703946352348464, -0.000917016099829735, -0.001114986581270253, -0.001292014799874503,
+-0.001442563411804926, -0.001561559957317790, -0.001644551048567398, -0.001687846581475964, -0.001688649703502788,
+-0.001645167889846890, -0.001556702802350076, -0.001423714708648073, -0.001247857669697092, -0.001031986722557201,
+-0.000780131048444402, -0.000497436825078657, -0.000190077210351809, 0.000134868279325909, 0.000469563533327739,
+ 0.000805591531546815, 0.001134152328775355, 0.001446279849797673, 0.001733071409562941, 0.001985924997799762,
+ 0.002196778054604388, 0.002358342626407065, 0.002464328098407475, 0.002509648218888532, 0.002490604086803692,
+ 0.002405037734357425, 0.002252452724297770, 0.002034094661603120, 0.001752990365583534, 0.001413941154886139,
+ 0.001023470495638453, 0.000589723521647734, 0.000122320866350319, -0.000367832138027160, -0.000868777013398284,
+-0.001367771151677059, -0.001851587344265625, -0.002306838088978190, -0.002720317947026380, -0.003079353614002113,
+-0.003372155891804708, -0.003588162376578369, -0.003718362558663737, -0.003755596511143005, -0.003694818131674599,
+-0.003533315298404129, -0.003270878754553819, -0.002909914962857412, -0.002455496391464944, -0.001915346645364514,
+-0.001299757227227888, -0.000621437066532776, 0.000104706515738248, 0.000861849931067767, 0.001631595707499856,
+ 0.002394368911341672, 0.003129858565588139, 0.003817496679992245, 0.004436963307209760, 0.004968707287606522,
+ 0.005394469536085115, 0.005697797543539088, 0.005864537618023589, 0.005883292537600076, 0.005745832319314692,
+ 0.005447447099071761, 0.004987231255534477, 0.004368289529377007, 0.003597859022418248, 0.002687338851256991,
+ 0.001652226293162047, 0.000511956075882180, -0.000710356149138656, -0.001988263330091648, -0.003292424566049982,
+-0.004591123342747130, -0.005850857852106148, -0.007036991266043732, -0.008114450164977267, -0.009048456200082230,
+-0.009805276478965942, -0.010352975302354198, -0.010662152577592631, -0.010706650669328861, -0.010464214075017983,
+-0.009917087295446811, -0.009052534679222271, -0.007863270920348924, -0.006347789704693751, -0.004510582323649121,
+-0.002362238055733795, 0.000080576968834213, 0.002795265196543707, 0.005753566158586979, 0.008921944932552510,
+ 0.012262093950265378, 0.015731539846483594, 0.019284344624007944, 0.022871886384520687, 0.026443706729191677,
+ 0.029948406200633094, 0.033334570666910354, 0.036551709955124537, 0.039551189200810140, 0.042287133974308874,
+ 0.044717290029466283, 0.046803820535016104, 0.048514022996355009, 0.049820951883635139, 0.050703932928426454,
+ 0.051148959210315710, 0.051148959210315710, 0.050703932928426454, 0.049820951883635139, 0.048514022996355009,
+ 0.046803820535016104, 0.044717290029466283, 0.042287133974308874, 0.039551189200810140, 0.036551709955124537,
+ 0.033334570666910354, 0.029948406200633094, 0.026443706729191677, 0.022871886384520687, 0.019284344624007944,
+ 0.015731539846483594, 0.012262093950265378, 0.008921944932552510, 0.005753566158586979, 0.002795265196543707,
+ 0.000080576968834213, -0.002362238055733795, -0.004510582323649121, -0.006347789704693751, -0.007863270920348924,
+-0.009052534679222271, -0.009917087295446811, -0.010464214075017983, -0.010706650669328861, -0.010662152577592631,
+-0.010352975302354198, -0.009805276478965942, -0.009048456200082230, -0.008114450164977267, -0.007036991266043732,
+-0.005850857852106148, -0.004591123342747130, -0.003292424566049982, -0.001988263330091648, -0.000710356149138656,
+ 0.000511956075882180, 0.001652226293162047, 0.002687338851256991, 0.003597859022418248, 0.004368289529377007,
+ 0.004987231255534477, 0.005447447099071761, 0.005745832319314692, 0.005883292537600076, 0.005864537618023589,
+ 0.005697797543539088, 0.005394469536085115, 0.004968707287606522, 0.004436963307209760, 0.003817496679992245,
+ 0.003129858565588139, 0.002394368911341672, 0.001631595707499856, 0.000861849931067767, 0.000104706515738248,
+-0.000621437066532776, -0.001299757227227888, -0.001915346645364514, -0.002455496391464944, -0.002909914962857412,
+-0.003270878754553819, -0.003533315298404129, -0.003694818131674599, -0.003755596511143005, -0.003718362558663737,
+-0.003588162376578369, -0.003372155891804708, -0.003079353614002113, -0.002720317947026380, -0.002306838088978190,
+-0.001851587344265625, -0.001367771151677059, -0.000868777013398284, -0.000367832138027160, 0.000122320866350319,
+ 0.000589723521647734, 0.001023470495638453, 0.001413941154886139, 0.001752990365583534, 0.002034094661603120,
+ 0.002252452724297770, 0.002405037734357425, 0.002490604086803692, 0.002509648218888532, 0.002464328098407475,
+ 0.002358342626407065, 0.002196778054604388, 0.001985924997799762, 0.001733071409562941, 0.001446279849797673,
+ 0.001134152328775355, 0.000805591531546815, 0.000469563533327739, 0.000134868279325909, -0.000190077210351809,
+-0.000497436825078657, -0.000780131048444402, -0.001031986722557201, -0.001247857669697092, -0.001423714708648073,
+-0.001556702802350076, -0.001645167889846890, -0.001688649703502788, -0.001687846581475964, -0.001644551048567398,
+-0.001561559957317790, -0.001442563411804926, -0.001292014799874503, -0.001114986581270253, -0.000917016099829735,
+-0.000703946352348464, -0.000481764526566339, -0.000256444114966522, -0.000033793183292569, 0.000180685902835315,
+ 0.000381924396468366, 0.000565398080608305, 0.000727219011746881, 0.000864209315714227, 0.000973950761085690,
+ 0.001054815583369999, 0.001105974243787613, 0.001127383039339373, 0.001119751426837743, 0.001084492755093968,
+ 0.001023657909064450, 0.000939856052624227, 0.000836164238172957, 0.000716029226064227, 0.000583164190168290,
+ 0.000441441918072383, 0.000294790953130229, 0.000147092077716480, 0.000002082667095075, -0.000136731311264191,
+-0.000266155252511831, -0.000383371840261246, -0.000485996080304965, -0.000572115873292030, -0.000640319946685634,
+-0.000689709694056092, -0.000719899536922384, -0.000731002305621048, -0.000723604675185869, -0.000698728981427767,
+-0.000657788245032425, -0.000602532044011899, -0.000534985542936898, -0.000457387566635848, -0.000372121907291206,
+-0.000281651282503015, -0.000188451833293202, -0.000094949813106744, -0.000003462782744354, 0.000083853091464077,
+ 0.000165048886226905, 0.000238422248479072, 0.000302547334727027, 0.000356297600912998, 0.000398857326863837,
+ 0.000429729020814434, 0.000448726371643413, 0.000455966225408344, 0.000451848709179591, 0.000437031818051652,
+ 0.000412403761615261, 0.000379047713684221, 0.000338204791740229, 0.000291234779803098, 0.000239577162514028,
+ 0.000184710477990398, 0.000128114399130489, 0.000071232572821451, 0.000015440388211825, -0.000037986085678081,
+-0.000087895370243821, -0.000133280012107173, -0.000173297342436372, -0.000207273956099563, -0.000234717772155001,
+-0.000255317038867589, -0.000268937472718753, -0.000275614059005332, -0.000275541485292432, -0.000269058714331757,
+-0.000256632149501508, -0.000238836419299503, -0.000216333899003825, -0.000189854272533545, -0.000160170174848483,
+-0.000128080670195777, -0.000094384355854646, -0.000059865389594949, -0.000025277165852799, 0.000008680571408025,
+ 0.000041365841965015, 0.000072210925236429, 0.000100726393185629, 0.000126511346757621, 0.000149250512353807,
+ 0.000168719942655099, 0.000184780318878738, 0.000197379393194548, 0.000206539880117977, 0.000212358734245594,
+ 0.000214994859281552, 0.000214655997661182, 0.000211604878787747, 0.000206128795372885, 0.000198541881389953,
+ 0.000189176709991702, 0.000178368313347299, 0.000166450784469067, 0.000153744508371709, 0.000140558396336177,
+ 0.000127174196746337, 0.000113853476544409, 0.000100818605854714, 0.000088271373315159, 0.000076360900545177,
+ 0.000065233162392019, 0.000054970017069384, 0.000045630720487935, 0.000037271082107518, 0.000029885221425020,
+ 0.000023463361155584, 0.000017966192635412, 0.000013350669444763, 0.000009551098482930, 0.000006499942123311,
+ 0.000004115682735322, 0.000002322193058869, 0.000001038946634000, 0.000000197734700398, -0.000000267011791999,
+-0.000005050567303837 };
 #endif
 
 #ifdef __cplusplus
index bcf3f981eb1c5852bd146ff81aa247a58152350b..a577fcdee85b7fbae8bb8d8efe88c0846e9c1330 100644 (file)
@@ -48,7 +48,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(pstate->ftxt, "%c\n", c);
+        //fprintf(pstate->ftxt, "%c\n", c);
     }
 }
 
@@ -99,8 +99,8 @@ int main(int argc, char *argv[]) {
     freedv = freedv_open(mode);
     assert(freedv != NULL);
 
-    if ( (argc > 4) && (strcmp(argv[4], "--testframes") == 0) ) {
-               freedv_set_test_frames(freedv, 1);
+    if ( (argc > 3) && (strcmp(argv[4], "--testframes") == 0) ) {
+      freedv_set_test_frames(freedv, 1);
     }
     freedv_set_snr_squelch_thresh(freedv, -100.0);
     freedv_set_squelch_en(freedv, 1);
@@ -136,8 +136,8 @@ int main(int argc, char *argv[]) {
         /* log some side info to the txt file */
                
         if (ftxt != NULL) {
-            fprintf(ftxt, "frame: %d  demod sync: %d  demod snr: %3.2f dB  bit errors: %d\n", frame
-                    sync, snr_est, total_bit_errors);
+            fprintf(ftxt, "frame: %d  demod sync: %d  nin:%d demod snr: %3.2f dB  bit errors: %d\n"
+                    frame, sync, nin, snr_est, total_bit_errors);
         }
 
        /* if this is in a pipeline, we probably don't want the usual