root/ossiedev/branches/mcarrick/ossiedev-trunk/components/Decimator/Decimator.cpp @ 9125

Revision 9125, 11.1 KB (checked in by mcarrick, 4 years ago)

pulling audio device, sig proc, decimator updates from trunk

  • Property svn:eol-style set to native
Line 
1/****************************************************************************
2
3Copyright 2005,2006 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Decimator.
6
7OSSIE Decimator is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12OSSIE Decimator is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OSSIE Decimator; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21
22****************************************************************************/
23
24#include <iostream>
25
26#include <string.h>
27#include <math.h>  // For energy debugging routine
28#include "ossie/cf.h"
29
30#include "Decimator.h"
31
32    //#define PRINT_ENERGY 1
33
34Decimator_i::Decimator_i(const char *uuid, omni_condition *condition) :
35    Resource_impl(uuid),
36    component_running(condition),
37    calculateFilterCoefficients(true),
38    M(1),
39    sample_count(0),
40    previous_length(0){
41   
42   
43    // Create the port for output data
44    dataOut = new standardInterfaces_i::complexShort_u("outData");
45
46    // Create port for input Data
47    dataIn = new standardInterfaces_i::complexShort_p("inData");
48
49    // Start the run_decimation thread
50    processing_thread = new omni_thread(do_run_decimation, (void *) this);
51    processing_thread->start();
52
53    filter_type=FIR;
54    // Filter length is L
55    len_h = 1;
56    h = new float[len_h];
57
58    h[0] = 1.0;
59
60    fir_i_filter = new SigProc::fir_filter(h, len_h);
61    fir_q_filter = new SigProc::fir_filter(h, len_h);
62    iir_i_filter = NULL;
63    iir_q_filter = NULL;
64
65    //outFile = new std::ofstream("decimator_out.dat");
66}
67
68void Decimator_i::start() throw (CF::Resource::StartError, CORBA::SystemException)
69
70{
71    std::cout << "Start Decimator called" << std::endl;
72
73}
74
75void Decimator_i::stop() throw (CF::Resource::StopError, CORBA::SystemException)
76
77{
78    std::cout << "Stop decimator called" << std::endl;
79
80}
81
82CORBA::Object_ptr Decimator_i::getPort(const char* portName) throw(CF::PortSupplier::UnknownPort, CORBA::SystemException)
83
84{
85    std::cout << "Decimator getPort called with : " << portName << std::endl;
86
87    CORBA::Object_var p;
88
89    p = dataOut->getPort(portName);
90
91    if (!CORBA::is_nil(p))
92        return p._retn();
93
94    p = dataIn->getPort(portName);
95
96    if (!CORBA::is_nil(p))
97        return p._retn();
98
99    throw CF::PortSupplier::UnknownPort();
100}
101
102void Decimator_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemException)
103
104{
105    std::cout << "Decimator Initialize called" << std::endl;
106
107}
108
109void Decimator_i::configure(const CF::Properties& props) throw (CORBA::SystemException, CF::PropertySet::InvalidConfiguration, CF::PropertySet::PartialConfiguration)
110
111{
112    std::cout << "decimator Configure called" << std::endl;
113
114    std::cout << "Props length : " << props.length() << std::endl;
115
116    for (unsigned int i = 0; i < props.length(); i++) {
117        std::cout << "Property id : " << props[i].id << std::endl;
118       
119        // DecimateBy property, sets the decimator factor
120        if (strcmp(props[i].id, "DCE:cea26b54-9d86-4b68-a761-14186efa9415") == 0) {
121            CORBA::UShort D;
122            props[i].value >>= D;
123            M = D;
124            std::cout << "Decimation factor set to " << M << std::endl;
125
126        } else if (strcmp(props[i].id, "DCE:134e5dd8-c773-47af-a557-2837076358c4") == 0) {
127            // filter property, Filter coefficients
128            CORBA::FloatSeq *coeff_ptr;
129            props[i].value >>= coeff_ptr;
130
131            len_h = coeff_ptr->length();
132           
133            if (len_h < 2) {
134                calculateFilterCoefficients = true;
135            } else {
136                calculateFilterCoefficients = false;
137
138                delete []h;
139                delete_filter_variables();
140
141                h = new float[len_h];
142                std::cout << "Decimator filter length = " << len_h << std::endl;
143                for (unsigned int k = 0; k < len_h; k++) {
144                    h[k] = (*coeff_ptr)[k];
145                    DEBUG(3, Decimator, "Coeff[" << k << "] = " << h[k])
146                }
147                fir_i_filter = new SigProc::fir_filter(h, len_h);
148                fir_q_filter = new SigProc::fir_filter(h, len_h);
149            }
150        } else if (strcmp(props[i].id, "DCE:537a42d9-2dd7-45b8-8dfb-f0999115ba71") == 0) {
151           const char * prop_str;
152            props[i].value >>= prop_str;
153            if ( strcmp(prop_str, "FIR") == 0 ) {
154               filter_type=FIR;
155               DEBUG(3, Decimator, "Filtertype set to FIR")
156            } else if ( strcmp(prop_str, "IIR") == 0 ){
157               filter_type=IIR;
158               DEBUG(3, Decimator, "Filtertype set to IIR")
159            } else {
160              std::cerr << "ERROR: Decimator::configure() unknown filter type" << std::endl;
161               throw CF::PropertySet::InvalidConfiguration();
162            };
163        } else {
164            std::cerr << "ERROR: Decimator::configure(): Unknown property "
165                      << props[i].id << std::endl;
166            throw CF::PropertySet::InvalidConfiguration();
167        }
168       
169    }
170   
171         
172         if (filter_type==FIR) {
173         
174                        if (calculateFilterCoefficients) {
175                        // calculate filter coefficients dynamically
176                        unsigned int m(2);      // filter delay (symbols)
177                        float beta(0.5f);       // excess bandwidth factor
178                        len_h = 2*2*M*m+1;      // filter length (samples)
179                        delete [] h;
180                        h = new float[len_h];
181                        SigProc::DesignRRCFilter(2*M, m, beta, h);
182
183                        // delete old filters
184                        delete_filter_variables();
185
186                        // print coefficients
187                        for (unsigned int k=0; k<len_h; k++)
188                            DEBUG(2, Decimator, " h[" << k << "] = " << h[k]);
189
190                        fir_i_filter = new SigProc::fir_filter(h, len_h);
191                        fir_q_filter = new SigProc::fir_filter(h, len_h);
192                        }
193               
194         } else {
195         
196         
197                       
198                        float *b_f;                ///< feedforward filter coefficients
199                        float *a_f;                ///< feedback filter coefficients
200                        unsigned int f_order;      ///< filter order
201                        // 10th-order Butterworth IIR filter, wc = (1/M)*pi rad,
202                        f_order = 10;
203                        b_f = new float[f_order+1];
204                        a_f = new float[f_order+1];
205                        // Delete old filters
206                        delete_filter_variables();
207                        SigProc::design_butter_lowpass_filter(f_order, 1.0/M, b_f, a_f);
208                        iir_i_filter = new SigProc::iir_filter(a_f, f_order+1, b_f, f_order+1);
209                        iir_q_filter = new SigProc::iir_filter(a_f, f_order+1, b_f, f_order+1);
210                        DEBUG(3, Decimator, "IIR Filter generated")
211                        delete b_f;
212                        delete a_f;
213         
214         }
215
216}
217void Decimator_i::releaseObject() throw (CF::LifeCycle::ReleaseError, CORBA::SystemException)
218
219{
220
221    std::cout << "decimator releaseObject called" << std::endl;
222
223    delete outFile;
224
225    // Clear the component running semaphore so main shuts down everything
226    component_running->signal();
227}
228
229void Decimator_i::run_decimation()
230{
231    std::cout << "run_decimation thread started" << std::endl;
232
233/**
234#ifdef LOG_DATA
235    dump_data pre_decim("pre.dat", 1000, 1000);
236    dump_data post_decim("post.dat", 1000, 1000);
237#endif
238**/
239   
240    unsigned int len=1024;
241    unsigned int len_out=1024;
242    PortTypes::ShortSequence I_out, Q_out;
243    short * I_buf = new short[len];
244    short * Q_buf = new short[len];
245    bool output_sample(false);
246
247    while (1) {
248        PortTypes::ShortSequence *I_in(NULL), *Q_in(NULL);
249
250
251        dataIn->getData(I_in, Q_in);
252
253         len=I_in->length();
254       
255        DEBUG(5, Decimator, "Received "<<len<<" samples")
256
257        if (len != previous_length) {
258            len_out=(unsigned int)(1.0*len/M);
259            I_out.length(len_out);
260            Q_out.length(len_out);
261            delete [] I_buf;
262            delete [] Q_buf;
263            I_buf = new short[len];
264            Q_buf = new short[len];
265            previous_length=len;
266        }
267
268//        I_out.length(len_out);
269//        Q_out.length(len_out);
270
271/**
272#ifdef PRINT_ENERGY
273        float E_in = 0, E_out = 0;
274#endif
275**/
276
277if (filter_type==FIR) {
278        for (unsigned int i = 0; i < len; ++i) {
279
280           
281
282         
283           
284                sample_count = (++sample_count) % M;
285                if (sample_count == 0) output_sample = true;
286                fir_i_filter->do_work(output_sample, (*I_in)[i], I_buf[i]);
287                fir_q_filter->do_work(output_sample, (*Q_in)[i], Q_buf[i] );
288
289/**
290#ifdef LOG_DATA
291            pre_decim.write_data((float)(*I_in)[i], (float)(*Q_in)[i]);
292#endif
293
294#ifdef PRINT_ENERGY
295            E_in  += (*I_in)[i] * (*I_in)[i] + (*Q_in)[i] * (*Q_in)[i];
296            E_out += i_out * i_out + q_out * q_out;
297#endif
298**/
299        }
300        } else {
301                for (unsigned int i = 0; i < len; ++i) {
302             iir_i_filter->do_work( (*I_in)[i], I_buf[i]);
303             iir_q_filter->do_work( (*Q_in)[i], Q_buf[i]);
304             }
305           
306        }
307       
308        for (unsigned int i=0; i<len_out; i++) {
309            I_out[i] = I_buf[M*i];
310            Q_out[i] = Q_buf[M*i];
311            /**
312            #ifdef LOG_DATA
313                 post_decim.write_data((float)I_buf[M*i], (float)q_buf[M*i]);
314            #endif
315            **/
316        }
317
318        DEBUG(5, Decimator, "Out "<<len_out<<" samples")
319        dataIn->bufferEmptied();
320        dataOut->pushPacket(I_out, Q_out);
321/**
322#ifdef PRINT_ENERGY
323        std::cout << "Energy in = " << 10 * log10(E_in/decimator->I_in.length() + 0.01) << "  Energy out = " << 10 * log10(E_out/len_out + 0.01) << std::endl;
324#endif
325**/     
326    }
327
328}
329
330short Decimator_i::f2s(float r)
331{
332    if (r > SHRT_MAX)
333        return SHRT_MAX;
334
335    if (r < SHRT_MIN)
336        return SHRT_MIN;
337
338    short ret = (short) r;
339
340    return ret;
341}
342
343void Decimator_i::delete_filter_variables()
344{
345DEBUG(5, Decimator, "Enter delete_filter_variables")
346        if (fir_i_filter!=NULL){
347               delete fir_i_filter;
348               fir_i_filter=NULL;
349        };
350       
351        if (fir_q_filter!=NULL){
352               delete fir_q_filter;
353               fir_q_filter=NULL;
354        };
355
356        if (iir_i_filter!=NULL){
357               delete iir_i_filter;
358               iir_i_filter=NULL;
359        };
360       
361        if (iir_q_filter!=NULL){
362               delete iir_q_filter;
363               iir_q_filter=NULL;
364        };       
365
366DEBUG(5, Decimator, "Exit delete_filter_variables")
367}
Note: See TracBrowser for help on using the browser.