fdmdv_mod coded but not tested
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 28 Apr 2012 01:09:09 +0000 (01:09 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 28 Apr 2012 01:09:09 +0000 (01:09 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@385 01035d8c-6547-0410-b346-abe4f91aad63

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

index 41881b222720755d6a29d382304ce3552619bdf5..5bf5d9d279283da7c179882c65a04de010e675e6 100644 (file)
@@ -122,7 +122,7 @@ libcodec2_la_LDFLAGS = $(LIBS)
 library_includedir = $(prefix)/include
 library_include_HEADERS        = codec2.h
 
-bin_PROGRAMS = c2demo c2enc c2dec c2sim
+bin_PROGRAMS = c2demo c2enc c2dec c2sim fdmdv_mod
 
 c2demo_SOURCES = c2demo.c
 c2demo_LDADD = $(lib_LTLIBRARIES) 
@@ -139,3 +139,6 @@ c2dec_LDFLAGS = $(LIBS)
 c2sim_SOURCES = c2sim.c
 c2sim_LDADD = $(lib_LTLIBRARIES) 
 c2sim_LDFLAGS = $(LIBS)
+
+fdmdv_mod_SOURCES = fdmdv_mod.c fdmdv.c fft.c kiss_fft.c octave.c
+fdmdv_mod_LDFLAGS = $(LIBS)
index 6d44219d7c4f48d206942468e72842d380ba6d47..a37bb30d406bbcc91c0927a68f21038e6f386a83 100644 (file)
@@ -40,7 +40,7 @@ build_triplet = @build@
 host_triplet = @host@
 noinst_PROGRAMS = generate_codebook$(EXEEXT) genlspdtcb$(EXEEXT)
 bin_PROGRAMS = c2demo$(EXEEXT) c2enc$(EXEEXT) c2dec$(EXEEXT) \
-       c2sim$(EXEEXT)
+       c2sim$(EXEEXT) fdmdv_mod$(EXEEXT)
 subdir = src
 DIST_COMMON = $(library_include_HEADERS) $(srcdir)/Makefile.am \
        $(srcdir)/Makefile.in
@@ -87,6 +87,10 @@ c2enc_DEPENDENCIES = $(am__DEPENDENCIES_1)
 am_c2sim_OBJECTS = c2sim.$(OBJEXT)
 c2sim_OBJECTS = $(am_c2sim_OBJECTS)
 c2sim_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_fdmdv_mod_OBJECTS = fdmdv_mod.$(OBJEXT) fdmdv.$(OBJEXT) \
+       fft.$(OBJEXT) kiss_fft.$(OBJEXT) octave.$(OBJEXT)
+fdmdv_mod_OBJECTS = $(am_fdmdv_mod_OBJECTS)
+fdmdv_mod_LDADD = $(LDADD)
 generate_codebook_SOURCES = generate_codebook.c
 generate_codebook_OBJECTS = generate_codebook.$(OBJEXT)
 generate_codebook_LDADD = $(LDADD)
@@ -105,11 +109,11 @@ CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
 SOURCES = $(libcodec2_la_SOURCES) $(c2dec_SOURCES) $(c2demo_SOURCES) \
-       $(c2enc_SOURCES) $(c2sim_SOURCES) generate_codebook.c \
-       genlspdtcb.c
+       $(c2enc_SOURCES) $(c2sim_SOURCES) $(fdmdv_mod_SOURCES) \
+       generate_codebook.c genlspdtcb.c
 DIST_SOURCES = $(libcodec2_la_SOURCES) $(c2dec_SOURCES) \
        $(c2demo_SOURCES) $(c2enc_SOURCES) $(c2sim_SOURCES) \
-       generate_codebook.c genlspdtcb.c
+       $(fdmdv_mod_SOURCES) generate_codebook.c genlspdtcb.c
 library_includeHEADERS_INSTALL = $(INSTALL_HEADER)
 HEADERS = $(library_include_HEADERS)
 ETAGS = etags
@@ -312,6 +316,8 @@ c2dec_LDFLAGS = $(LIBS)
 c2sim_SOURCES = c2sim.c
 c2sim_LDADD = $(lib_LTLIBRARIES) 
 c2sim_LDFLAGS = $(LIBS)
+fdmdv_mod_SOURCES = fdmdv_mod.c fdmdv.c fft.c kiss_fft.c octave.c
+fdmdv_mod_LDFLAGS = $(LIBS)
 all: all-am
 
 .SUFFIXES:
@@ -421,6 +427,9 @@ c2enc$(EXEEXT): $(c2enc_OBJECTS) $(c2enc_DEPENDENCIES)
 c2sim$(EXEEXT): $(c2sim_OBJECTS) $(c2sim_DEPENDENCIES) 
        @rm -f c2sim$(EXEEXT)
        $(LINK) $(c2sim_LDFLAGS) $(c2sim_OBJECTS) $(c2sim_LDADD) $(LIBS)
+fdmdv_mod$(EXEEXT): $(fdmdv_mod_OBJECTS) $(fdmdv_mod_DEPENDENCIES) 
+       @rm -f fdmdv_mod$(EXEEXT)
+       $(LINK) $(fdmdv_mod_LDFLAGS) $(fdmdv_mod_OBJECTS) $(fdmdv_mod_LDADD) $(LIBS)
 generate_codebook$(EXEEXT): $(generate_codebook_OBJECTS) $(generate_codebook_DEPENDENCIES) 
        @rm -f generate_codebook$(EXEEXT)
        $(LINK) $(generate_codebook_LDFLAGS) $(generate_codebook_OBJECTS) $(generate_codebook_LDADD) $(LIBS)
@@ -438,8 +447,12 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c2demo.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c2enc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c2sim.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmdv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmdv_mod.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fft.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generate_codebook.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genlspdtcb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kiss_fft.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcodec2_la-codebook.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcodec2_la-codebookd.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcodec2_la-codebookdt.Plo@am__quote@
@@ -460,6 +473,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcodec2_la-postfilter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcodec2_la-quantise.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcodec2_la-sine.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/octave.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
index 0b5ac148d148592dc237ec026ae11490a6d00927..5cc256f5042709162363b36d6207bc80e0ee4a3a 100644 (file)
@@ -4,8 +4,7 @@
   AUTHOR......: David Rowe
   DATE CREATED: April 14 2012
                                                                              
-  Functions that implement a Frequency Divison Multiplexed Modem for
-  Digital Voice (FDMDV) over HF channels.
+  Functions that implement the FDMDV modem.
                                                                              
 \*---------------------------------------------------------------------------*/
 
@@ -102,27 +101,6 @@ static COMP cadd(COMP a, COMP b)
     return res;
 }
 
-static COMP cdot(COMP a[], COMP b[], int n)
-{
-    COMP res;
-    int  i;
-    
-    for(i=0; i<n; i++) 
-       res = cadd(res, cmult(a[i], b[i]));
-
-    return res;
-}
-
-static void cbuf_shift_update(COMP buf[], COMP update[], int buflen, int updatelen)
-{
-    int  i,j;
-    
-    for(i=0; i<buflen-updatelen; i++) 
-       buf[i] = buf[updatelen+i];
-    for(j=0; j<updatelen; j++) 
-       buf[i] = update[j];
-}
-
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: fdmdv_create        
@@ -717,7 +695,6 @@ void freq_shift(COMP rx_fdm_fcorr[], float rx_fdm[], float foff, COMP *foff_rect
 void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin)
 {
     int  i,c;
-    COMP pilot;
 
     /* maximum number of input samples to demod */
 
@@ -920,7 +897,7 @@ float qpsk_to_bits(int rx_bits[], int *sync_bit, COMP prev_rx_symbols[], COMP rx
     COMP  phase_difference[NC+1];
     COMP  pi_on_4;
     COMP  d;
-    int   msb, lsb;
+    int   msb=0, lsb=0;
     float ferr;
 
     pi_on_4.real = cos(PI/4.0);
@@ -1115,8 +1092,7 @@ void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], int *sync_bit, float rx_fdm
     float         rx_timing;
     float         env[NT*P];
     COMP          rx_symbols[NC+1];
-    float         ferr;
-
     /* freq offset estimation and correction */
 
     foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, *nin);
index 75700629ba3d55d83e9ee67a3ffa606584eb32d4..ecb02594bfeb11126b290a7869a49c509927e67c 100644 (file)
@@ -4,9 +4,15 @@
   AUTHOR......: David Rowe                                                          
   DATE CREATED: April 14 2012
                                                                              
-  Header file for a Frequency Divison Multiplexed Modem for Digital
-  Voice (FDMDV) over HF channels.
-                                                                             
+  A 1400 bit/s Frequency Divison Multiplexed Digital Voice (FDMDV)
+  modem.  Used for digital audio over HF SSB. The input and output
+  sample rate is 8000 Hz. See tfdmdv_mod.c and tfdmdv_demod.c for
+  example usage.
+                     
+  References:
+  [1] http://n1su.com/fdmdv/FDMDV_Docs_Rel_1_4b.pdf
+
 \*---------------------------------------------------------------------------*/
 
 /*
@@ -35,8 +41,9 @@ extern "C" {
 
 #include "comp.h"
 
-#define FDMDV_BITS_PER_FRAME     28
-#define FDMDV_SAMPLES_PER_FRAME 160
+#define FDMDV_BITS_PER_FRAME      28  /* odd/even frames 56 bits, 1400 bit/s  */
+#define FDMDV_SAMPLES_PER_FRAME  160  /* 8000 Hz sample rate                  */
+#define FDMDV_SCALE             1000  /* suggested scaling for 16 bit shorts  */
 
 struct FDMDV;
     
diff --git a/codec2-dev/src/fdmdv_mod.c b/codec2-dev/src/fdmdv_mod.c
new file mode 100644 (file)
index 0000000..9137eb7
--- /dev/null
@@ -0,0 +1,123 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: tfdmdv_mod.c
+  AUTHOR......: David Rowe  
+  DATE CREATED: April 28 2012
+                                                                             
+  Given an input file of bits outputs a raw file (8kHz, 16 bit shorts)
+  of FDMDV modem samples ready to send over a HF radio channel.  The
+  input file is assumed to be arranged as codec frames of 56 bits (7
+  bytes) which we send as two 28 bit modem frames.
+                                                                             
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  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 <math.h>
+#include <errno.h>
+
+#include "fdmdv.h"
+#include "octave.h"
+
+#define BITS_PER_CODEC_FRAME (2*FDMDV_BITS_PER_FRAME)
+#define BYTES_PER_CODEC_FRAME (BITS_PER_CODEC_FRAME/8)
+
+int main(int argc, char *argv[])
+{
+    FILE         *fin, *fout;
+    struct FDMDV *fdmdv;
+    char          packed_bits[BYTES_PER_CODEC_FRAME];
+    int           tx_bits[2*FDMDV_BITS_PER_FRAME];
+    COMP          tx_fdm[2*FDMDV_SAMPLES_PER_FRAME];
+    short         tx_fdm_scaled[FDMDV_SAMPLES_PER_FRAME];
+    int           frames;
+    int           i, bit, byte;
+    int           sync_bit;
+
+    if (argc < 3) {
+       printf("usage: %s InputBitFile OutputModemRawFile\n", argv[0]);
+       printf("e.g    %s hts1a.c2 hts1a_fdmdv.raw\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input bit file: %s: %s.\n",
+         argv[1], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output modem sample file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    fdmdv = fdmdv_create();
+    frames = 0;
+
+    while(fread(packed_bits, sizeof(char), BYTES_PER_CODEC_FRAME, fin) == BYTES_PER_CODEC_FRAME) {
+       frames++;
+       
+       /* unpack bits, MSB first */
+
+       bit = 7; byte = 0;
+       for(i=0; i<BITS_PER_CODEC_FRAME; i++) {
+           tx_bits[i] = (packed_bits[byte] >> bit) & 0x1;
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+       assert(byte == BYTES_PER_CODEC_FRAME);
+
+       /* modulate even and odd frames */
+
+       fdmdv_mod(fdmdv, tx_fdm, tx_bits, &sync_bit);
+       assert(sync_bit == 0);
+
+       fdmdv_mod(fdmdv, &tx_fdm[FDMDV_SAMPLES_PER_FRAME], &tx_bits[FDMDV_BITS_PER_FRAME], &sync_bit);
+       assert(sync_bit == 1);
+
+       /* scale and save to disk as shorts */
+
+       for(i=0; i<2*FDMDV_SAMPLES_PER_FRAME; i++)
+           tx_fdm_scaled[i] = FDMDV_SCALE * tx_fdm[i].real;
+
+       fwrite(tx_fdm_scaled, sizeof(short), 2*FDMDV_SAMPLES_PER_FRAME, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);         
+    }
+
+    fclose(fin);
+    fclose(fout);
+    codec2_destroy(fdmdv);
+
+    return 0;
+}
diff --git a/codec2-dev/src/octave.c b/codec2-dev/src/octave.c
new file mode 100644 (file)
index 0000000..cf4cc20
--- /dev/null
@@ -0,0 +1,85 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: octave.c
+  AUTHOR......: David Rowe  
+  DATE CREATED: April 28 2012
+                                                                             
+  Functions to save C arrays in Octave matrix format.  the output text
+  file can be directly read into octave using "load filename".
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include "octave.h"
+
+void octave_save_int(FILE *f, char name[], int data[], int rows, int cols)
+{
+    int r,c;
+
+    fprintf(f, "# name: %s\n", name);
+    fprintf(f, "# type: matrix\n");
+    fprintf(f, "# rows: %d\n", rows);
+    fprintf(f, "# columns: %d\n", cols);
+    
+    for(r=0; r<rows; r++) {
+       for(c=0; c<cols; c++)
+           fprintf(f, " %d", data[r*cols+c]);
+       fprintf(f, "\n");
+    }
+
+    fprintf(f, "\n\n");
+}
+
+void octave_save_float(FILE *f, char name[], float data[], int rows, int cols)
+{
+    int r,c;
+
+    fprintf(f, "# name: %s\n", name);
+    fprintf(f, "# type: matrix\n");
+    fprintf(f, "# rows: %d\n", rows);
+    fprintf(f, "# columns: %d\n", cols);
+    
+    for(r=0; r<rows; r++) {
+       for(c=0; c<cols; c++)
+           fprintf(f, " %f", data[r*cols+c]);
+       fprintf(f, "\n");
+    }
+
+    fprintf(f, "\n\n");
+}
+
+void octave_save_complex(FILE *f, char name[], COMP data[], int rows, int cols, int col_len)
+{
+    int r,c;
+
+    fprintf(f, "# name: %s\n", name);
+    fprintf(f, "# type: complex matrix\n");
+    fprintf(f, "# rows: %d\n", rows);
+    fprintf(f, "# columns: %d\n", cols);
+    
+    for(r=0; r<rows; r++) {
+       for(c=0; c<cols; c++)
+           fprintf(f, " (%f,%f)", data[r*col_len+c].real, data[r*col_len+c].imag);
+       fprintf(f, "\n");
+    }
+
+    fprintf(f, "\n\n");
+}
diff --git a/codec2-dev/src/octave.h b/codec2-dev/src/octave.h
new file mode 100644 (file)
index 0000000..d8b8586
--- /dev/null
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: octave.h
+  AUTHOR......: David Rowe  
+  DATE CREATED: April 28 2012
+                                                                             
+  Functions to save C arrays in Octave matrix format.  the output text
+  file can be directly read into octave using "load filename".
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __OCTAVE__
+#define __OCTAVE__
+
+#include "comp.h"
+
+void octave_save_int(FILE *f, char name[], int data[], int rows, int cols);
+void octave_save_float(FILE *f, char name[], float data[], int rows, int cols);
+void octave_save_complex(FILE *f, char name[], COMP data[], int rows, int cols, int col_len);
+
+#endif
index d5b1d934fe4f9739314926a353ffeb8155759b40..96b930e9be0dc5d3014f587278a90d7a90e2f9df 100644 (file)
@@ -52,7 +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 ../src/fft.c ../src/kiss_fft.c
+tfdmdv_SOURCES = tfdmdv.c ../src/fdmdv.c ../src/fft.c ../src/kiss_fft.c ../src/octave.c
 tfdmdv_LDADD = $(lib_LTLIBRARIES) 
 tfdmdv_LDFLAGS = $(LIBS)
 
index 84b1c844d673d8b5d5cd4b387b4ddd4ef326cc08..e502088e45ecf8dee0479b514ffd0fd98e8ecf38 100644 (file)
 
 #include "fdmdv_internal.h"
 #include "fdmdv.h"
+#include "octave.h"
 
 #define FRAMES 25
 
-void octave_save_int(FILE *f, char name[], int data[], int rows, int cols);
-void octave_save_float(FILE *f, char name[], float data[], int rows, int cols);
-void octave_save_complex(FILE *f, char name[], COMP data[], int rows, int cols, int col_len);
-
 int main(int argc, char *argv[])
 {
     struct FDMDV *fdmdv;
@@ -226,55 +223,3 @@ int main(int argc, char *argv[])
     return 0;
 }
 
-void octave_save_int(FILE *f, char name[], int data[], int rows, int cols)
-{
-    int r,c;
-
-    fprintf(f, "# name: %s\n", name);
-    fprintf(f, "# type: matrix\n");
-    fprintf(f, "# rows: %d\n", rows);
-    fprintf(f, "# columns: %d\n", cols);
-    
-    for(r=0; r<rows; r++) {
-       for(c=0; c<cols; c++)
-           fprintf(f, " %d", data[r*cols+c]);
-       fprintf(f, "\n");
-    }
-
-    fprintf(f, "\n\n");
-}
-
-void octave_save_float(FILE *f, char name[], float data[], int rows, int cols)
-{
-    int r,c;
-
-    fprintf(f, "# name: %s\n", name);
-    fprintf(f, "# type: matrix\n");
-    fprintf(f, "# rows: %d\n", rows);
-    fprintf(f, "# columns: %d\n", cols);
-    
-    for(r=0; r<rows; r++) {
-       for(c=0; c<cols; c++)
-           fprintf(f, " %f", data[r*cols+c]);
-       fprintf(f, "\n");
-    }
-
-    fprintf(f, "\n\n");
-}
-void octave_save_complex(FILE *f, char name[], COMP data[], int rows, int cols, int col_len)
-{
-    int r,c;
-
-    fprintf(f, "# name: %s\n", name);
-    fprintf(f, "# type: complex matrix\n");
-    fprintf(f, "# rows: %d\n", rows);
-    fprintf(f, "# columns: %d\n", cols);
-    
-    for(r=0; r<rows; r++) {
-       for(c=0; c<cols; c++)
-           fprintf(f, " (%f,%f)", data[r*col_len+c].real, data[r*col_len+c].imag);
-       fprintf(f, "\n");
-    }
-
-    fprintf(f, "\n\n");
-}