1 /* -*- c++ -*- */
2 /*
3  * Copyright 2014 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
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)
10  * any later version.
11  *
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.
16  *
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.
21  */
22 
23 #include "atsc_randomize.h"
24 
25 namespace gr {
26 namespace dtv {
27 
28 unsigned char atsc_randomize::s_output_map[1 << 14];
29 bool atsc_randomize::s_output_map_initialized_p = false;
30 
atsc_randomize()31 atsc_randomize::atsc_randomize()
32 {
33     d_state = PRELOAD_VALUE;
34 
35     if (!s_output_map_initialized_p)
36         initialize_output_map();
37 }
38 
39 /*!
40  * \brief Generate the table used in the fast_output_map function.
41  *
42  * The table has 16K byte entries, but because of how is is used, only
43  * 256 entries end up being resident in the cache.  This seems
44  * like a good use of memory.  We can get away with a 16K table
45  * because the low two bits of the state do not affect the output
46  * function.  By shifting right those two bits we shrink the table,
47  * and also get better cache line utilization.
48  */
initialize_output_map()49 void atsc_randomize::initialize_output_map()
50 {
51     s_output_map_initialized_p = true;
52 
53     for (int i = 0; i < (1 << 14); i++)
54         s_output_map[i] = slow_output_map(i << 2);
55 }
56 
57 
reset()58 void atsc_randomize::reset() { d_state = PRELOAD_VALUE; }
59 
randomize(atsc_mpeg_packet_no_sync & out,const atsc_mpeg_packet & in)60 void atsc_randomize::randomize(atsc_mpeg_packet_no_sync& out, const atsc_mpeg_packet& in)
61 {
62     assert(in.data[0] == MPEG_SYNC_BYTE); // confirm it's there, then drop
63 
64     for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++)
65         out.data[i] = in.data[i + 1] ^ output_and_clk();
66 }
67 
derandomize(atsc_mpeg_packet & out,const atsc_mpeg_packet_no_sync & in)68 void atsc_randomize::derandomize(atsc_mpeg_packet& out,
69                                  const atsc_mpeg_packet_no_sync& in)
70 {
71     out.data[0] = MPEG_SYNC_BYTE; // add sync byte to beginning of packet
72 
73     for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++)
74         out.data[i + 1] = in.data[i] ^ output_and_clk();
75 }
76 
77 
slow_output_map(int st)78 unsigned char atsc_randomize::slow_output_map(int st)
79 {
80     int output = 0;
81 
82     if (st & 0x8000)
83         output |= 0x01;
84 
85     if (st & 0x2000)
86         output |= 0x02;
87 
88     if (st & 0x1000)
89         output |= 0x04;
90 
91     if (st & 0x0200)
92         output |= 0x08;
93 
94     if (st & 0x0020)
95         output |= 0x10;
96 
97     if (st & 0x0010)
98         output |= 0x20;
99 
100     if (st & 0x0008)
101         output |= 0x40;
102 
103     if (st & 0x0004)
104         output |= 0x80;
105 
106     return output;
107 }
108 
109 } /* namespace dtv */
110 } /* namespace gr */
111