summaryrefslogtreecommitdiff
path: root/gr-dtv/lib/dvbt/dvbt_demod_reference_signals_impl.cc
blob: 606221e23875f78fea159448c4d43579111b3899 (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* -*- c++ -*- */
/*
 * Copyright 2015 Free Software Foundation, Inc.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "dvbt_demod_reference_signals_impl.h"
#include <gnuradio/io_signature.h>

namespace gr {
namespace dtv {

dvbt_demod_reference_signals::sptr
dvbt_demod_reference_signals::make(int itemsize,
                                   int ninput,
                                   int noutput,
                                   dvb_constellation_t constellation,
                                   dvbt_hierarchy_t hierarchy,
                                   dvb_code_rate_t code_rate_HP,
                                   dvb_code_rate_t code_rate_LP,
                                   dvb_guardinterval_t guard_interval,
                                   dvbt_transmission_mode_t transmission_mode,
                                   int include_cell_id,
                                   int cell_id)
{
    return gnuradio::make_block_sptr<dvbt_demod_reference_signals_impl>(itemsize,
                                                                        ninput,
                                                                        noutput,
                                                                        constellation,
                                                                        hierarchy,
                                                                        code_rate_HP,
                                                                        code_rate_LP,
                                                                        guard_interval,
                                                                        transmission_mode,
                                                                        include_cell_id,
                                                                        cell_id);
}

/*
 * The private constructor
 */
dvbt_demod_reference_signals_impl::dvbt_demod_reference_signals_impl(
    int itemsize,
    int ninput,
    int noutput,
    dvb_constellation_t constellation,
    dvbt_hierarchy_t hierarchy,
    dvb_code_rate_t code_rate_HP,
    dvb_code_rate_t code_rate_LP,
    dvb_guardinterval_t guard_interval,
    dvbt_transmission_mode_t transmission_mode,
    int include_cell_id,
    int cell_id)
    : block("dvbt_demod_reference_signals",
            io_signature::make(1, 1, itemsize * ninput),
            io_signature::make(1, 1, itemsize * noutput)),
      config(constellation,
             hierarchy,
             code_rate_HP,
             code_rate_LP,
             guard_interval,
             transmission_mode,
             include_cell_id,
             cell_id),
      d_pg(config),
      d_init(0),
      d_fi_start(0)
{
    d_ninput = ninput;
    d_noutput = noutput;

    // TODO - investigate why this is happening
    if ((config.d_constellation == MOD_64QAM) && (config.d_transmission_mode == T8k))
        d_fi_start = 2;
    else
        d_fi_start = 3;
}

/*
 * Our virtual destructor.
 */
dvbt_demod_reference_signals_impl::~dvbt_demod_reference_signals_impl() {}

void dvbt_demod_reference_signals_impl::forecast(int noutput_items,
                                                 gr_vector_int& ninput_items_required)
{
    int ninputs = ninput_items_required.size();

    for (int i = 0; i < ninputs; i++)
        ninput_items_required[i] = 2 * noutput_items;
}

int dvbt_demod_reference_signals_impl::is_sync_start(int nitems)
{
    std::vector<tag_t> tags;
    const uint64_t nread = this->nitems_read(0); // number of items read on port 0
    this->get_tags_in_range(
        tags, 0, nread, nread + nitems, pmt::string_to_symbol("sync_start"));

    return !tags.empty() ? 1 : 0;
}

int dvbt_demod_reference_signals_impl::general_work(
    int noutput_items,
    gr_vector_int& ninput_items,
    gr_vector_const_void_star& input_items,
    gr_vector_void_star& output_items)
{
    const gr_complex* in = (const gr_complex*)input_items[0];
    gr_complex* out = (gr_complex*)output_items[0];

    int symbol_index = 0;
    int frame_index = 0;
    int to_out = 0;

    for (int i = 0; i < noutput_items; i++) {
        to_out += d_pg.parse_input(
            &in[i * d_ninput], &out[i * d_noutput], &symbol_index, &frame_index);
    }

    /*
     * Wait for a sync_start tag from upstream that signals when to start.
     * Always consume until to a superframe start.
     */
    if (is_sync_start(noutput_items)) {
        d_init = 0;
    }

    if (d_init == 0) {
        // This is super-frame start
        if (((symbol_index % 68) == 0) && ((frame_index % 4) == d_fi_start)) {
            d_init = 1;

            const uint64_t offset = this->nitems_written(0);
            pmt::pmt_t key = pmt::string_to_symbol("superframe_start");
            pmt::pmt_t value = pmt::from_long(0xaa);
            this->add_item_tag(0, offset, key, value);
        } else {
            consume_each(1);
            return (0);
        }
    }

    // Send a tag for each OFDM symbol informing about
    // symbol index.
    const uint64_t offset = this->nitems_written(0);
    pmt::pmt_t key = pmt::string_to_symbol("symbol_index");
    pmt::pmt_t value = pmt::from_long(symbol_index);
    this->add_item_tag(0, offset, key, value);

    // Consume from input stream
    consume_each(noutput_items);

    // Tell runtime system how many output items we produced.
    return to_out;
}

} /* namespace dtv */
} /* namespace gr */