Merge branch 'dfsg-orig'
[debian/gnuradio] / gr-atsc / src / lib / GrAtscEqualizer.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2002 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 #include <GrAtscEqualizer.h>
24 #include <atsci_equalizer.h>
25
26 // typedefs for fundamental i/o types
27
28 typedef float           dataType;
29 typedef atsc::syminfo   tagType;
30
31 static const int NUMBER_OF_OUTPUTS = 2; // # of output streams 
32
33
34 GrAtscEqualizer::GrAtscEqualizer (atsci_equalizer *equalizer)
35   : VrHistoryProc<dataType,dataType> (NUMBER_OF_OUTPUTS)
36 {
37   // due to limitation of runtime, all inputs must be the same size
38   assert (sizeof (dataType) == sizeof (tagType));
39   
40   d_equalizer = equalizer;
41
42   // 1 + number of extra input elements at which we look.  This is
43   // used by the superclass's forecast routine to get us the correct
44   // range on our inputs.
45   //
46   // Set this to the answer returned by the equalizer primitive we were passed.
47   history = d_equalizer->ntaps ();
48 }
49
50 GrAtscEqualizer::~GrAtscEqualizer ()
51 {
52   // Anything that isn't automatically cleaned up...
53
54   delete d_equalizer;
55 }
56
57
58 /*
59  * non-standard forecast routine that handles getting the correct amount of
60  * history for the data input as well as ensuring correct alignment of
61  * the data and tags.
62  */
63
64 int
65 GrAtscEqualizer::forecast (VrSampleRange output,
66                            VrSampleRange inputs[]) 
67 {
68   assert (numberInputs == 2);
69   
70   int ntaps = d_equalizer->ntaps ();
71   int npretaps = d_equalizer->npretaps ();
72   
73   assert (ntaps >= 1);
74   assert (npretaps >= 0 && npretaps < ntaps);
75   
76   inputs[0].index = output.index;               // the equalizer data
77   inputs[0].size  = output.size + ntaps - 1;    // history on data
78   
79   // FIXME if there's a problem, it's probably on the next line...
80   int offset = ntaps - npretaps - 1;
81
82   assert (offset >= 0 && offset < ntaps);
83
84   inputs[1].index = output.index + offset;      // align equalizer tags
85   inputs[1].size = output.size;                 // N.B., no extra history on tags
86
87   return 0;
88 }  
89
90 /*
91  * This is the real work horse.  We consume 2 input streams
92  * and produce 2 output streams.
93  */
94
95 int 
96 GrAtscEqualizer::work (VrSampleRange output, void *ao[],
97                        VrSampleRange inputs[], void *ai[])
98 {
99   // assert (numberInputs == 2);
100   
101   // If we have state that persists across invocations (e.g., we have
102   // instance variables that we modify), we must use the sync method
103   // to indicate to the scheduler that our output must be computed in
104   // order.  This doesn't keep other things from being run in
105   // parallel, it just means that at any given time, there is only a
106   // single thread working this code, and that the scheduler will
107   // ensure that we are asked to produce output that is contiguous and
108   // that will be presented to us in order of increasing time.
109
110   // We have state, hence we must use sync.
111
112   sync (output.index);
113
114   // construct some nicer i/o pointers to work with.
115
116   dataType *input_samples  = ((dataType **) ai)[0];
117   tagType  *input_tags     = ((tagType **)  ai)[1];
118   dataType *output_samples = ((dataType **) ao)[0];
119   tagType  *output_tags    = ((tagType **)  ao)[1];
120
121
122   // peform the actual equalization
123
124   d_equalizer->filter (input_samples, input_tags,
125                        output_samples, output.size);
126
127   // write the output tags
128
129   for (unsigned int i = 0; i < output.size; i++)
130     output_tags[i] = input_tags[i];
131
132   // Return the number of units we produced.
133
134   return output.size;
135 }