Fix typo in variable name (Firas Abbas)
[debian/gnuradio] / gnuradio-core / src / lib / general / gr_ofdm_bpsk_mapper.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2007 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 <gr_ofdm_bpsk_mapper.h>
28 #include <gr_io_signature.h>
29 #include <stdexcept>
30 #include <string.h>
31
32 gr_ofdm_bpsk_mapper_sptr
33 gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit, 
34                           unsigned int occupied_carriers, unsigned int fft_length)
35 {
36   return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length));
37 }
38
39 // Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
40 gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int msgq_limit, 
41                                           unsigned int occupied_carriers, unsigned int fft_length)
42   : gr_sync_block ("ofdm_bpsk_mapper",
43                    gr_make_io_signature (0, 0, 0),
44                    gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))),
45     d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false),
46     d_occupied_carriers(occupied_carriers),
47     d_fft_length(fft_length),
48     d_bit_offset(0),
49     d_pending_flag(0)
50 {
51   if (!(d_occupied_carriers <= d_fft_length))
52     throw std::invalid_argument("gr_ofdm_bpsk_mapper: occupied carriers must be <= fft_length");
53 }
54
55 gr_ofdm_bpsk_mapper::~gr_ofdm_bpsk_mapper(void)
56 {
57 }
58
59 static float
60 randombit()
61 {
62   int r = rand()&1;
63   return (float)(1 - 2*r);
64 }
65
66 int
67 gr_ofdm_bpsk_mapper::work(int noutput_items,
68                           gr_vector_const_void_star &input_items,
69                           gr_vector_void_star &output_items)
70 {
71   gr_complex *out = (gr_complex *)output_items[0];
72   
73   unsigned int i=0;
74   unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
75   unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
76
77   //printf("OFDM BPSK Mapper:  ninput_items: %d   noutput_items: %d\n", ninput_items[0], noutput_items);
78
79   if(d_eof) {
80     return -1;
81   }
82   
83   if(!d_msg) {
84     d_msg = d_msgq->delete_head();         // block, waiting for a message
85     d_msg_offset = 0;
86     d_bit_offset = 0;
87     d_pending_flag = 1;                    // new packet, write start of packet flag
88     
89     if((d_msg->length() == 0) && (d_msg->type() == 1)) {
90       d_msg.reset();
91       return -1;                // We're done; no more messages coming.
92     }
93   }
94
95   char *out_flag = 0;
96   if(output_items.size() == 2)
97     out_flag = (char *) output_items[1];
98   
99
100   // Build a single symbol:
101   
102
103   // Initialize all bins to 0 to set unused carriers
104   memset(out, 0, d_fft_length*sizeof(gr_complex));
105   
106   i = 0;
107   while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
108     unsigned char bit = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
109     out[i + zeros_on_left] = gr_complex(1-2*(bit));
110     i++;
111     d_bit_offset++;
112     if(d_bit_offset == 8) {
113       d_bit_offset = 0;
114       d_msg_offset++;
115     }
116   }
117
118   // Ran out of data to put in symbol
119   if (d_msg_offset == d_msg->length()) {
120     while(i < d_occupied_carriers) {   // finish filling out the symbol
121       out[i + zeros_on_left] = gr_complex(randombit(),0);
122       i++;
123     }
124
125     if (d_msg->type() == 1)             // type == 1 sets EOF
126       d_eof = true;
127     d_msg.reset();                      // finished packet, free message
128     assert(d_bit_offset == 0);
129   }
130
131   if (out_flag)
132     out_flag[0] = d_pending_flag;
133   d_pending_flag = 0;
134
135   return 1;  // produced symbol
136 }
137