diff options
Diffstat (limited to 'gr-atsc/lib/atsci_viterbi_gen.cc')
-rw-r--r-- | gr-atsc/lib/atsci_viterbi_gen.cc | 267 |
1 files changed, 0 insertions, 267 deletions
diff --git a/gr-atsc/lib/atsci_viterbi_gen.cc b/gr-atsc/lib/atsci_viterbi_gen.cc deleted file mode 100644 index bff3c47736..0000000000 --- a/gr-atsc/lib/atsci_viterbi_gen.cc +++ /dev/null @@ -1,267 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2002,2006 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#include <iostream> -#include <stdio.h> - -using std::cerr; - -/* - * Trellis-encode a whole pile of 12 data segments for ATSC. - * This also includes scrambling the data among twelve Trellis encoders. - * - * Input is twelve 207-byte blocks of raw data (Reed-Solomon output that's - * been scrambled up by interleaving with other blocks). - * - * Output is 12 x 208 x 4 bytes, each byte containing a 3-bit symbol. - * The first 4 bytes are the segment sync symbol. - * - Got the first version of Trellis encoder coded. Compiles, but I - didn't realize that each data segment contains an odd number of BITS! - The second data segment in a field starts by pulling bits out of the - middles of the bytes it's encoding. You actually have to read all the - entries in that table on page 59 AND 60 to get it. - - There's a 4-segment asymmetric pattern of bit accesses. - There's a 3-segment asymmetric pattern of muxing encoders. - - The result is there's a 12-segment pattern that repeats throughout - the encoding of a field. So this routine now encodes 12 segments at once. - - This encoding system was either designed by a complete idiot or by - a complete genius. It's highly complex when it could have been very - simple. Now the question is whether - this incredible complexity buys us anything subtle and important. - */ - -#define SEGMENT_SIZE 207 -#define INPUT_SIZE (SEGMENT_SIZE * 12) -#define DIBITS_PER_BYTE 4 -#define EXTRAS (4 * 12) /* FIXME, sync symbols and such */ -#define SYMBOLS_OUT ((INPUT_SIZE * DIBITS_PER_BYTE) + EXTRAS) -#define SEGOF(x) ( (x) / ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE)) -#define SYMOF(x) (((x) % ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE))-4) -#define ENCODERS 12 -#define ENCODER_SEG_BUMP 4 - - -/* Shift counts to bit numbers (high order, low order); 9x entries unused */ -static const int bit1[8] = {1, 99, 3, 98, 5, 97, 7, 96}; -static const int bit2[8] = {0, 99, 2, 98, 4, 97, 6, 96}; - -/* Detailed Debugging */ -int debug_dec = 0; - -/* - * Build indirect data structures to say which symbols go into which - * encoder, and then where the resulting dibits from the encoders go. - */ -int -build_decode_structures (char *fileout) -{ - int retval = 0; - int i; - int encoder; - int trellis_wheredata[ENCODERS]; - unsigned char *symp, *next_sym_seg; - unsigned char symbols[SYMBOLS_OUT]; - int chunk; - int shift; - int skip_encoder_bump; - int *enco_syms[ENCODERS]; - int *enco_dibits[ENCODERS]; - int j; - /* The data structures we'll build and then spit out... */ - int sync_symbol_indices[1000]; - int sync_symbol_indices_max; - int enco_which_syms[ENCODERS][INPUT_SIZE]; - int enco_which_dibits[ENCODERS][INPUT_SIZE]; - int enco_which_max; - #define BIT_PTR(int,shif) (((int) << 3) | ((shif) & 0x7)) - /* Running indices into them as we build 'em... */ - int *syncsyms = sync_symbol_indices; - - /* Start our running pointers at the start of our per-encoder subarrays */ - for (i = 0; i < ENCODERS; i++) { - enco_dibits[i] = enco_which_dibits[i]; - enco_syms[i] = enco_which_syms[i]; - } - - encoder = ENCODERS - ENCODER_SEG_BUMP; - skip_encoder_bump = 0; - symp = symbols; - next_sym_seg = symp; - - for (chunk = 0; - chunk < INPUT_SIZE; - chunk += ENCODERS) { - /* Associate data bytes with the Trellis encoders. - They get loaded or stored in an order that depends on where we are in the - segment sync progress (sigh). - GRR! When the chunk reload happens at the same time as the - segment boundary, we should bump the encoder NOW for the reload, - rather than LATER during the bitshift transition!!! */ - if (symp >= next_sym_seg) { - encoder = (encoder + ENCODER_SEG_BUMP) % ENCODERS; - skip_encoder_bump = 1; - } - - /* Remember where the data bytes are going to go, once we've - accumulated them from the 12 interleaved decoders */ - for (i = 0; i < ENCODERS; i++) { - trellis_wheredata[encoder] = chunk+i; - encoder++; - if (encoder >= ENCODERS) encoder = 0; - } - - for (shift = 6; shift >= 0; shift -= 2) { - - /* Segment boundaries happen to occur on some bitshift transitions. */ - if (symp >= next_sym_seg) { - /* Segment transition. Output a data segment sync symbol, and - mess with the trellis encoder mux. */ - *syncsyms++ = symp - symbols; - symp += 4; - next_sym_seg = symp + (SEGMENT_SIZE * DIBITS_PER_BYTE); - - if (!skip_encoder_bump) - encoder = (encoder + ENCODER_SEG_BUMP) % ENCODERS; - skip_encoder_bump = 0; - } - - /* Now run each of the 12 Trellis encoders to spit out 12 symbols. - Each encoder takes input from the same byte of the chunk, but the - outputs of the encoders come out in various orders. - NOPE -- this is false. The encoders take input from various - bytes of the chunk (which changes at segment sync time), AND - they also come out in various orders. You really do have to - keep separate track of: the datasegs bytes, the encoders, and - the symbol bytes -- because they're all moving with respect to - each other!!! */ - for (i = 0; i < ENCODERS; i++) { - if (debug_dec) - printf ("Seg %ld Symb %3ld Trell %2d Byte %6d Bits %d-%d = ", - (long) SEGOF(symp-symbols), (long) SYMOF(symp-symbols), - encoder, trellis_wheredata[encoder], - bit1[shift], bit2[shift]); - - /* Decoding: Grab symbol, run through decoder, slice dibit into - buffer. */ - /* This symbol goes into this encoder next */ - *(enco_syms[encoder]++) = symp - symbols; - symp++; - /* The next output from this encoder goes into these dibits */ - *(enco_dibits[encoder]++) = BIT_PTR(trellis_wheredata[encoder], shift); - - encoder++; if (encoder >= ENCODERS) encoder = 0; - } /* Encoders */ - } /* Bit shifts */ - -#if 0 - /* Now dump out the chunk of 12 data bytes that the twelve decoders have - accumulated. */ - unsigned char trellis_buffer[ENCODERS]; - unsigned char dibit; - unsigned char symbol; - int save_state; - for (i = 0; i < ENCODERS; i++) { - datasegs [trellis_wheredata[encoder]] = trellis_buffer[encoder]; - encoder++; - if (encoder >= ENCODERS) encoder = 0; - } /* Dumping encoder bytes */ -#endif - } /* Chunks */ - - /* Now print the resulting data structures in C++ */ - - if (!freopen(fileout, "w", stdout)) - return 2; - - printf ("/*\n\ - * atsc_viterbi_mux.cc\n\ - *\n\ - * Data structures for knowing which symbols are fed to which\n\ - * Viterbi decoders, and then where to put the resulting output dibits.\n\ - *\n\ - * Generated by 'atsc_viterbi_gen.cc'.\n\ - */\n\n"); - sync_symbol_indices_max = syncsyms - sync_symbol_indices; - printf ("const unsigned int sync_symbol_indices_max = %d;\n", - sync_symbol_indices_max); - printf ("const unsigned int sync_symbol_indices[%d] = {\n ", - sync_symbol_indices_max); - for (i = 0; i < sync_symbol_indices_max; i++) { - printf ("%d,%s", sync_symbol_indices[i], (7 == i%8)? "\n ": " "); - } - printf ("};\n\n"); - - enco_which_max = enco_dibits[0] - enco_which_dibits[0]; - for (i = 0; i < ENCODERS; i++) - if (enco_which_max != enco_dibits[i] - enco_which_dibits[i]) { - cerr << "Encoder " << i << " has different max_dibits " << - enco_dibits[i] - enco_which_dibits[i] << " than " << enco_which_max; - retval = 3; - } - - printf ("const unsigned int enco_which_max = %d;\n" , enco_which_max); - - printf ("const unsigned int enco_which_syms[%d][%d] = {\n", - ENCODERS, enco_which_max); - for (i = 0; i < ENCODERS; i++) { - printf (" /* %d */\n {", i); - for (j = 0; j < enco_which_max; j++) - printf ("%d,%s", enco_which_syms[i][j], (7 == j%8)? "\n ": " "); - printf ("},\n"); - } - printf ("};\n\n"); - - printf ("const unsigned int enco_which_dibits[%d][%d] = {\n", - ENCODERS, enco_which_max); - for (i = 0; i < ENCODERS; i++) { - printf (" /* %d */\n {", i); - for (j = 0; j < enco_which_max; j++) - printf ("%d,%s", enco_which_dibits[i][j], (7 == j%8)? "\n ": " "); - printf ("},\n"); - } - printf ("};\n\n"); - return retval; -} - -int -usage() -{ - cerr << "atsc_viterbi_gen: Usage:\n"; - cerr << " ./atsc_viterbi_gen -o atsc_viterbi_mux.cc\n"; - cerr << "That's all, folks!\n"; - return 1; -} - - -int -main(int argc, char **argv) -{ - if (argc != 3) return usage(); - if (argv[1][0] != '-' - || argv[1][1] != 'o' - || argv[1][2] != 0 ) return usage(); - return build_decode_structures(argv[2]); -} |