3 * Copyright 2006,2007 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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)
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.
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.
28 #include <gr_ofdm_mapper_bcv.h>
29 #include <gr_io_signature.h>
32 gr_ofdm_mapper_bcv_sptr
33 gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned int msgq_limit,
34 unsigned int occupied_carriers, unsigned int fft_length)
36 return gr_ofdm_mapper_bcv_sptr (new gr_ofdm_mapper_bcv (constellation, msgq_limit,
37 occupied_carriers, fft_length));
40 // Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
41 gr_ofdm_mapper_bcv::gr_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned int msgq_limit,
42 unsigned int occupied_carriers, unsigned int fft_length)
43 : gr_sync_block ("ofdm_mapper_bcv",
44 gr_make_io_signature (0, 0, 0),
45 gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))),
46 d_constellation(constellation),
47 d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false),
48 d_occupied_carriers(occupied_carriers),
49 d_fft_length(fft_length),
55 if (!(d_occupied_carriers <= d_fft_length))
56 throw std::invalid_argument("gr_ofdm_mapper_bcv: occupied carriers must be <= fft_length");
58 d_nbits = (unsigned long)ceil(log10(d_constellation.size()) / log10(2.0));
61 gr_ofdm_mapper_bcv::~gr_ofdm_mapper_bcv(void)
65 int gr_ofdm_mapper_bcv::randsym()
67 return (rand() % d_constellation.size());
71 gr_ofdm_mapper_bcv::work(int noutput_items,
72 gr_vector_const_void_star &input_items,
73 gr_vector_void_star &output_items)
75 gr_complex *out = (gr_complex *)output_items[0];
78 unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
79 unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
81 //printf("OFDM BPSK Mapper: ninput_items: %d noutput_items: %d\n", ninput_items[0], noutput_items);
88 d_msg = d_msgq->delete_head(); // block, waiting for a message
91 d_pending_flag = 1; // new packet, write start of packet flag
93 if((d_msg->length() == 0) && (d_msg->type() == 1)) {
95 return -1; // We're done; no more messages coming.
100 if(output_items.size() == 2)
101 out_flag = (char *) output_items[1];
104 // Build a single symbol:
105 // Initialize all bins to 0 to set unused carriers
106 memset(out, 0, d_fft_length*sizeof(gr_complex));
109 unsigned char bits = 0;
110 while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
112 // need new data to process
113 if(d_bit_offset == 0) {
114 d_msgbytes = d_msg->msg()[d_msg_offset];
115 //printf("mod message byte: %x\n", d_msgbytes);
119 d_resid |= (((1 << d_nresid)-1) & d_msgbytes) << (d_nbits - d_nresid);
122 out[i + zeros_on_left] = d_constellation[bits];
125 d_bit_offset += d_nresid;
128 //printf("mod bit(r): %x resid: %x nresid: %d bit_offset: %d\n",
129 // bits, d_resid, d_nresid, d_bit_offset);
132 if((8 - d_bit_offset) >= d_nbits) {
133 bits = ((1 << d_nbits)-1) & (d_msgbytes >> d_bit_offset);
134 d_bit_offset += d_nbits;
136 out[i + zeros_on_left] = d_constellation[bits];
140 printf("mod bit: %x out: %.4f + j%.4f resid: %x nresid: %d bit_offset: %d\n",
141 bits, out[i-1 + zeros_on_left].real(), out[i-1 + zeros_on_left].imag(),
142 d_resid, d_nresid, d_bit_offset);
146 unsigned int extra = 8-d_bit_offset;
147 d_resid = ((1 << extra)-1) & (d_msgbytes >> d_bit_offset);
148 d_bit_offset += extra;
149 d_nresid = d_nbits - extra;
154 if(d_bit_offset == 8) {
160 // Ran out of data to put in symbol
161 if (d_msg_offset == d_msg->length()) {
169 while(i < d_occupied_carriers) { // finish filling out the symbol
170 out[i + zeros_on_left] = d_constellation[randsym()];
174 if (d_msg->type() == 1) // type == 1 sets EOF
176 d_msg.reset(); // finished packet, free message
177 assert(d_bit_offset == 0);
181 out_flag[0] = d_pending_flag;
184 return 1; // produced symbol