summaryrefslogtreecommitdiff
path: root/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc')
-rw-r--r--gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc207
1 files changed, 103 insertions, 104 deletions
diff --git a/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc b/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc
index bf1e86c9f8..a30c5663d1 100644
--- a/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc
+++ b/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc
@@ -30,135 +30,134 @@
#include "atsc_viterbi_mux.h"
namespace gr {
- namespace dtv {
-
- atsc_viterbi_decoder::sptr
- atsc_viterbi_decoder::make()
- {
- return gnuradio::get_initial_sptr
- (new atsc_viterbi_decoder_impl());
- }
-
- atsc_viterbi_decoder_impl::atsc_viterbi_decoder_impl()
- : sync_block("dtv_atsc_viterbi_decoder",
- io_signature::make(1, 1, sizeof(atsc_soft_data_segment)),
- io_signature::make(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)))
- {
- set_output_multiple(NCODERS);
-
- /*
- * These fifo's handle the alignment problem caused by the
- * inherent decoding delay of the individual viterbi decoders.
- * The net result is that this entire block has a pipeline latency
- * of 12 complete segments.
- *
- * If anybody cares, it is possible to do it with less delay, but
- * this approach is at least somewhat understandable...
- */
-
- // the -4 is for the 4 sync symbols
- int fifo_size = ATSC_DATA_SEGMENT_LENGTH - 4 - viterbi[0].delay();
- for (int i = 0; i < NCODERS; i++)
+namespace dtv {
+
+atsc_viterbi_decoder::sptr atsc_viterbi_decoder::make()
+{
+ return gnuradio::get_initial_sptr(new atsc_viterbi_decoder_impl());
+}
+
+atsc_viterbi_decoder_impl::atsc_viterbi_decoder_impl()
+ : sync_block("dtv_atsc_viterbi_decoder",
+ io_signature::make(1, 1, sizeof(atsc_soft_data_segment)),
+ io_signature::make(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)))
+{
+ set_output_multiple(NCODERS);
+
+ /*
+ * These fifo's handle the alignment problem caused by the
+ * inherent decoding delay of the individual viterbi decoders.
+ * The net result is that this entire block has a pipeline latency
+ * of 12 complete segments.
+ *
+ * If anybody cares, it is possible to do it with less delay, but
+ * this approach is at least somewhat understandable...
+ */
+
+ // the -4 is for the 4 sync symbols
+ int fifo_size = ATSC_DATA_SEGMENT_LENGTH - 4 - viterbi[0].delay();
+ for (int i = 0; i < NCODERS; i++)
fifo[i] = new fifo_t(fifo_size);
- reset();
- }
+ reset();
+}
- atsc_viterbi_decoder_impl::~atsc_viterbi_decoder_impl()
- {
- for (int i = 0; i < NCODERS; i++)
+atsc_viterbi_decoder_impl::~atsc_viterbi_decoder_impl()
+{
+ for (int i = 0; i < NCODERS; i++)
delete fifo[i];
- }
+}
- void
- atsc_viterbi_decoder_impl::reset()
- {
- for (int i = 0; i < NCODERS; i++)
+void atsc_viterbi_decoder_impl::reset()
+{
+ for (int i = 0; i < NCODERS; i++)
fifo[i]->reset();
- }
+}
- std::vector<float>
- atsc_viterbi_decoder_impl::decoder_metrics() const
- {
- std::vector<float> metrics(NCODERS);
- for (int i = 0; i < NCODERS; i++)
+std::vector<float> atsc_viterbi_decoder_impl::decoder_metrics() const
+{
+ std::vector<float> metrics(NCODERS);
+ for (int i = 0; i < NCODERS; i++)
metrics[i] = viterbi[i].best_state_metric();
- return metrics;
- }
-
- int
- atsc_viterbi_decoder_impl::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- const atsc_soft_data_segment *in = (const atsc_soft_data_segment *) input_items[0];
- atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0];
-
- // The way the fs_checker works ensures we start getting packets
- // starting with a field sync, and out input multiple is set to
- // 12, so we should always get a mod 12 numbered first packet
- assert(noutput_items % NCODERS == 0);
-
- int dbwhere;
- int dbindex;
- int shift;
- float symbols[NCODERS][enco_which_max];
- unsigned char dibits[NCODERS][enco_which_max];
-
- unsigned char out_copy[OUTPUT_SIZE];
-
- for (int i = 0; i < noutput_items; i += NCODERS) {
+ return metrics;
+}
+
+int atsc_viterbi_decoder_impl::work(int noutput_items,
+ gr_vector_const_void_star& input_items,
+ gr_vector_void_star& output_items)
+{
+ const atsc_soft_data_segment* in = (const atsc_soft_data_segment*)input_items[0];
+ atsc_mpeg_packet_rs_encoded* out = (atsc_mpeg_packet_rs_encoded*)output_items[0];
+
+ // The way the fs_checker works ensures we start getting packets
+ // starting with a field sync, and out input multiple is set to
+ // 12, so we should always get a mod 12 numbered first packet
+ assert(noutput_items % NCODERS == 0);
+
+ int dbwhere;
+ int dbindex;
+ int shift;
+ float symbols[NCODERS][enco_which_max];
+ unsigned char dibits[NCODERS][enco_which_max];
+
+ unsigned char out_copy[OUTPUT_SIZE];
+
+ for (int i = 0; i < noutput_items; i += NCODERS) {
/* Build a continuous symbol buffer for each encoder */
for (unsigned int encoder = 0; encoder < NCODERS; encoder++)
- for (unsigned int k = 0; k < enco_which_max; k++)
- symbols[encoder][k] = in[i + (enco_which_syms[encoder][k]/832)].data[enco_which_syms[encoder][k] % 832];
+ for (unsigned int k = 0; k < enco_which_max; k++)
+ symbols[encoder][k] = in[i + (enco_which_syms[encoder][k] / 832)]
+ .data[enco_which_syms[encoder][k] % 832];
/* Now run each of the 12 Viterbi decoders over their subset of
the input symbols */
for (unsigned int encoder = 0; encoder < NCODERS; encoder++)
- for (unsigned int k = 0; k < enco_which_max; k++)
- dibits[encoder][k] = viterbi[encoder].decode(symbols[encoder][k]);
+ for (unsigned int k = 0; k < enco_which_max; k++)
+ dibits[encoder][k] = viterbi[encoder].decode(symbols[encoder][k]);
/* Move dibits into their location in the output buffer */
for (unsigned int encoder = 0; encoder < NCODERS; encoder++) {
- for (unsigned int k = 0; k < enco_which_max; k++) {
- /* Store the dibit into the output data segment */
- dbwhere = enco_which_dibits[encoder][k];
- dbindex = dbwhere >> 3;
- shift = dbwhere & 0x7;
- out_copy[dbindex] = (out_copy[dbindex] & ~(0x03 << shift)) | (fifo[encoder]->stuff(dibits[encoder][k]) << shift);
- } /* Symbols fed into one encoder */
- } /* Encoders */
+ for (unsigned int k = 0; k < enco_which_max; k++) {
+ /* Store the dibit into the output data segment */
+ dbwhere = enco_which_dibits[encoder][k];
+ dbindex = dbwhere >> 3;
+ shift = dbwhere & 0x7;
+ out_copy[dbindex] = (out_copy[dbindex] & ~(0x03 << shift)) |
+ (fifo[encoder]->stuff(dibits[encoder][k]) << shift);
+ } /* Symbols fed into one encoder */
+ } /* Encoders */
// copy output from contiguous temp buffer into final output
for (int j = 0; j < NCODERS; j++) {
- memcpy (&out[i + j].data[0],
- &out_copy[j * OUTPUT_SIZE/NCODERS],
- ATSC_MPEG_RS_ENCODED_LENGTH * sizeof(out_copy[0]));
+ memcpy(&out[i + j].data[0],
+ &out_copy[j * OUTPUT_SIZE / NCODERS],
+ ATSC_MPEG_RS_ENCODED_LENGTH * sizeof(out_copy[0]));
- // adjust pipeline info to reflect 12 segment delay
- plinfo::delay(out[i + j].pli, in[i + j].pli, NCODERS);
+ // adjust pipeline info to reflect 12 segment delay
+ plinfo::delay(out[i + j].pli, in[i + j].pli, NCODERS);
}
- }
-
- return noutput_items;
}
- void
- atsc_viterbi_decoder_impl::setup_rpc()
- {
+ return noutput_items;
+}
+
+void atsc_viterbi_decoder_impl::setup_rpc()
+{
#ifdef GR_CTRLPORT
- add_rpc_variable(
- rpcbasic_sptr(new rpcbasic_register_get<atsc_viterbi_decoder, std::vector<float> >(
- alias(), "decoder_metrics",
- &atsc_viterbi_decoder::decoder_metrics,
- pmt::make_f32vector(1,0),
- pmt::make_f32vector(1,100000),
- pmt::make_f32vector(1,0),
- "", "Viterbi decoder metrics", RPC_PRIVLVL_MIN,
- DISPTIME)));
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<atsc_viterbi_decoder, std::vector<float>>(
+ alias(),
+ "decoder_metrics",
+ &atsc_viterbi_decoder::decoder_metrics,
+ pmt::make_f32vector(1, 0),
+ pmt::make_f32vector(1, 100000),
+ pmt::make_f32vector(1, 0),
+ "",
+ "Viterbi decoder metrics",
+ RPC_PRIVLVL_MIN,
+ DISPTIME)));
#endif /* GR_CTRLPORT */
- }
+}
- } /* namespace dtv */
+} /* namespace dtv */
} /* namespace gr */