3 * Copyright 2005 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.
27 #include <gr_lms_dfe_cc.h>
28 #include <gr_io_signature.h>
33 gr_lms_dfe_cc::slicer_0deg (gr_complex sample)
36 if(fabs(real(sample))>fabs(imag(sample))) {
38 out = gr_complex(1,0);
40 out = gr_complex(-1,0);
44 out = gr_complex(0,1);
46 out = gr_complex(0,-1);
52 gr_lms_dfe_cc::slicer_45deg (gr_complex sample)
56 out = gr_complex(1,0);
58 out = gr_complex(-1,0);
60 out += gr_complex(0,1);
62 out += gr_complex(0,-1);
67 gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb,
68 unsigned int num_fftaps, unsigned int num_fbtaps)
70 return gr_lms_dfe_cc_sptr (new gr_lms_dfe_cc (lambda_ff, lambda_fb,
71 num_fftaps, num_fbtaps));
74 gr_lms_dfe_cc::gr_lms_dfe_cc (float lambda_ff, float lambda_fb ,
75 unsigned int num_fftaps, unsigned int num_fbtaps)
76 : gr_sync_block ("lms_dfe_cc",
77 gr_make_io_signature (1, 1, sizeof (gr_complex)),
78 gr_make_io_signature (1, 1, sizeof (gr_complex))),
79 d_lambda_ff (lambda_ff), d_lambda_fb (lambda_fb),
80 d_ff_delayline(gr_rounduppow2(num_fftaps)),
81 d_fb_delayline(gr_rounduppow2(num_fbtaps)),
82 d_ff_taps(num_fftaps),d_fb_taps(num_fbtaps),
83 d_ff_index(0), d_fb_index(0)
85 gr_zero_vector(d_ff_taps);
86 d_ff_taps [d_ff_taps.size()/2] = 1;
88 gr_zero_vector(d_fb_taps);
89 gr_zero_vector(d_ff_delayline);
90 gr_zero_vector(d_fb_delayline);
94 gr_lms_dfe_cc::work (int noutput_items,
95 gr_vector_const_void_star &input_items,
96 gr_vector_void_star &output_items)
98 const gr_complex *iptr = (const gr_complex *) input_items[0];
99 gr_complex *optr = (gr_complex *) output_items[0];
101 gr_complex acc, decision, error;
104 unsigned int ff_mask = d_ff_delayline.size() - 1; // size is power of 2
105 unsigned int fb_mask = d_fb_delayline.size() - 1;
107 int size = noutput_items;
110 d_ff_delayline[d_ff_index] = *iptr++;
113 for (i=0; i < d_ff_taps.size(); i++)
114 acc += conj(d_ff_delayline[(i+d_ff_index) & ff_mask]) * d_ff_taps[i];
116 for (i=0; i < d_fb_taps.size(); i++)
117 acc -= conj(d_fb_delayline[(i+d_fb_index) & fb_mask]) * d_fb_taps[i];
119 decision = slicer_45deg(acc);
120 error = decision - acc;
123 for (i=0; i < d_ff_taps.size(); i++)
124 d_ff_taps[i] += d_lambda_ff * conj(error) * d_ff_delayline[(i+d_ff_index) & ff_mask];
126 for (i=0; i < d_fb_taps.size(); i++)
127 d_fb_taps[i] -= d_lambda_fb * conj(error) * d_fb_delayline[(i+d_fb_index) & fb_mask];
129 d_fb_index = (d_fb_index - 1) & fb_mask; // Decrement index
130 d_ff_index = (d_ff_index - 1) & ff_mask; // Decrement index
132 d_fb_delayline[d_fb_index] = decision; // Save decision in feedback
134 *optr++ = acc; // Output decision
138 std::cout << "FF Taps\t";
139 for(i=0;i<d_ff_taps.size();i++)
140 std::cout << d_ff_taps[i] << "\t";
141 std::cout << std::endl << "FB Taps\t";
142 for(i=0;i<d_fb_taps.size();i++)
143 std::cout << d_fb_taps[i] << "\t";
144 std::cout << std::endl;
147 return noutput_items;