first 2 unit tests pass for fdmdv C port
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 17 Apr 2012 04:50:22 +0000 (04:50 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 17 Apr 2012 04:50:22 +0000 (04:50 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@370 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/tfdmdv.m [new file with mode: 0644]
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv.h
codec2-dev/src/fdmdv_internal.h
codec2-dev/unittest/Makefile.am
codec2-dev/unittest/Makefile.in
codec2-dev/unittest/tfdmdv.c

diff --git a/codec2-dev/octave/tfdmdv.m b/codec2-dev/octave/tfdmdv.m
new file mode 100644 (file)
index 0000000..3e7e797
--- /dev/null
@@ -0,0 +1,58 @@
+% tfdmdv.m
+%
+% Octave script that evaluates the output of tfdmdv.c Unit Test program for FDMDV modem.
+%
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+fdmdv; % load modem code
+% Generate reference vectors using Octave implementation of FDMDV modem
+
+passes = fails = 0;
+frames = 10;
+prev_tx_symbols = ones(Nc+1,1);
+tx_bits_log = [];
+tx_symbols_log = [];
+
+for f=1:frames
+
+  tx_bits = get_test_bits(Nc*Nb);
+  tx_bits_log = [tx_bits_log tx_bits];
+  tx_symbols = bits_to_qpsk(prev_tx_symbols, tx_bits, 'dqpsk');
+  prev_tx_symbols = tx_symbols;
+  tx_symbols_log = [tx_symbols_log tx_symbols];
+
+end
+
+% Compare to the output from the C version
+
+load ../unittest/tfdmdv_out.txt
+
+figure(1)
+subplot(211)
+plot(tx_bits_log - tx_bits_tfdmdv);
+title('tx bits')
+subplot(212)
+plot(tx_symbols_log - tx_symbols_tfdmdv);
+title('tx symbols')
+
+if sum(tx_bits_log - tx_bits_tfdmdv) == 0
+  printf("fdmdv_get_test_bits..: OK\n");
+  passes++;
+else;
+  printf("fdmdv_get_test_bits..: FAIL\n");
+  fails++;
+end
+if sum(tx_symbols_log - tx_symbols_tfdmdv) == 0
+  printf("bits_to_dqpsk_symbols: OK\n");
+  passes++;
+else;
+  printf("bits_to_dqpsk_symbols: FAIL\n");
+  fails++;
+end
+
+printf("\npasses: %d fails: %d\n", passes, fails);
index 7ece1ffd79714e56118cac4996e03bb4df338772..a4d7a2ee37df37aa2b9028954d991c375667d7d6 100644 (file)
   along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
-/*---------------------------------------------------------------------------*\
-                                                                             
-                               DEFINES
-
-\*---------------------------------------------------------------------------*/
-
-#define FS                    8000  /* sample rate in Hz                                                    */
-#define T                   (1/Fs)  /* sample period in seconds                                             */
-#define RS                      50  /* symbol rate in Hz                                                    */
-#define NC                      14  /* number of carriers                                                   */
-#define NB                       2  /* Bits/symbol for QPSK modulation                                      */
-#define RB              (Nc*Rs*Nb)  /* bit rate                                                             */
-#define M                    Fs/Rs  /* oversampling factor                                                  */
-#define NSYM                     4  /* number of symbols to filter over                                     */
-#define FSEP                    75  /* Separation between carriers (Hz)                                     */
-#define FCENTRE               1200  /* Centre frequency, Nc/2 carriers below this, Nc/2 carriers above (Hz) */
-#define NT                       5  /* number of symbols we estimate timing over                            */
-#define P                        4  /* oversample factor used for initial rx symbol filtering               */
-#define NFILTER            (NSYM*M) /* size of tx/rx filters at sampel rate M                               */
-#define NFILTERTIMING (M+Nfilter+M) /* filter memory used for resampling after timing estimation            */
-
-#define NTEST_BITS        (Nc*Nb*4) /* length of test bit sequence */
-
-/*---------------------------------------------------------------------------*\
-                                                                             
-                               STRUCT for States
-
-\*---------------------------------------------------------------------------*/
-
-struct FDMDV {
-    int current_test_bit;
-};
-
 /*---------------------------------------------------------------------------*\
                                                                              
                                INCLUDES
 
 \*---------------------------------------------------------------------------*/
 
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "fdmdv_internal.h"
 #include "fdmdv.h"
 #include "rn.h"
-#include "testbits.h"
+#include "test_bits.h"
 
 /*---------------------------------------------------------------------------*\
                                                                              
@@ -111,7 +84,7 @@ static COMP cdot(COMP a[], COMP b[], int n)
     int  i;
     
     for(i=0; i<n; i++) 
-       res = cadd(res, cmult(a,b));
+       res = cadd(res, cmult(a[i], b[i]));
 
     return res;
 }
@@ -140,13 +113,23 @@ static void cbuf_shift_update(COMP buf[], COMP update[], int buflen, int updatel
 
 struct FDMDV *fdmdv_create(void)
 {
-    struct FDMDV *fdmdv;
+    struct FDMDV *f;
+    int           c;
+
+    assert(FDMDV_BITS_PER_FRAME == NC*NB);
+    assert(FDMDV_SAMPLES_PER_FRAME == M);
 
-    fdmdv = (struct FDMDV*)malloc(sizeof(struct FDMDV));
-    if (fdmdv == NULL)
+    f = (struct FDMDV*)malloc(sizeof(struct FDMDV));
+    if (f == NULL)
        return NULL;
     
-    return fdmdv;
+    f->current_test_bit = 0;
+    f->tx_pilot_bit = 0;
+    for(c=0; c<NC+1; c++) {
+       f->prev_tx_symbols[c].real = 1.0;
+       f->prev_tx_symbols[c].imag = 0.0;
+    }
+    return f;
 }
 
 /*---------------------------------------------------------------------------*\
@@ -165,6 +148,30 @@ void codec2_destroy(struct FDMDV *fdmdv)
     free(fdmdv);
 }
 
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: fdmdv_get_test_bits()       
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 16/4/2012
+
+  Generate a frame of bits from a repeating sequence of random data.  OK so
+  it's not very random if it repeats but it makes syncing at the demod easier
+  for test purposes.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[])
+{
+    int i;
+
+    for(i=0; i<FDMDV_BITS_PER_FRAME; i++) {
+       tx_bits[i] = test_bits[f->current_test_bit];
+       f->current_test_bit++;
+       if (f->current_test_bit > (NTEST_BITS-1))
+           f->current_test_bit = 0;
+    }
+ }
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: bits_to_dqpsk_symbols()             
@@ -180,7 +187,6 @@ void bits_to_dqpsk_symbols(COMP tx_symbols[], COMP prev_tx_symbols[], int tx_bit
 {
     int c, msb, lsb;
     COMP j = {0.0,1.0};
-    COMP minusj = {0.0,-1.0};
 
     /* map tx_bits to to Nc DQPSK symbols */
 
@@ -201,9 +207,9 @@ void bits_to_dqpsk_symbols(COMP tx_symbols[], COMP prev_tx_symbols[], int tx_bit
        two spectral lines at +/- Rs/2 */
  
     if (*pilot_bit)
-       tx_symbols[Nc] = cneg(prev_tx_symbols[Nc]);
+       tx_symbols[NC] = cneg(prev_tx_symbols[NC]);
     else
-       tx_symbols[Nc] = prev_tx_symbols[Nc];
+       tx_symbols[NC] = prev_tx_symbols[NC];
 
     if (*pilot_bit) 
        *pilot_bit = 0;
index 671636ffef0cf13a8b2b9f1307dde17abf41dd0f..647b87bf5bed30cb9895c1cc8293f7275cc9b9fa 100644 (file)
 extern "C" {
 #endif
 
+#define FDMDV_BITS_PER_FRAME     28
+#define FDMDV_SAMPLES_PER_FRAME 160
+
 struct FDMDV;
     
+struct FDMDV_STATS {
+    float  snr;          /* estimated SNR of rx signal  in dB                  */
+    COMP  *rx_symbols;   /* NC+1 latest received symbols, for scatter plot     */ 
+    int    fest_track;   /* == 0, freq est in acquire mode, == 1 in track mode */ 
+    float  foff;         /* estimated freq offset in Hz                        */       
+    float  timing;       /* timing offset 0..1 as fraction of symbol period    */
+    float  clock_offset; /* Estimated tx/rx sample clock offset in ppm         */
+};
+
+
 struct FDMDV *fdmdv_create(void);
 void          fdmdv_destroy(struct FDMDV *fdmdv_state);
     
-void          fdmdv_mod(struct FDMDV *fdmdv_state, int tx_bits[], COMP tx_fdm[]);
-void          fdmdv_demod(struct FDMDV *fdmdv_state, int tx_bits[], float rx_fdm[], int *nin);
+void          fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[]);
+void          fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *sync, float rx_fdm[], int *nin);
     
 void          fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
 void          fdmdv_put_test_bits(struct FDMDV *fdmdv_state, int rx_bits[]);
     
-float         fdmdv_get_snr(struct FDMDV *fdmdv_state);
+float         fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct FDMDV_STATS *fdmdv_stats);
 void          fdmdv_get_waterfall_line(struct FDMDV *fdmdv_state, float magnitudes[], int *magnitude_points);
 
 #endif
index f70d683a4f253a74e98596d68a9c22ec7ef99769..a995a42a0d0453a540d03f5e5d58a068bd3ee804 100644 (file)
 
 #include "comp.h"
 
+/*---------------------------------------------------------------------------*\
+                                                                             
+                               DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+#define FS                    8000  /* sample rate in Hz                                                    */
+#define T                 (1.0/FS)  /* sample period in seconds                                             */
+#define RS                      50  /* symbol rate in Hz                                                    */
+#define NC                      14  /* number of carriers                                                   */
+#define NB                       2  /* Bits/symbol for QPSK modulation                                      */
+#define RB              (NC*RS*NB)  /* bit rate                                                             */
+#define M                  (FS/RS)  /* oversampling factor                                                  */
+#define NSYM                     4  /* number of symbols to filter over                                     */
+#define FSEP                    75  /* Separation between carriers (Hz)                                     */
+#define FCENTRE               1200  /* Centre frequency, Nc/2 carriers below this, Nc/2 carriers above (Hz) */
+#define NT                       5  /* number of symbols we estimate timing over                            */
+#define P                        4  /* oversample factor used for initial rx symbol filtering               */
+#define NFILTER            (NSYM*M) /* size of tx/rx filters at sampel rate M                               */
+#define NFILTERTIMING (M+Nfilter+M) /* filter memory used for resampling after timing estimation            */
+
+#define NTEST_BITS        (NC*NB*4) /* length of test bit sequence */
+
+/*---------------------------------------------------------------------------*\
+                                                                             
+                               STRUCT for States
+
+\*---------------------------------------------------------------------------*/
+
+struct FDMDV {
+    int  current_test_bit;
+    int  tx_pilot_bit;
+    COMP prev_tx_symbols[NC+1];
+};
+
+/*---------------------------------------------------------------------------*\
+                                                                             
+                              FUNCTION PROTOTYPES
+
+\*---------------------------------------------------------------------------*/
+
 void bits_to_dqpsk_symbols(COMP tx_symbols[], COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit);
 
 #endif
index 41b12834eee2c65d2c29f5d7bf5bff6017f4e2c9..60a4aa5a16cd5240a91aacc80002b469b85dee2c 100644 (file)
@@ -3,7 +3,7 @@ AUTOMAKE_OPTS = gnu
 NAME = libcodec2
 AM_CPPFLAGS = $(AM_CFLAGS)
 
-noinst_PROGRAMS = genres genlsp extract vqtrain vqtrainjnd tnlp tinterp tquant tcodec2 vq_train_jvm scalarlsptest
+noinst_PROGRAMS = genres genlsp extract vqtrain vqtrainjnd tnlp tinterp tquant tcodec2 vq_train_jvm scalarlsptest tfdmdv
 
 genres_SOURCES = genres.c ../src/lpc.c
 genres_LDADD = $(lib_LTLIBRARIES) 
@@ -52,3 +52,7 @@ scalarlsptest_SOURCES = scalarlsptest.c ../src/quantise.c ../src/lpc.c ../src/ls
 scalarlsptest_LDADD = $(lib_LTLIBRARIES) 
 scalarlsptest_LDFLAGS = $(LIBS)
 
+tfdmdv_SOURCES = tfdmdv.c ../src/fdmdv.c
+tfdmdv_LDADD = $(lib_LTLIBRARIES) 
+tfdmdv_LDFLAGS = $(LIBS)
+
index 94f4a037b26164f2a288143c1b935a297360e7ff..801a6e3f901a5a9f0caa9b29ec636a67d8084a85 100644 (file)
@@ -39,7 +39,7 @@ host_triplet = @host@
 noinst_PROGRAMS = genres$(EXEEXT) genlsp$(EXEEXT) extract$(EXEEXT) \
        vqtrain$(EXEEXT) vqtrainjnd$(EXEEXT) tnlp$(EXEEXT) \
        tinterp$(EXEEXT) tquant$(EXEEXT) tcodec2$(EXEEXT) \
-       vq_train_jvm$(EXEEXT) scalarlsptest$(EXEEXT)
+       vq_train_jvm$(EXEEXT) scalarlsptest$(EXEEXT) tfdmdv$(EXEEXT)
 subdir = unittest
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -74,6 +74,9 @@ am_tcodec2_OBJECTS = tcodec2.$(OBJEXT) quantise.$(OBJEXT) \
        interp.$(OBJEXT) pack.$(OBJEXT) $(am__objects_1)
 tcodec2_OBJECTS = $(am_tcodec2_OBJECTS)
 tcodec2_DEPENDENCIES =
+am_tfdmdv_OBJECTS = tfdmdv.$(OBJEXT) fdmdv.$(OBJEXT)
+tfdmdv_OBJECTS = $(am_tfdmdv_OBJECTS)
+tfdmdv_DEPENDENCIES =
 am_tinterp_OBJECTS = tinterp.$(OBJEXT) sine.$(OBJEXT) fft.$(OBJEXT) \
        kiss_fft.$(OBJEXT) interp.$(OBJEXT) lpc.$(OBJEXT) \
        lsp.$(OBJEXT) quantise.$(OBJEXT) $(am__objects_1) \
@@ -110,13 +113,15 @@ CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
 SOURCES = $(extract_SOURCES) $(genlsp_SOURCES) $(genres_SOURCES) \
-       $(scalarlsptest_SOURCES) $(tcodec2_SOURCES) $(tinterp_SOURCES) \
-       $(tnlp_SOURCES) $(tquant_SOURCES) $(vq_train_jvm_SOURCES) \
-       $(vqtrain_SOURCES) $(vqtrainjnd_SOURCES)
+       $(scalarlsptest_SOURCES) $(tcodec2_SOURCES) $(tfdmdv_SOURCES) \
+       $(tinterp_SOURCES) $(tnlp_SOURCES) $(tquant_SOURCES) \
+       $(vq_train_jvm_SOURCES) $(vqtrain_SOURCES) \
+       $(vqtrainjnd_SOURCES)
 DIST_SOURCES = $(extract_SOURCES) $(genlsp_SOURCES) $(genres_SOURCES) \
-       $(scalarlsptest_SOURCES) $(tcodec2_SOURCES) $(tinterp_SOURCES) \
-       $(tnlp_SOURCES) $(tquant_SOURCES) $(vq_train_jvm_SOURCES) \
-       $(vqtrain_SOURCES) $(vqtrainjnd_SOURCES)
+       $(scalarlsptest_SOURCES) $(tcodec2_SOURCES) $(tfdmdv_SOURCES) \
+       $(tinterp_SOURCES) $(tnlp_SOURCES) $(tquant_SOURCES) \
+       $(vq_train_jvm_SOURCES) $(vqtrain_SOURCES) \
+       $(vqtrainjnd_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -264,6 +269,9 @@ tcodec2_LDFLAGS = $(LIBS)
 scalarlsptest_SOURCES = scalarlsptest.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/fft.c ../src/kiss_fft.c $(CODEBOOKS)
 scalarlsptest_LDADD = $(lib_LTLIBRARIES) 
 scalarlsptest_LDFLAGS = $(LIBS)
+tfdmdv_SOURCES = tfdmdv.c ../src/fdmdv.c
+tfdmdv_LDADD = $(lib_LTLIBRARIES) 
+tfdmdv_LDFLAGS = $(LIBS)
 all: all-am
 
 .SUFFIXES:
@@ -319,6 +327,9 @@ scalarlsptest$(EXEEXT): $(scalarlsptest_OBJECTS) $(scalarlsptest_DEPENDENCIES)
 tcodec2$(EXEEXT): $(tcodec2_OBJECTS) $(tcodec2_DEPENDENCIES) 
        @rm -f tcodec2$(EXEEXT)
        $(LINK) $(tcodec2_LDFLAGS) $(tcodec2_OBJECTS) $(tcodec2_LDADD) $(LIBS)
+tfdmdv$(EXEEXT): $(tfdmdv_OBJECTS) $(tfdmdv_DEPENDENCIES) 
+       @rm -f tfdmdv$(EXEEXT)
+       $(LINK) $(tfdmdv_LDFLAGS) $(tfdmdv_OBJECTS) $(tfdmdv_LDADD) $(LIBS)
 tinterp$(EXEEXT): $(tinterp_OBJECTS) $(tinterp_DEPENDENCIES) 
        @rm -f tinterp$(EXEEXT)
        $(LINK) $(tinterp_LDFLAGS) $(tinterp_OBJECTS) $(tinterp_LDADD) $(LIBS)
@@ -354,6 +365,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codec2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmdv.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fft.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genlsp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genres.Po@am__quote@
@@ -369,6 +381,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scalarlsptest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sine.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcodec2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfdmdv.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinterp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnlp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tquant.Po@am__quote@
@@ -677,6 +690,20 @@ pack.obj: ../src/pack.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pack.obj `if test -f '../src/pack.c'; then $(CYGPATH_W) '../src/pack.c'; else $(CYGPATH_W) '$(srcdir)/../src/pack.c'; fi`
 
+fdmdv.o: ../src/fdmdv.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fdmdv.o -MD -MP -MF "$(DEPDIR)/fdmdv.Tpo" -c -o fdmdv.o `test -f '../src/fdmdv.c' || echo '$(srcdir)/'`../src/fdmdv.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/fdmdv.Tpo" "$(DEPDIR)/fdmdv.Po"; else rm -f "$(DEPDIR)/fdmdv.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/fdmdv.c' object='fdmdv.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fdmdv.o `test -f '../src/fdmdv.c' || echo '$(srcdir)/'`../src/fdmdv.c
+
+fdmdv.obj: ../src/fdmdv.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fdmdv.obj -MD -MP -MF "$(DEPDIR)/fdmdv.Tpo" -c -o fdmdv.obj `if test -f '../src/fdmdv.c'; then $(CYGPATH_W) '../src/fdmdv.c'; else $(CYGPATH_W) '$(srcdir)/../src/fdmdv.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/fdmdv.Tpo" "$(DEPDIR)/fdmdv.Po"; else rm -f "$(DEPDIR)/fdmdv.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/fdmdv.c' object='fdmdv.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fdmdv.obj `if test -f '../src/fdmdv.c'; then $(CYGPATH_W) '../src/fdmdv.c'; else $(CYGPATH_W) '$(srcdir)/../src/fdmdv.c'; fi`
+
 mostlyclean-libtool:
        -rm -f *.lo
 
index 374f5d177bc37edd46e394ea4ad38b2f00727382..06b2c05bcc8905acd84ffabe70a0b7341a7a58be 100644 (file)
   along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
+#include "fdmdv_internal.h"
 #include "fdmdv.h"
 
+#define FRAMES 10
+
+void octave_save_int(FILE *f, char name[], int data[], int len);
+void octave_save_complex(FILE *f, char name[], COMP data[], int len);
+
 int main(int argc, char *argv[])
 {
-    
-    /* save to text file for comparison to Octave version */
+    struct FDMDV *fdmdv;
+    int           tx_bits[FDMDV_BITS_PER_FRAME*FRAMES];
+    COMP          tx_symbols[(NC+1)*FRAMES];
+    FILE         *fout;
+    int           f,i;
+
+    fdmdv = fdmdv_create();
+
+    for(f=0; f<FRAMES; f++) {
+       fdmdv_get_test_bits(fdmdv, &tx_bits[FDMDV_BITS_PER_FRAME*f]);
+       bits_to_dqpsk_symbols(&tx_symbols[(NC+1)*f], fdmdv->prev_tx_symbols, 
+                             &tx_bits[FDMDV_BITS_PER_FRAME*f], &fdmdv->tx_pilot_bit);
+       memcpy(fdmdv->prev_tx_symbols, &tx_symbols[(NC+1)*f], (NC+1)*sizeof(COMP));
+    }
+    codec2_destroy(fdmdv);
+
+    /* dump to Octave file for evaluation by Octave script */
+
+    fout = fopen("tfdmdv_out.txt","wt");
+    assert(fout != NULL);
+    fprintf(fout, "# Created by tfdmdv.c\n");
+    octave_save_int(fout, "tx_bits_tfdmdv", tx_bits, FDMDV_BITS_PER_FRAME*FRAMES);
+    octave_save_complex(fout, "tx_symbols_tfdmdv", tx_symbols, (NC+1)*FRAMES);  
+    fclose(fout);
 
     return 0;
 }
+
+void octave_save_int(FILE *f, char name[], int data[], int len)
+{
+    int i;
+
+    fprintf(f, "# name: %s\n", name);
+    fprintf(f, "# type: matrix\n");
+    fprintf(f, "# rows: %d\n", 1);
+    fprintf(f, "# columns: %d\n", len);
+    
+    for(i=0; i<len; i++)
+       fprintf(f, " %d", data[i]);
+
+    fprintf(f, "\n\n\n");
+}
+
+void octave_save_complex(FILE *f, char name[], COMP data[], int len)
+{
+    int i;
+
+    fprintf(f, "# name: %s\n", name);
+    fprintf(f, "# type: complex matrix\n");
+    fprintf(f, "# rows: %d\n", 1);
+    fprintf(f, "# columns: %d\n", len);
+    
+    for(i=0; i<len; i++)
+       fprintf(f, " (%f,%f)", data[i].real, data[i].imag);
+
+    fprintf(f, "\n\n\n");
+}