Revision c7dbfcc7 gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc

b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
1 1
/* -*- c++ -*- */
2 2
/*
3
 * Copyright 2006 Free Software Foundation, Inc.
3
 * Copyright 2007 Free Software Foundation, Inc.
4 4
 * 
5 5
 * This file is part of GNU Radio
6 6
 * 
......
29 29
#include <vector>
30 30

31 31
gr_ofdm_bpsk_mapper_sptr
32
gr_make_ofdm_bpsk_mapper (unsigned int mtu, unsigned int occupied_carriers, unsigned int vlen,
33
			  std::vector<gr_complex> known_symbol1, std::vector<gr_complex> known_symbol2)
32
gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit, 
33
			  unsigned int occupied_carriers, unsigned int fft_length,
34
			  const std::vector<gr_complex> &known_symbol1, 
35
			  const std::vector<gr_complex> &known_symbol2)
34 36
{
35
  return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (mtu, occupied_carriers, vlen, 
37
  return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length, 
36 38
							    known_symbol1, known_symbol2));
37 39
}
38 40

39
gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int mtu, unsigned int occupied_carriers, unsigned int vlen,
40
					  std::vector<gr_complex> known_symbol1, 
41
					  std::vector<gr_complex> known_symbol2)
42
  : gr_block ("ofdm_bpsk_mapper",
43
	      gr_make_io_signature (1, 1, 2*sizeof(int) + sizeof(unsigned char)*mtu),
44
	      gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen)),
45
    d_mtu(mtu),
41
// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
42
gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int msgq_limit, 
43
					  unsigned int occupied_carriers, unsigned int fft_length,
44
					  const std::vector<gr_complex> &known_symbol1, 
45
					  const std::vector<gr_complex> &known_symbol2)
46
  : gr_sync_block ("ofdm_bpsk_mapper",
47
		   gr_make_io_signature (0, 0, 0),
48
		   gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))),
49
    d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false),
46 50
    d_occupied_carriers(occupied_carriers),
47
    d_vlen(vlen),
48
    d_packet_offset(0),
51
    d_fft_length(fft_length),
49 52
    d_bit_offset(0),
50 53
    d_header_sent(0),
51 54
    d_known_symbol1(known_symbol1),
52 55
    d_known_symbol2(known_symbol2)
53

54 56
{
55
  assert(d_occupied_carriers < d_vlen);
57
  assert(d_occupied_carriers <= d_fft_length);
56 58
  assert(d_occupied_carriers == d_known_symbol1.size());
57 59
  assert(d_occupied_carriers == d_known_symbol2.size());
58 60
}
......
61 63
{
62 64
}
63 65

64
void
65
gr_ofdm_bpsk_mapper::forecast (int noutput_items, gr_vector_int &ninput_items_required)
66
float randombit()
66 67
{
67
  unsigned ninputs = ninput_items_required.size ();
68
  for (unsigned i = 0; i < ninputs; i++)
69
    ninput_items_required[i] = 1;
68
  int r = rand()&1;
69
  return (float)(-1 + 2*r);
70 70
}
71 71

72 72
int
73
gr_ofdm_bpsk_mapper::general_work(int noutput_items,
74
				  gr_vector_int &ninput_items,
75
				  gr_vector_const_void_star &input_items,
76
				  gr_vector_void_star &output_items)
73
gr_ofdm_bpsk_mapper::work(int noutput_items,
74
			  gr_vector_const_void_star &input_items,
75
			  gr_vector_void_star &output_items)
77 76
{
78
  const gr_frame *in = (const gr_frame *) input_items[0];
79 77
  gr_complex *out = (gr_complex *)output_items[0];
80 78
  
81 79
  unsigned int i=0;
82
  unsigned int num_symbols = 0, pkt_length;
80
  unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
81
  unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
83 82

84 83
  //printf("OFDM BPSK Mapper:  ninput_items: %d   noutput_items: %d\n", ninput_items[0], noutput_items);
85 84

86
  pkt_length = in[0].length;
87

88
  std::vector<gr_complex>::iterator ks_itr;
89
  if(d_header_sent == 0) {
90
     ks_itr = d_known_symbol1.begin();
91
  }
92
  else if(d_header_sent == 1) {
93
    ks_itr = d_known_symbol2.begin();
85
  if(d_eof) {
86
    return -1;
94 87
  }
95 88
  
96
  if(d_header_sent < 2) {
97
    //  Add training symbols here
98
    for(i=0; i < (ceil((d_vlen - d_occupied_carriers)/2.0)); i++) {
99
      out[i] = gr_complex(0,0);
89
  if(!d_msg) {
90
    d_msg = d_msgq->delete_head();	   // block, waiting for a message
91
    d_msg_offset = 0;
92
    d_bit_offset = 0;
93
    d_header_sent = 0;
94
    
95
    if((d_msg->length() == 0) && (d_msg->type() == 1)) {
96
      d_msg.reset();
97
      return -1;
100 98
    }
101
    for(;i<d_vlen - ceil((d_vlen-d_occupied_carriers)/2.0);i++) {
102
      //out[i] = gr_complex(1,0);
103
      out[i] = *(ks_itr++);
99
  }
100

101
  if(output_items.size() == 2) {
102
    char *sig = (char *)output_items[1];
103
    if(d_header_sent == 1) {
104
      sig[0] = 1;
104 105
    }
105
    for(; i < d_vlen; i++) {
106
      out[i] = gr_complex(0,0);
106
    else {
107
      sig[0] = 0;
107 108
    }
108

109
    num_symbols = 1;
110
    out += d_vlen;
111
    d_header_sent++;
112 109
  }
113 110
  
114
  unsigned int unoccupied_carriers = d_vlen - d_occupied_carriers;
115
  unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
116
  unsigned int zeros_on_right = unoccupied_carriers - zeros_on_left;
111
  // Build a single symbol:
117 112

118
  while(num_symbols < (unsigned)noutput_items) {
113
  // Initialize all bins to 0 to set unused carriers
114
  memset(out, 0, d_fft_length*sizeof(gr_complex));
115
  
116
  if(d_header_sent == 0) {
117
     for(i=0; i < d_occupied_carriers; i++) {
118
       out[i+zeros_on_left] = d_known_symbol1[i];
119
     }
120
    d_header_sent++;
119 121

120
    // stick in unused carriers
121
    for(i = d_vlen-zeros_on_right; i < d_vlen; i++) {
122
      out[i] = gr_complex(0,0);
122
    return 1;
123
  }
124
  
125
  if(d_header_sent == 1) {
126
    for(i=0; i < d_occupied_carriers; i++) {
127
      out[i+zeros_on_left] = d_known_symbol2[i];
123 128
    }
129
    d_header_sent++;
124 130

125
    for(i=0; i < zeros_on_left; i++) {
126
      out[i] = gr_complex(0,0);
127
    }
131
    return 1;
132
  }
128 133

129
    while((d_packet_offset < pkt_length) && (i < d_vlen-zeros_on_right)) {
130
      unsigned char bit = (in[0].data[d_packet_offset] >> (d_bit_offset++)) & 0x01;
131
      out[i++] = gr_complex(-1+2*(bit));
132
      if(d_bit_offset == 8) {
133
	d_bit_offset = 0;
134
	d_packet_offset++;
135
      }
134
  i = 0;
135
  while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
136
    unsigned char bit = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
137
    out[i + zeros_on_left] = gr_complex(-1+2*(bit));
138
    i++;
139
    d_bit_offset++;
140
    if(d_bit_offset == 8) {
141
      d_bit_offset = 0;
142
      d_msg_offset++;
136 143
    }
144
  }
137 145

138
    // Ran out of data to put in symbols
139
    if(d_packet_offset == pkt_length) {
140
      while(i < d_vlen-zeros_on_right) {
141
	out[i++] = gr_complex(0,0);
142
      }
143

144
      d_packet_offset = 0;
145
      assert(d_bit_offset == 0);
146
      num_symbols++;
147
      d_header_sent = 0;
148
      consume_each(1);
149
      return num_symbols;
146
  // Ran out of data to put in symbol
147
  if (d_msg_offset == d_msg->length()) {
148
    while(i < d_occupied_carriers) {   // finish filling out the symbol
149
      out[i + zeros_on_left] = gr_complex(randombit(),0);
150
      i++;
150 151
    }
151
    
152
    // Ran out of space in symbol
153
    out += d_vlen;
154
    num_symbols++;
152

153
    if (d_msg->type() == 1)	           // type == 1 sets EOF
154
      d_eof = true;
155
    d_msg.reset();   // finished packet, free message
156
 
157
    assert(d_bit_offset == 0);
158
    return 1;          // produced one symbol
155 159
  }
156
  consume_each(0);
157
  return num_symbols;
160
  
161
  return 1;  // produced symbol
158 162
}
159 163

Also available in: Unified diff