1 // ----------------------------------------------------------------------------
2 // interleave.cxx -- MFSK (de)interleaver
3 //
4 // Copyright (C) 2006-2008
5 // Dave Freese, W1HKJ
6 //
7 // This file is part of fldigi. Adapted from code contained in gmfsk source code
8 // distribution.
9 // gmfsk Copyright (C) 2001, 2002, 2003
10 // Tomi Manninen (oh2bns@sral.fi)
11 //
12 // Fldigi is free software: you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation, either version 3 of the License, or
15 // (at your option) any later version.
16 //
17 // Fldigi is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with fldigi. If not, see <http://www.gnu.org/licenses/>.
24 // ----------------------------------------------------------------------------
25
26 #include <config.h>
27
28 #include <cstring>
29
30 #include "interleave.h"
31
32 // ----------------------------------------------------------------------
33
interleave(int _size,int _depth,int dir)34 interleave::interleave (int _size, int _depth, int dir)
35 {
36 size = _size;
37 depth = _depth;
38 direction = dir;
39 len = size * size * depth;
40 table = new unsigned char [len];
41 flush();
42 }
43
~interleave()44 interleave::~interleave ()
45 {
46 delete [] table;
47 }
48
init()49 void interleave::init()
50 {
51 if(table) {
52 len = size * size * depth;
53 flush();
54 }
55 }
56
symbols(unsigned char * psyms)57 void interleave::symbols(unsigned char *psyms)
58 {
59 int i, j, k;
60
61 for (k = 0; k < depth; k++) {
62 for (i = 0; i < size; i++)
63 for (j = 0; j < size - 1; j++)
64 *tab(k, i, j) = *tab(k, i, j + 1);
65
66 for (i = 0; i < size; i++)
67 *tab(k, i, size - 1) = psyms[i];
68
69 for (i = 0; i < size; i++) {
70 if (direction == INTERLEAVE_FWD)
71 psyms[i] = *tab(k, i, size - i - 1);
72 else
73 psyms[i] = *tab(k, i, i);
74 }
75 }
76 }
77
bits(unsigned int * pbits)78 void interleave::bits(unsigned int *pbits)
79 {
80 unsigned char syms[size];
81 int i;
82
83 for (i = 0; i < size; i++)
84 syms[i] = (*pbits >> (size - i - 1)) & 1;
85
86 symbols(syms);
87
88 for (*pbits = i = 0; i < size; i++)
89 *pbits = (*pbits << 1) | syms[i];
90 }
91
flush(void)92 void interleave::flush(void)
93 {
94 // Fill entire RX interleaver with punctures or 0 depending on whether
95 // Rx or Tx
96 if (direction == INTERLEAVE_REV)
97 memset(table, PUNCTURE, len);
98 else
99 memset(table, 0, len);
100 }
101
102
103 // ----------------------------------------------------------------------
104
105