summaryrefslogtreecommitdiff
path: root/gr-atsc/src/lib/atsci_randomizer.h
blob: 30c3235bb0c6b1f1b6ccfd1c0fb26b256b02a61b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* -*- c++ -*- */
/*
 * Copyright 2001 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.
 */

#ifndef _ATSC_RANDOMIZER_H_
#define _ATSC_RANDOMIZER_H_

#include <atsc_api.h>
#include <atsc_types.h>

/*! 
 * \brief ATSC data "whitener"
 *
 * The data randomizer described in ATSC standard A/53B.  
 * See figure D4 on page 54.
 */

class ATSC_API atsci_randomizer {
  friend class qa_atsci_randomizer;
  
 public:
  atsci_randomizer();

  /*! \brief reset randomizer LFSR
   *
   * must be called during the Data Segment Sync interval prior to the
   * first data segment.  I.e., the LFSR is reset prior to the first
   * field of each VSB data frame.
   */
  void reset ();

  //! randomize (whiten) mpeg packet and remove leading MPEG-2 sync byte
  void randomize (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet &in);

  //! derandomize (de-whiten) mpeg packet and add leading MPEG-2 sync byte
  void derandomize (atsc_mpeg_packet &out, const atsc_mpeg_packet_no_sync &in);

  unsigned int state() const { return d_state; }

 private:
  static void initialize_output_map ();
  static unsigned char slow_output_map (int st);

  static unsigned char fast_output_map (int st){
    return s_output_map[(st & 0xb23c) >> 2]; // Magic const with 8 bits set improves cache 
                                             // utilization.  The bits correspond to the taps
					     // used in output calculation.  Others may be 
					     // safely ignored.
  }
    
  //! return current output value
  unsigned char output (){
    return fast_output_map (d_state);
  }

  //! clock LFSR; advance to next state.
  void clk (){
    if (d_state & 0x1)
      d_state = ((d_state ^ MASK) >> 1) | 0x8000;
    else
      d_state = d_state >> 1;
  }

  //! return current output value and advance to next state
  unsigned char output_and_clk (){
    unsigned char r = output ();
    clk ();
    return r;
  }

  unsigned int		    d_state;

  static const unsigned int PRELOAD_VALUE = 0x018f; /* 0xf180 bit reversed */
  static const unsigned int MASK = 0xa638;
  static unsigned char 	    s_output_map[1 << 14];
  static bool 		    s_output_map_initialized_p;
};

#endif /* _ATSC_RANDOMIZER_H_ */