Statistics
| Branch: | Tag: | Revision:

root / gr-atsc / src / lib / atsc_field_sync_mux.cc @ 34af4364

History | View | Annotate | Download (5.5 kB)

1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2006 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
#ifdef HAVE_CONFIG_H
24
#include <config.h>
25
#endif
26
27
#include <atsc_field_sync_mux.h>
28
#include <gr_io_signature.h>
29
#include <atsc_consts.h>
30
#include <atsci_pnXXX.h>
31
32
33
atsc_field_sync_mux_sptr
34
atsc_make_field_sync_mux()
35
{
36
  return atsc_field_sync_mux_sptr(new atsc_field_sync_mux());
37
}
38
39
atsc_field_sync_mux::atsc_field_sync_mux()
40
  : gr_sync_block("atsc_field_sync_mux",
41
                  gr_make_io_signature(1, 1, sizeof(atsc_data_segment)),
42
                  gr_make_io_signature(1, 1, sizeof(atsc_data_segment)))
43
{
44
  reset();
45
}
46
47
static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one)
48
49
static const int N_SAVED_SYMBOLS = atsc_field_sync_mux::N_SAVED_SYMBOLS;
50
51
static void
52
init_field_sync_common (unsigned char *p, int mask,
53
                        const unsigned char saved_symbols[N_SAVED_SYMBOLS])
54
{
55
  static const unsigned char bin_map[2] = { 1, 6 };  // map binary values to 1 of 8 levels
56
57
  int  i = 0;
58
59
  p[i++] = bin_map[1];                  // data segment sync pulse
60
  p[i++] = bin_map[0];
61
  p[i++] = bin_map[0];
62
  p[i++] = bin_map[1];
63
64
  for (int j = 0; j < 511; j++)         // PN511
65
    p[i++] = bin_map[atsc_pn511[j]];
66
67
  for (int j = 0; j < 63; j++)          // PN63
68
    p[i++] = bin_map[atsc_pn63[j]];
69
70
  for (int j = 0; j < 63; j++)          // PN63, toggled on field 2
71
    p[i++] = bin_map[atsc_pn63[j] ^ mask];
72
73
  for (int j = 0; j < 63; j++)          // PN63
74
    p[i++] = bin_map[atsc_pn63[j]];
75
76
  p[i++] = bin_map[0];                  // 24 bits of VSB8 mode identifiera
77
  p[i++] = bin_map[0];
78
  p[i++] = bin_map[0];
79
  p[i++] = bin_map[0];
80
81
  p[i++] = bin_map[1];
82
  p[i++] = bin_map[0];
83
  p[i++] = bin_map[1];
84
  p[i++] = bin_map[0];
85
86
  p[i++] = bin_map[0];
87
  p[i++] = bin_map[1];
88
  p[i++] = bin_map[0];
89
  p[i++] = bin_map[1];
90
91
  p[i++] = bin_map[1];
92
  p[i++] = bin_map[1];
93
  p[i++] = bin_map[1];
94
  p[i++] = bin_map[1];
95
96
  p[i++] = bin_map[0];
97
  p[i++] = bin_map[1];
98
  p[i++] = bin_map[0];
99
  p[i++] = bin_map[1];
100
101
  p[i++] = bin_map[1];
102
  p[i++] = bin_map[0];
103
  p[i++] = bin_map[1];
104
  p[i++] = bin_map[0];
105
106
107
  for (int j = 0; j < 92; j++)          // 92 more bits
108
    p[i++] = bin_map[atsc_pn63[j % 63]];
109
110
  // now copy the last 12 symbols of the previous segment
111
112
  for (int j = 0; j < N_SAVED_SYMBOLS; j++)
113
    p[i++] = saved_symbols[j];
114
115
  assert (i == ATSC_DATA_SEGMENT_LENGTH);
116
}
117
inline static void
118
init_field_sync_1 (atsc_data_segment *s,
119
                   const unsigned char saved_symbols[N_SAVED_SYMBOLS])
120
{
121
  init_field_sync_common (&s->data[0], 0, saved_symbols);
122
}
123
124
inline static void
125
init_field_sync_2 (atsc_data_segment *s,
126
                   const unsigned char saved_symbols[N_SAVED_SYMBOLS])
127
128
{
129
  init_field_sync_common (&s->data[0], 1, saved_symbols);
130
}
131
132
static void
133
save_last_symbols (unsigned char saved_symbols[N_SAVED_SYMBOLS],
134
                   const atsc_data_segment &seg)
135
{
136
  for (int i = 0; i < N_SAVED_SYMBOLS; i++)
137
    saved_symbols[i] = seg.data[i + ATSC_DATA_SEGMENT_LENGTH - N_SAVED_SYMBOLS];}
138
139
140
inline static bool
141
last_regular_seg_p (const plinfo &pli)
142
{
143
  return pli.regular_seg_p () && (pli.segno () == ATSC_DSEGS_PER_FIELD - 1);
144
}
145
146
void
147
atsc_field_sync_mux::forecast (int noutput_items, gr_vector_int &ninput_items_required)
148
{
149
  unsigned ninputs = ninput_items_required.size();
150
  for (unsigned i = 0; i < ninputs; i++) 
151
    ninput_items_required[i] = fixed_rate_noutput_to_ninput (noutput_items);
152
  
153
}
154
155
156
int
157
atsc_field_sync_mux::work (int noutput_items,
158
                       gr_vector_const_void_star &input_items,
159
                       gr_vector_void_star &output_items)
160
{
161
  const atsc_data_segment *in = (const atsc_data_segment *) input_items[0];
162
  atsc_data_segment *out = (atsc_data_segment *) output_items[0];
163
164
  unsigned int index = 0;
165
  for (int outdex = 0; outdex < noutput_items; outdex++){
166
167
    assert (in[index].pli.regular_seg_p ());
168
169
    if (!in[index].pli.first_regular_seg_p ()){
170
      out[outdex] = in[index];                  // just copy in to out
171
172
      if (last_regular_seg_p (in[index].pli))
173
        save_last_symbols (d_saved_symbols, in[index]);
174
175
      index++;
176
    }
177
    else {                                      // first_regular_seg_p
178
      if (!d_already_output_field_sync){
179
        // write out field sync...
180
        atsc_data_segment       field_sync;
181
182
        if (in[index].pli.in_field1_p ())
183
          init_field_sync_1 (&field_sync, d_saved_symbols);
184
        else
185
          init_field_sync_2 (&field_sync, d_saved_symbols);
186
187
        // note that index doesn't advance in this branch
188
        out[outdex] = field_sync;
189
        d_already_output_field_sync = true;
190
      }
191
      else {
192
        // already output field sync, now output first regular segment
193
        out[outdex] = in[index];
194
        index++;
195
        d_already_output_field_sync = false;
196
      }
197
    }
198
  }
199
200
  d_current_index += index;
201
202
  return noutput_items;
203
}