summaryrefslogtreecommitdiff
path: root/gr-atsc/lib/atsci_viterbi_gen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-atsc/lib/atsci_viterbi_gen.cc')
-rw-r--r--gr-atsc/lib/atsci_viterbi_gen.cc267
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]);
-}