3 * Copyright 2002 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
23 #include <atsci_viterbi_decoder.h>
27 #include "atsci_viterbi_mux.cc"
30 /* How many separate Trellis encoders / Viterbi decoders run in parallel */
31 static const int NCODERS = 12;
33 static const float DSEG_SYNC_SYM1 = 5;
34 static const float DSEG_SYNC_SYM2 = -5;
35 static const float DSEG_SYNC_SYM3 = -5;
36 static const float DSEG_SYNC_SYM4 = 5;
38 atsci_viterbi_decoder::atsci_viterbi_decoder ()
43 * These fifo's handle the alignment problem caused by the
44 * inherent decoding delay of the individual viterbi decoders.
45 * The net result is that this entire block has a pipeline latency
46 * of 12 complete segments.
48 * If anybody cares, it is possible to do it with less delay, but
49 * this approach is at least somewhat understandable...
52 // the -4 is for the 4 sync symbols
53 int fifo_size = ATSC_DATA_SEGMENT_LENGTH - 4 - viterbi[0].delay ();
54 for (int i = 0; i < NCODERS; i++)
55 fifo[i] = new fifo_t(fifo_size);
60 atsci_viterbi_decoder::~atsci_viterbi_decoder ()
62 for (int i = 0; i < NCODERS; i++)
67 atsci_viterbi_decoder::reset ()
69 for (int i = 0; i < NCODERS; i++){
77 atsci_viterbi_decoder::decode (atsc_mpeg_packet_rs_encoded out[NCODERS],
78 const atsc_soft_data_segment in[NCODERS])
80 unsigned char out_copy[OUTPUT_SIZE];
81 float in_copy[INPUT_SIZE];
83 // copy input into continguous temporary buffer
84 for (int i = 0; i < NCODERS; i++){
85 assert (in[i].pli.regular_seg_p ());
86 memcpy (&in_copy[i * INPUT_SIZE/NCODERS],
88 ATSC_DATA_SEGMENT_LENGTH * sizeof (in_copy[0]));
91 memset (out_copy, 0, sizeof (out_copy)); // sanity check
94 decode_helper (out_copy, in_copy);
96 // copy output from contiguous temp buffer into final output
97 for (int i = 0; i < NCODERS; i++){
98 memcpy (&out[i].data[0],
99 &out_copy[i * OUTPUT_SIZE/NCODERS],
100 ATSC_MPEG_RS_ENCODED_LENGTH * sizeof (out_copy[0]));
103 // adjust pipeline info to reflect 12 segment delay
104 plinfo::delay (out[i].pli, in[i].pli, NCODERS);
109 atsci_viterbi_decoder::decode_helper (unsigned char out[OUTPUT_SIZE],
110 const float symbols_in[INPUT_SIZE])
121 /* Memset is not necessary if it's all working... */
122 memset (out, 0, OUTPUT_SIZE);
127 /* Check for sync symbols in the incoming data stream */
128 /* For now, all we do is complain to stdout. FIXME, pass it back to
129 caller as an error/quality signal. */
130 for (i = 0; i < sync_symbol_indices_max; i++) {
131 int j = sync_symbol_indices[i];
132 if (fabsf (symbols_in[j] - DSEG_SYNC_SYM1) > 1.0)
133 if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 1 at %d, expect %g, got %g.\n",
134 j, DSEG_SYNC_SYM1, symbols_in[j]);
136 if (fabsf (symbols_in[j] - DSEG_SYNC_SYM2) > 1.0)
137 if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 2 at %d, expect %g, got %g.\n",
138 j, DSEG_SYNC_SYM2, symbols_in[j]);
140 if (fabsf (symbols_in[j] - DSEG_SYNC_SYM3) > 1.0)
141 if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 3 at %d, expect %g, got %g.\n",
142 j, DSEG_SYNC_SYM3, symbols_in[j]);
144 if (fabsf (symbols_in[j] - DSEG_SYNC_SYM4) > 1.0)
145 if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 4 at %d, expect %g, got %g.\n",
146 j, DSEG_SYNC_SYM4, symbols_in[j]);
151 // printf ("@@@ DIBITS @@@\n");
153 /* Now run each of the 12 Trellis encoders over their subset of
155 for (encoder = 0; encoder < NCODERS; encoder++) {
156 dbi = 0; /* Reinitialize dibit index for new encoder */
157 fifo_t *dibit_fifo = fifo[encoder];
159 /* Feed all the incoming symbols into one encoder;
160 pump them into the relevant dibits. */
161 for (i = 0; i < enco_which_max; i++) {
162 symbol = symbols_in[enco_which_syms[encoder][i]];
163 dibit = dibit_fifo->stuff (viterbi[encoder].decode (symbol));
164 // printf ("%d\n", dibit);
165 /* Store the dibit into the output data segment */
166 dbwhere = enco_which_dibits[encoder][dbi++];
167 dbindex = dbwhere >> 3;
168 shift = dbwhere & 0x7;
170 (out[dbindex] & ~(0x03 << shift)) | (dibit << shift);
171 } /* Symbols fed into one encoder */