varicode encoding and decoding, passes unittest
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 24 Nov 2012 11:02:48 +0000 (11:02 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 24 Nov 2012 11:02:48 +0000 (11:02 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1058 01035d8c-6547-0410-b346-abe4f91aad63

fdmdv2/src/varicode.c [new file with mode: 0644]
fdmdv2/src/varicode.h [new file with mode: 0644]
fdmdv2/src/varicode_table.h [new file with mode: 0644]

diff --git a/fdmdv2/src/varicode.c b/fdmdv2/src/varicode.c
new file mode 100644 (file)
index 0000000..31c64e2
--- /dev/null
@@ -0,0 +1,166 @@
+//==========================================================================
+// Name:            varicode.h
+// Purpose:         Varicode encoded and decode functions
+// Created:         Nov 24, 2012
+// Authors:         David Rowe
+//
+// To test:
+//          $ gcc varicode.c -o varicode -DVARICODE_UNITTEST -Wall
+//          $ ./varicode
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  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 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 "varicode.h"
+#include "varicode_table.h"
+
+#define VARICODE_MAX_BITS (10+2) /* 10 bits for code plus 2 0 bits for inter-character space */
+
+/*
+  output is an unpacked array of bits of maximum size max_out.  Note
+  unpacked arrays are a more suitable form for modulator input.
+*/
+
+int varicode_encode(int varicode_out[], char ascii_in[], int max_out, int n_in) {
+    int            n_out, index, n_zeros, v_len;
+    unsigned short byte1, byte2, packed;
+
+    n_out = 0;
+
+    while(n_in && (n_out < max_out)) {
+
+        assert((unsigned int)(*ascii_in) < 128);
+
+        index = 2*(unsigned int)(*ascii_in);
+        byte1 = varicode_table[index];
+        byte2 = varicode_table[index+1];
+        packed = (byte1 << 8) + byte2;
+        //printf("n_in: %d ascii_in: %c index: %d packed 0x%x\n", n_in, *ascii_in, index, packed);
+        ascii_in++;
+
+        n_zeros = 0;
+        v_len = 0;
+        while ((n_zeros < 2) && (n_out < max_out) && (v_len <= VARICODE_MAX_BITS)) {
+            if (packed & 0x8000) {
+                *varicode_out = 1;
+                n_zeros = 0;
+            }
+            else {
+                *varicode_out = 0;
+                n_zeros++;
+            }
+            //printf("packed: 0x%x *varicode_out: %d n_zeros: %d v_len: %d\n", packed, *varicode_out, n_zeros,v_len );
+            packed <<= 1;
+            varicode_out++;
+
+            n_out++;
+            v_len++;
+        }
+        assert(v_len <= VARICODE_MAX_BITS);
+
+        n_in--;
+            
+    }
+
+    return n_out;
+}
+
+int varicode_decode(char ascii_out[], int varicode_in[], int max_out, int n_in) {
+    int            i, n_out, n_zeros, found, v_len;
+    unsigned short byte1, byte2, packed;
+
+    n_out = 0;
+
+    //printf("max_out: %d n_in: %d\n", max_out, n_in);
+    while(n_in && (n_out < max_out)) {
+        
+        n_zeros = 0;
+        v_len = 0;
+        packed = 0;
+        while ((n_zeros < 2) && n_in && (v_len <= VARICODE_MAX_BITS)) {
+            if (*varicode_in++) {
+                packed |= (0x8000 >> v_len);
+                n_zeros = 0;
+            }
+            else {
+                n_zeros++;
+            }
+            n_in--;
+            v_len++;
+        }
+        
+        //printf("packed: 0x%x n_zeros: %d v_len: %d n_in: %d\n", packed, n_zeros, v_len, n_in);
+      
+        /* v_len might be > VARICODE_MAX_BITS is an error condition */
+
+        if (v_len && (v_len <= VARICODE_MAX_BITS)) {
+            byte1 = packed >> 8;
+            byte2 = packed & 0xff;
+
+            found = 0;
+            for(i=0; i<128; i++) {
+                if ((byte1 == varicode_table[2*i]) && (byte2 == varicode_table[2*i+1])) {
+                    found = 1;
+                    //printf("%c\n", (char)i);
+                    *ascii_out++ = i;
+                }
+            }
+            if (found == 1)
+                n_out++;
+        }
+        //printf("n_out: %d n_in: %d\n", n_out, n_in);
+    }
+
+    return n_out;
+}
+
+#ifdef VARICODE_UNITTEST
+int main(void) {
+    char *ascii_in;
+    int *varicode;
+    int  i, n_varicode_bits_out, n_ascii_chars_out;
+    char *ascii_out;
+
+    ascii_in = (char*)malloc(sizeof(varicode_table)/2);
+    varicode = (int*)malloc(VARICODE_MAX_BITS*sizeof(int)*strlen(ascii_in));
+    ascii_out = (char*)malloc(strlen(ascii_in)+1);
+    
+    for(i=0; i<sizeof(varicode_table)/2; i++)
+        ascii_in[i] = (char)i;
+    n_varicode_bits_out = varicode_encode(varicode, ascii_in, VARICODE_MAX_BITS*strlen(ascii_in), strlen(ascii_in));
+    n_ascii_chars_out = varicode_decode(ascii_out, varicode, strlen(ascii_in), n_varicode_bits_out);
+    assert(n_ascii_chars_out == strlen(ascii_in));
+    ascii_out[n_ascii_chars_out] = 0;
+
+    //for(i=0; i<n_varicode_bits_out; i++) {
+    //    printf("%d \n", varicode[i]);
+    //}
+
+    //printf("ascii_out: %s\n", ascii_out);
+    if (strcmp(ascii_in, ascii_out) == 0)
+        printf("Pass\n");
+    else
+        printf("Fail\n");
+
+    free(ascii_in);
+    free(ascii_out);
+    free(varicode);
+    return 0;
+}
+#endif
diff --git a/fdmdv2/src/varicode.h b/fdmdv2/src/varicode.h
new file mode 100644 (file)
index 0000000..b40b695
--- /dev/null
@@ -0,0 +1,36 @@
+//==========================================================================
+// Name:            varicode.h
+// Purpose:         Varicode encoded and decode functions
+// Created:         Nov 24, 2012
+// Authors:         David Rowe
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  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 General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __VARICODE__
+#define __VARICODE__
+
+#ifdef __cplusplus
+extern "C" {
+
+#endif
+int varicode_encode(int varicode_out[], char ascii_in[], int max_out, int n_in);
+int varicode_decode(char ascii_out[], int varicode_in[], int max_out, int n_in);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/fdmdv2/src/varicode_table.h b/fdmdv2/src/varicode_table.h
new file mode 100644 (file)
index 0000000..75155a8
--- /dev/null
@@ -0,0 +1,291 @@
+//==========================================================================
+// Name:            varicode_table.h
+// Purpose:         Varicode look up table
+// Created:         Nov 24, 2012
+// Authors:         Clint Turner, KA7OEI,  Peter Martinez, G3PLX
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  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 General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+/* The following table defines the PKS31 varicode.  There are 128 entries,
+corresponding to ASCII characters 0-127 with two bytes for each entry.  The bits
+for the varicode are to be shifted out MSB-first for both bytes, with the first byte
+in the table being the first one to be sent.
+
+More than one zero in sequence signifies the end of the character (i.e.
+two zeroes are the intercharacter sequence, so at least two zeroes should always be
+sent before the next character is sent.
+
+This file is constructed with information from the article "PSK31 Fundamentals"
+by Peter Martinez, G3PLX by Clint Turner, KA7OEI
+*/
+unsigned char const varicode_table[256] =      {
+0b10101010,
+0b11000000, // 0 NUL
+0b10110110,
+0b11000000, // 1 SOH
+0b10111011,
+0b01000000, // 2 STX
+0b11011101,
+0b11000000, // 3 ETX
+0b10111010,
+0b11000000, // 4 EOT
+0b11010111,
+0b11000000, // 5 ENQ
+0b10111011,
+0b11000000, // 6 ACK
+0b10111111,
+0b01000000, // 7 BEL
+0b10111111,
+0b11000000, // 8 BS
+0b11101111,
+0b00000000, // 9 HT
+0b11101000,
+0b00000000, // 10 LF
+0b11011011,
+0b11000000, // 11 VT
+0b10110111,
+0b01000000, // 12 FF
+0b11111000,
+0b00000000, // 13 CR
+0b11011101,
+0b01000000, // 14 SO
+0b11101010,
+0b11000000, // 15 SI
+0b10111101,
+0b11000000, // 16 DLE
+0b10111101,
+0b01000000, // 17 DC1
+0b11101011,
+0b01000000, // 18 DC2
+0b11101011,
+0b11000000, // 19 DC3
+0b11010110,
+0b11000000, // 20 DC4
+0b11011010,
+0b11000000, // 21 NAK
+0b11011011,
+0b01000000, // 22 SYN
+0b11010101,
+0b11000000, // 23 ETB
+0b11011110,
+0b11000000, // 24 CAN
+0b11011111,
+0b01000000, // 25 EM
+0b11101101,
+0b11000000, // 26 SUB
+0b11010101,
+0b01000000, // 27 ESC
+0b11010111,
+0b01000000, // 28 FS
+0b11101110,
+0b11000000, // 29 GS
+0b10111110,
+0b11000000, // 30 RS
+0b11011111,
+0b11000000, // 31 US
+0b10000000,
+0b00000000, // 32 SP
+0b11111111,
+0b10000000, // 33 !
+0b10101111,
+0b10000000, // 34 "
+0b11111010,
+0b10000000, // 35 #
+0b11101101,
+0b10000000, // 36 $
+0b10110101,
+0b01000000, // 37 %
+0b10101110,
+0b11000000, // 38 &
+0b10111111,
+0b10000000, // 39 '
+0b11111011,
+0b00000000, // 40 (
+0b11110111,
+0b00000000, // 41 )
+0b10110111,
+0b10000000, // 42 *
+0b11101111,
+0b10000000, // 43 +
+0b11101010,
+0b00000000, // 44 ,
+0b11010100,
+0b00000000, // 45 -
+0b10101110,
+0b00000000, // 46 .
+0b11010111,
+0b10000000, // 47 /
+0b10110111,
+0b00000000, // 48 0
+0b10111101,
+0b00000000, // 49 1
+0b11101101,
+0b00000000, // 50 2
+0b11111111,
+0b00000000, // 51 3
+0b10111011,
+0b10000000, // 52 4
+0b10101101,
+0b10000000, // 53 5
+0b10110101,
+0b10000000, // 54 6
+0b11010110,
+0b10000000, // 55 7
+0b11010101,
+0b10000000, // 56 8
+0b11011011,
+0b10000000, // 57 9
+0b11110101,
+0b00000000, // 58 :
+0b11011110,
+0b10000000, // 59 ;
+0b11110110,
+0b10000000, // 60 <
+0b10101010,
+0b00000000, // 61 =
+0b11101011,
+0b10000000, // 62 >
+0b10101011,
+0b11000000, // 63 ?
+0b10101111,
+0b01000000, // 64 @
+0b11111010,
+0b00000000, // 65 A
+0b11101011,
+0b00000000, // 66 B
+0b10101101,
+0b00000000, // 67 C
+0b10110101,
+0b00000000, // 68 D
+0b11101110,
+0b00000000, // 69 E
+0b11011011,
+0b00000000, // 70 F
+0b11111101,
+0b00000000, // 71 G
+0b10101010,
+0b10000000, // 72 H
+0b11111110,
+0b00000000, // 73 I
+0b11111110,
+0b10000000, // 74 J
+0b10111110,
+0b10000000, // 75 K
+0b11010111,
+0b00000000, // 76 L
+0b10111011,
+0b00000000, // 77 M
+0b11011101,
+0b00000000, // 78 N
+0b10101011,
+0b00000000, // 79 O
+0b11010101,
+0b00000000, // 80 P
+0b11101110,
+0b10000000, // 81 Q
+0b10101111,
+0b00000000, // 82 R
+0b11011110,
+0b00000000, // 83 S
+0b11011010,
+0b00000000, // 84 T
+0b10101011,
+0b10000000, // 85 U
+0b11011010,
+0b10000000, // 86 V
+0b10101110,
+0b10000000, // 87 W
+0b10111010,
+0b10000000, // 88 X
+0b10111101,
+0b10000000, // 89 Y
+0b10101011,
+0b01000000, // 90 Z
+0b11111011,
+0b10000000, // 91 [
+0b11110111,
+0b10000000, // 92 "\"
+0b11111101,
+0b10000000, // 93 ]
+0b10101111,
+0b11000000, // 94 ^
+0b10110110,
+0b10000000, // 95 _ (underline)
+0b10110111,
+0b11000000, // 96 `
+0b10110000,
+0b00000000, // 97 a
+0b10111110,
+0b00000000, // 98 b
+0b10111100,
+0b00000000, // 99 c
+0b10110100,
+0b00000000, // 100 d
+0b11000000,
+0b00000000, // 101 e
+0b11110100,
+0b00000000, // 102 f
+0b10110110,
+0b00000000, // 103 g
+0b10101100,
+0b00000000, // 104 h
+0b11010000,
+0b00000000, // 105 i
+0b11110101,
+0b10000000, // 106 j
+0b10111111,
+0b00000000, // 107 k
+0b11011000,
+0b00000000, // 108 l
+0b11101100,
+0b00000000, // 109 m
+0b11110000,
+0b00000000, // 110 n
+0b11100000,
+0b00000000, // 111 o
+0b11111100,
+0b00000000, // 112 p
+0b11011111,
+0b10000000, // 113 q
+0b10101000,
+0b00000000, // 114 r
+0b10111000,
+0b00000000, // 115 s
+0b10100000,
+0b00000000, // 116 t
+0b11011100,
+0b00000000, // 117 u
+0b11110110,
+0b00000000, // 118 v
+0b11010110,
+0b00000000, // 119 w
+0b11011111,
+0b00000000, // 120 x
+0b10111010,
+0b00000000, // 121 y
+0b11101010,
+0b10000000, // 122 z
+0b10101101,
+0b11000000, // 123 {
+0b11011101,
+0b10000000, // 124 |
+0b10101101,
+0b01000000, // 125 }
+0b10110101,
+0b11000000, // 126 ~
+0b11101101,
+0b01000000, // 127 (del)
+};