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