horus_demod and horus_api demodulating RTTY OK
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 14 Apr 2018 01:48:11 +0000 (01:48 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 14 Apr 2018 01:48:11 +0000 (01:48 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3482 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/horus_api.c
codec2-dev/src/horus_api.h
codec2-dev/src/horus_demod.c

index 037eac2be6db5ad5de7f2461a4a03442cc5fc331..a7440132f4ff9d285747a12b04da8764ee6dcfb6 100644 (file)
@@ -41,7 +41,8 @@
 #define HORUS_BINARY_NUM_PAYLOAD_BYTES  22    /* fixed number of bytes in binary payload     */
 
 struct horus {
-    int         mode;                
+    int         mode;
+    int         verbose;
     struct FSK *fsk;                 /* states for FSK modem              */
     int         Fs;                  /* sample rate in Hz                 */
     int         mFSK;                /* number of FSK tones               */
@@ -79,7 +80,7 @@ struct horus *horus_open (int mode) {
     struct horus *hstates = (struct horus *)malloc(sizeof(struct horus));
     assert(hstates != NULL);
 
-    hstates->Fs = 48000; hstates->Rs = 100;
+    hstates->Fs = 48000; hstates->Rs = 100; hstates->verbose = 0; hstates->mode = mode;
 
     if (mode == HORUS_MODE_RTTY) {
         hstates->mFSK = 2;
@@ -133,20 +134,20 @@ uint32_t horus_nin(struct horus *hstates) {
     return nin;
 }
 
-int horus_find_uw(struct horus *hstates) {
+int horus_find_uw(struct horus *hstates, int n) {
     int i, j, corr, mx, mx_ind;
-    int rx_bits_mapped[hstates->rx_bits_len];
+    int rx_bits_mapped[n+hstates->uw_len];
     
     /* map rx_bits to +/-1 for UW search */
 
-    for(i=0; i<hstates->max_packet_len; i++) {
+    for(i=0; i<n+hstates->uw_len; i++) {
         rx_bits_mapped[i] = 2*hstates->rx_bits[i] - 1;
     }
     
     /* look for UW  */
 
     mx = 0; mx_ind = 0;
-    for(i=0; i<hstates->fsk->Nbits; i++) {
+    for(i=0; i<n; i++) {
 
         /* calculate correlation between bit stream and UW */
         
@@ -192,7 +193,7 @@ int extract_horus_rtty(struct horus *hstates, char ascii_out[], int uw_loc) {
     char    *pout, *ptx_crc;
     uint16_t rx_crc, tx_crc;
 
-    pout = ascii_out; nout = 0; crc_ok = 0; endpacket = 0;
+    pout = ascii_out; nout = 0; crc_ok = 0; endpacket = 0; rx_crc = tx_crc = 0;
     
     for (i=st; i<en; i+=nfield+npad) {
 
@@ -200,16 +201,22 @@ int extract_horus_rtty(struct horus *hstates, char ascii_out[], int uw_loc) {
 
         char_dec = 0;
         for(j=0; j<nfield; j++) {
-            assert(hstates->rx_bits[i] <= 1);
-            char_dec |= hstates->rx_bits[i] * (1<<j);
+            assert(hstates->rx_bits[i+j] <= 1);
+            char_dec |= hstates->rx_bits[i+j] * (1<<j);
         }
-        
+        if (hstates->verbose) {
+            fprintf(stderr, "i: %4d 0x%02x %c ", i, char_dec, char_dec);
+            if ((nout % 6) == 0) {
+                fprintf(stderr, "\n");
+            }
+        }
+
         /*  if we find a '*' that's the end of the packet for RX CRC calculations */
 
         if (!endpacket && (char_dec == 42)) {
             endpacket = 1;
             rx_crc = horus_l2_gen_crc16((uint8_t*)ascii_out, nout);
-            ptx_crc = pout + 2; /* start of tx CRC */
+            ptx_crc = pout + 1; /* start of tx CRC */
         }
 
         /* build up output array, really only need up to tx crc but
@@ -220,13 +227,15 @@ int extract_horus_rtty(struct horus *hstates, char ascii_out[], int uw_loc) {
         
     }
 
-    /* if we found the end of packet flag and have enough chars to computer checksum ... */
-    
+    /* if we found the end of packet flag and have enough chars to compute checksum ... */
+
+    //fprintf(stderr, "\n\ntx CRC...\n");
     if (endpacket && (pout > (ptx_crc+3))) {
         tx_crc = 0;
         for(i=0; i<4; i++) {
             tx_crc <<= 4;
-            tx_crc += hex2int(ptx_crc[i]);
+            tx_crc |= hex2int(ptx_crc[i]);
+            //fprintf(stderr, "ptx_crc[%d] %c 0x%02X tx_crc: 0x%04X\n", i, ptx_crc[i], hex2int(ptx_crc[i]), tx_crc);
         }
         crc_ok = (tx_crc == rx_crc);
         *(ptx_crc-1) = 0;  /* terminate ASCII string */
@@ -235,6 +244,11 @@ int extract_horus_rtty(struct horus *hstates, char ascii_out[], int uw_loc) {
         *ascii_out = 0;
     }
 
+    if (hstates->verbose) {
+        fprintf(stderr, "\n endpacket: %d nout: %d tx_crc: 0x%04x rx_crc: 0x%04x\n",
+                endpacket, nout, tx_crc, rx_crc);
+    }
+    
     /* make sure we don't overrun storage */
     
     assert(nout <= horus_get_max_ascii_out_len(hstates));
@@ -248,7 +262,7 @@ int extract_horus_binary(struct horus *hstates, char hex_out[], int uw_loc) {
     int st = uw_loc + hstates->uw_len;                  /* first bit of first char        */
     int en = uw_loc + hstates->max_packet_len - nfield; /* last bit of max length packet  */
 
-    int      i, j, nout;
+    int      j, b, nout;
     uint8_t  rxpacket[hstates->max_packet_len];
     uint8_t  rxbyte, *pout;
  
@@ -256,15 +270,15 @@ int extract_horus_binary(struct horus *hstates, char hex_out[], int uw_loc) {
     
     pout = rxpacket; nout = 0;
     
-    for (i=st; i<en; i+=nfield) {
+    for (b=st; b<en; b+=nfield) {
 
         /* assemble bytes MSB to LSB */
 
         rxbyte = 0;
         for(j=0; j<nfield; j++) {
-            assert(hstates->rx_bits[i] <= 1);
+            assert(hstates->rx_bits[b+j] <= 1);
             rxbyte <<= 1;
-            rxbyte |= hstates->rx_bits[i];
+            rxbyte |= hstates->rx_bits[b+j];
         }
         
         /* build up output array */
@@ -285,12 +299,18 @@ int horus_rx(struct horus *hstates, char ascii_out[], short demod_in[]) {
     
     assert(hstates != NULL);
     valid_packet = 0;
+
+    int Nbits = hstates->fsk->Nbits;
+    int rx_bits_len = hstates->rx_bits_len;
+    
+    if (hstates->verbose) {
+        fprintf(stderr, "max_packet_len: %d rx_bits_len: %d Nbits: %d\n",
+                hstates->max_packet_len, rx_bits_len, Nbits);
+    }
     
     /* shift buffer of bits to make room for new bits */
 
-    int Nbits = hstates->fsk->Nbits;
-    int max_packet_len = hstates->max_packet_len;
-    for(i=0,j=max_packet_len-Nbits; i<Nbits; i++,j++) {
+    for(i=0,j=Nbits; j<rx_bits_len; i++,j++) {
         hstates->rx_bits[i] = hstates->rx_bits[j];
     }
                    
@@ -301,12 +321,16 @@ int horus_rx(struct horus *hstates, char ascii_out[], short demod_in[]) {
         demod_in_comp[i].real = demod_in[i];
         demod_in_comp[i].imag = 0;
     }
-    fsk_demod(hstates->fsk, &hstates->rx_bits[max_packet_len-Nbits], demod_in_comp);
+    fsk_demod(hstates->fsk, &hstates->rx_bits[rx_bits_len-Nbits], demod_in_comp);
     
     /* UW search to see if we can find the start of a packet in the buffer */
     
-    if ((uw_loc = horus_find_uw(hstates)) != -1) {
+    if ((uw_loc = horus_find_uw(hstates, Nbits)) != -1) {
 
+        if (hstates->verbose) {
+            fprintf(stderr, "uw_loc: %d mode: %d\n", uw_loc, hstates->mode);
+        }
+        
         /* OK we have found a unique word, and therefore the start of
            a packet, so lets try to extract valid packets */
 
@@ -387,3 +411,8 @@ void horus_get_modem_extended_stats (struct horus *hstates, struct MODEM_STATS *
     }
 }
 
+void horus_set_verbose(struct horus *hstates, int verbose) {
+    assert(hstates != NULL);
+    hstates->verbose = verbose;
+}
+
index c3fd1a2485ea34ecdadaa54696ba3b00b04d9607..36e171a339fe1c44d30696a1d534659afbb7c13a 100644 (file)
@@ -52,6 +52,10 @@ uint32_t      horus_nin   (struct horus *hstates);
       
 int           horus_rx    (struct horus *hstates, char ascii_out[], short demod_in[]);
 
+/* set verbose level */
+      
+void horus_set_verbose(struct horus *hstates, int verbose);
+      
 /* functions to get information from API  */
       
 int           horus_get_version              (void);
index 9fe95d96e9998042e706d3dc82ebce95ffe059dc..5ff6af0add22d3860cbdc20f5fcc2fde02669cff 100644 (file)
  
   Can operate in Horus RTTY or Binary mode.
 
+  Testing with a 8000Hz sample rate wave file:
+
+    $ sox ~/Desktop/horus.wav -r 48000 -t raw - | ./horus_demod -m RTTY -v - /dev/nul/
+
 \*---------------------------------------------------------------------------*/
 
 /*
@@ -43,14 +47,15 @@ int main(int argc, char *argv[]) {
     struct   MODEM_STATS stats;
     FILE    *fin,*fout;
     int      i,j,Ndft,mode;
-    int      stats_ctr,stats_loop, stats_rate;
+    int      stats_ctr,stats_loop, stats_rate, verbose;
     float    loop_time;
     int      enable_stats = 0;
 
     stats_loop = 0;
     stats_rate = 8;
     mode = -1;
-
+    verbose = 0;
+    
     int o = 0;
     int opt_idx = 0;
     while ( o != -1 ) {
@@ -61,7 +66,7 @@ int main(int argc, char *argv[]) {
             {0, 0, 0, 0}
         };
         
-        o = getopt_long(argc,argv,"hm:t::",long_opts,&opt_idx);
+        o = getopt_long(argc,argv,"hvm:t::",long_opts,&opt_idx);
         
         switch(o) {
             case 'm':
@@ -85,56 +90,65 @@ int main(int argc, char *argv[]) {
                     }
                 }
                 break;
+            case 'v':
+                verbose = 1;
+            break;    
             case 'h':
             case '?':
                 goto helpmsg;
                 break;
         }
-
-        int dx = optind;
+    }
     
-        if( (argc - dx) < 1) {
-            fprintf(stderr, "Too few arguments\n");
-            goto helpmsg;
-        }
+    int dx = optind;
     
-        if( (argc - dx) > 5){
-            fprintf(stderr, "Too many arguments\n");
-        helpmsg:
-            fprintf(stderr,"usage: %s -m RTTY|binary [-t [r]] InputModemRawFile OutputAsciiFile\n",argv[0]);
-            fprintf(stderr,"\n");
-            fprintf(stderr,"InputModemRawFile      -  48 kHz 16 bit shorts real modem signal from radio\n");
-            fprintf(stderr," -m RTTY|binary\n"); 
-            fprintf(stderr,"--mode=RTTY|binary[r]  -  RTTY or binary Horus protcols\n");
-            fprintf(stderr," -t[r] --stats=[r]     -  Print out modem statistics to stderr in JSON.\n");
-            fprintf(stderr,"                          r, if provided, sets the number of modem frames"
-                                                 "between statistic printouts\n");
-            exit(1);
-        }
+    if( (argc - dx) < 1) {
+        fprintf(stderr, "Too few arguments\n");
+        goto helpmsg;
+    }
+    
+    if( (argc - dx) > 5){
+        fprintf(stderr, "Too many arguments\n");
+    helpmsg:
+        fprintf(stderr,"usage: %s -m RTTY|binary [-v] [-t [r]] InputModemRawFile OutputAsciiFile\n",argv[0]);
+        fprintf(stderr,"\n");
+        fprintf(stderr,"InputModemRawFile      48 kHz 16 bit shorts real modem signal from radio\n");
+        fprintf(stderr," -m RTTY|binary\n"); 
+        fprintf(stderr,"--mode=RTTY|binary[r]  RTTY or binary Horus protcols\n");
+        fprintf(stderr," -t[r] --stats=[r]     Print out modem statistics to stderr in JSON.\n");
+        fprintf(stderr,"                       r, if provided, sets the number of modem frames\n"
+                "                       between statistic printouts\n");
+        fprintf(stderr," -v                    verbose debug info\n");
+        exit(1);
+    }
         
-        /* Open files */
+    /* Open files */
 
-        if (strcmp(argv[dx + 1],"-")==0) {
-            fin = stdin;
-        } else {
-            fin = fopen(argv[dx + 1],"rb");
-        }
+    if (verbose) {
+         fprintf(stderr, "mode: %d verbose: %d stats_loop: %d stats_rate: %d\n",mode, verbose, stats_loop, stats_rate);
+    }
+    if (strcmp(argv[dx],"-")==0) {
+        fin = stdin;
+    } else {
+        fin = fopen(argv[dx],"rb");
+    }
     
-        if (strcmp(argv[dx + 2],"-")==0) {
-            fout = stdout;
-        } else {
-            fout = fopen(argv[dx + 4],"w");
-        }
+    if (strcmp(argv[dx + 1],"-")==0) {
+        fout = stdout;
+    } else {
+        fout = fopen(argv[dx + 1],"w");
+    }
         
-        if ((fin==NULL) || (fout==NULL)) {
-            fprintf(stderr,"Couldn't open test vector files\n");
-            exit(1);
-        }
+    if ((fin==NULL) || (fout==NULL)) {
+        fprintf(stderr,"Couldn't open test vector files\n");
+        exit(1);
     }
 
     /* end command line processing */
 
     hstates = horus_open(mode);
+    horus_set_verbose(hstates, verbose);
+    
     if (hstates == NULL) {
         fprintf(stderr, "Couldn't open Horus API\n");
         exit(1);
@@ -154,7 +168,10 @@ int main(int argc, char *argv[]) {
     /* Main loop ----------------------------------------------------------------------- */
 
     while( fread(demod_in, sizeof(short), horus_nin(hstates), fin) == horus_nin(hstates) ) {
+
+        if (verbose) {
+            fprintf(stderr, "read nin %d\n", horus_nin(hstates));
+        }
         if (horus_rx(hstates, ascii_out, demod_in)) {
             fprintf(stdout, "%s\n", ascii_out);
         }