Statistics
| Branch: | Tag: | Revision:

root / gnuradio-core / src / lib / general / gr_lms_dfe_ff.cc @ 5d69a524

History | View | Annotate | Download (3.5 kB)

1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2005 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 2, 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., 59 Temple Place - Suite 330,
20
 * Boston, MA 02111-1307, USA.
21
 */
22
23
#ifdef HAVE_CONFIG_H
24
#include "config.h"
25
#endif
26
27
#include <gr_lms_dfe_ff.h>
28
#include <gr_io_signature.h>
29
#include <gr_misc.h>
30
#include <iostream>
31
32
float
33
slice(float val)
34
{
35
  if (val>0)
36
    return 1;
37
  else
38
    return -1;
39
}
40
41
gr_lms_dfe_ff_sptr
42
gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb, 
43
                    unsigned int num_fftaps, unsigned int num_fbtaps)
44
{
45
  return gr_lms_dfe_ff_sptr (new gr_lms_dfe_ff (lambda_ff,lambda_fb,num_fftaps,num_fbtaps));
46
}
47
48
gr_lms_dfe_ff::gr_lms_dfe_ff (float lambda_ff, float lambda_fb , 
49
                              unsigned int num_fftaps, unsigned int num_fbtaps)
50
  : gr_sync_block ("lms_dfe_ff",
51
                   gr_make_io_signature (1, 1, sizeof (float)),
52
                   gr_make_io_signature (1, 1, sizeof (float))),
53
    d_lambda_ff (lambda_ff), d_lambda_fb (lambda_fb), 
54
    d_ff_delayline(gr_rounduppow2(num_fftaps)),
55
    d_fb_delayline(gr_rounduppow2(num_fbtaps)),
56
    d_ff_taps(num_fftaps), d_fb_taps(num_fbtaps),
57
    d_ff_index(0), d_fb_index(0)
58
{
59
  gr_zero_vector(d_ff_taps);
60
  d_ff_taps [d_ff_taps.size()/2] = 1;
61
62
  gr_zero_vector(d_fb_taps);
63
  gr_zero_vector(d_ff_delayline);
64
  gr_zero_vector(d_fb_delayline);
65
}
66
67
int
68
gr_lms_dfe_ff::work (int noutput_items,
69
                   gr_vector_const_void_star &input_items,
70
                   gr_vector_void_star &output_items)
71
{
72
  const float *iptr = (const float *) input_items[0];
73
  float *optr = (float *) output_items[0];
74
  
75
  float acc, decision, error;
76
  unsigned int i;
77
78
  unsigned int ff_mask = d_ff_delayline.size() - 1;        // size is power of 2
79
  unsigned int fb_mask = d_fb_delayline.size() - 1;
80
81
  int        size = noutput_items;
82
  while(size-- > 0) {
83
    acc = 0; 
84
    d_ff_delayline[d_ff_index] = *iptr++;
85
86
    // Compute output
87
    for (i=0; i < d_ff_taps.size(); i++) 
88
      acc += d_ff_delayline[(i+d_ff_index) & ff_mask] * d_ff_taps[i];
89
    
90
    for (i=0; i < d_fb_taps.size(); i++)
91
      acc -= d_fb_delayline[(i+d_fb_index) & fb_mask] * d_fb_taps[i];
92
93
    decision = slice(acc);
94
    error = decision - acc;
95
    
96
    // Update taps
97
    for (i=0; i < d_ff_taps.size(); i++)
98
      d_ff_taps[i] += d_lambda_ff * error * d_ff_delayline[(i+d_ff_index) & ff_mask];
99
    
100
    for (i=0; i < d_fb_taps.size(); i++)
101
      d_fb_taps[i] -= d_lambda_fb * error * d_fb_delayline[(i+d_fb_index) & fb_mask];
102
    
103
    d_fb_index = (d_fb_index - 1) & fb_mask;           // Decrement index
104
    d_ff_index = (d_ff_index - 1) & ff_mask;           // Decrement index
105
106
    d_fb_delayline[d_fb_index] = decision;         // Save decision in feedback
107
108
    *optr++ = acc;   // Output decision
109
  }
110
111
  if (0){
112
    std::cout << "FF Taps\t";
113
    for(i=0;i<d_ff_taps.size();i++)
114
      std::cout << d_ff_taps[i] << "\t";
115
    std::cout << std::endl << "FB Taps\t";
116
    for(i=0;i<d_fb_taps.size();i++)
117
      std::cout << d_fb_taps[i] << "\t";
118
    std::cout << std::endl;
119
  }
120
121
  return noutput_items;
122
}