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