root/ossiedev/branches/jeongo9/components/liquid-components/src/Resampler.cpp @ 10731

Revision 10731, 7.4 KB (checked in by jeongo9, 2 years ago)

add liquid components

Line 
1/****************************************************************************
2
3Copyright 2010 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Resampler.
6
7OSSIE Resampler 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 Resampler 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 Resampler; 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 <string>
25#include <iostream>
26#include <stdio.h>
27
28#include "config.h"
29#include "Resampler.h"
30
31// include main.cpp (must define COMPONENT_OBJECT)
32#define  COMPONENT_OBJECT Resampler_i
33#include "main.cpp"
34
35Resampler_i::Resampler_i(const char *uuid, omni_condition *condition) :
36    Resource_impl(uuid), component_running(condition)
37{
38    samplesInPort = new standardInterfaces_i::complexFloat_p("SamplesIn");
39    samplesOutPort = new standardInterfaces_i::complexFloat_u("SamplesOut");
40
41    verbose = 0;
42
43    // create/initialize signal processing objects
44    h_len = 13;
45    r = 1.0f;
46    bw = 0.5f;
47    As = 60.0f;
48    npfb = 32;
49    resampler = resamp_crcf_create(r, h_len, bw, As, npfb);
50}
51
52Resampler_i::~Resampler_i(void)
53{
54    // delete ports
55    delete samplesInPort;
56    delete samplesOutPort;
57
58    // delete resampling object
59    resamp_crcf_destroy(resampler);
60}
61
62// Static function for omni thread
63void Resampler_i::Run( void * data )
64{
65    ((Resampler_i*)data)->ProcessData();
66}
67
68CORBA::Object_ptr Resampler_i::getPort( const char* portName ) throw (
69    CORBA::SystemException, CF::PortSupplier::UnknownPort)
70{
71    DEBUG(3, Resampler, "getPort() invoked with " << portName)
72
73    CORBA::Object_var p;
74
75    p = samplesInPort->getPort(portName);
76
77    if (!CORBA::is_nil(p))
78        return p._retn();
79
80    p = samplesOutPort->getPort(portName);
81
82    if (!CORBA::is_nil(p))
83        return p._retn();
84
85    /*exception*/
86    throw CF::PortSupplier::UnknownPort();
87}
88
89void Resampler_i::start() throw (CORBA::SystemException,
90    CF::Resource::StartError)
91{
92    DEBUG(3, Resampler, "start() invoked")
93    omni_mutex_lock  l(processing_mutex);
94    if( false == thread_started )
95    {
96        thread_started = true;
97        // Create the thread for the writer's processing function
98        processing_thread = new omni_thread(Run, (void *) this);
99
100        // Start the thread containing the writer's processing function
101        processing_thread->start();
102    }
103}
104
105void Resampler_i::stop() throw (CORBA::SystemException, CF::Resource::StopError)
106{
107    DEBUG(3, Resampler, "stop() invoked")
108    omni_mutex_lock l(processing_mutex);
109    thread_started = false;
110}
111
112void Resampler_i::releaseObject() throw (CORBA::SystemException,
113    CF::LifeCycle::ReleaseError)
114{
115    DEBUG(3, Resampler, "releaseObject() invoked")
116
117    component_running->signal();
118}
119
120void Resampler_i::initialize() throw (CF::LifeCycle::InitializeError,
121    CORBA::SystemException)
122{
123    DEBUG(3, Resampler, "initialize() invoked")
124}
125
126void Resampler_i::query( CF::Properties & configProperties ) throw (CORBA::SystemException, CF::UnknownProperties)
127{
128    if( configProperties.length() == 0 )
129    {
130        configProperties.length( propertySet.length() );
131        for( unsigned int i = 0; i < propertySet.length(); i++ )
132        {
133            configProperties[i].id = CORBA::string_dup( propertySet[i].id );
134            configProperties[i].value = propertySet[i].value;
135        }
136        return;
137    } else {
138        for (unsigned int i = 0; i < configProperties.length(); i++ ) {
139            for (unsigned int j = 0; j < propertySet.length(); j++ ) {
140                if( strcmp(configProperties[i].id, propertySet[j].id) == 0 ) {
141                    configProperties[i].value = propertySet[j].value;
142                }
143            }
144        }
145    } // end if-else
146}
147
148void Resampler_i::configure(const CF::Properties& props)
149throw (CORBA::SystemException,
150    CF::PropertySet::InvalidConfiguration,
151    CF::PropertySet::PartialConfiguration)
152{
153    DEBUG(3, Resampler, "configure() invoked")
154
155#if 0
156    static int init = 0;
157    if( init == 0 ) {
158        if( props.length() == 0 ) {
159            std::cout << "configure called with invalid props.length - " << props.length() << std::endl;
160            return;
161        }
162        propertySet.length(props.length());
163        for (unsigned int j=0; j < props.length(); j++ ) {
164            propertySet[j].id = CORBA::string_dup(props[j].id);
165            propertySet[j].value = props[j].value;
166        }
167        init = 1;
168    }
169#endif
170
171    std::cout << "props length : " << props.length() << std::endl;
172
173    for ( unsigned int i = 0; i <props.length(); i++) {
174        std::cout << "Property id : " << props[i].id << std::endl;
175
176        if (strcmp(props[i].id, "DCE:c5d3bd64-a554-11df-82df-001aa089d644") == 0) {
177            // verbosity
178            CORBA::Short simple_temp;
179            props[i].value >>= simple_temp;
180            verbose = simple_temp;
181        } else if (strcmp(props[i].id, "DCE:d5d1f2c6-a554-11df-b9ee-001aa089d644") == 0) {
182            // resampling rate
183            CORBA::Float simple_temp;
184            props[i].value >>= simple_temp;
185            r = simple_temp;
186
187            // validate input
188            if (r < 0.5f || r > 2.0f) {
189                fprintf(stderr, "error: Resampler::configure(), invalid resampling rate (%f) must be in [0.5,2]\n", r);
190                throw CF::PropertySet::InvalidConfiguration();
191            }
192
193            // set resampler rate
194            resamp_crcf_setrate(resampler, r);
195        }
196    }
197}
198
199void Resampler_i::ProcessData()
200{
201    DEBUG(3, Resampler, "ProcessData() invoked")
202
203    PortTypes::FloatSequence I_out, Q_out;
204
205    std::complex<float> x;      // input sample
206    std::complex<float> y[12];  // temporary buffer for output samples
207                                // TODO : ensure y is sufficiently sized
208
209
210    PortTypes::FloatSequence *I_in(NULL), *Q_in(NULL);
211    CORBA::UShort I_in_length, Q_in_length;
212
213    while(continue_processing())
214    {
215        samplesInPort->getData(I_in, Q_in);
216
217        I_in_length = I_in->length();
218        Q_in_length = Q_in->length();
219
220        unsigned int i;
221        unsigned int n=0;
222        unsigned int k;
223        for (i=0; i<I_in_length; i++) {
224            // strip input sample
225            x.real( (*I_in)[i] );
226            x.imag( (*Q_in)[i] );
227
228            // push into resampler
229            resamp_crcf_execute(resampler, x, y, &k);
230
231            // extend output array, if necessary
232            if (n + k > I_out.length()) {
233                I_out.length(n + k);
234                Q_out.length(n + k);
235            }
236
237            // append samples to output
238            unsigned int j;
239            for (j=0; j<k; j++) {
240                I_out[n+j] = y[j].real();
241                Q_out[n+j] = y[j].imag();
242            }
243            n += k;
244        }
245
246        // release input buffer
247        samplesInPort->bufferEmptied();
248
249        // push output packet
250        samplesOutPort->pushPacket(I_out, Q_out);
251    }
252}
253
254bool Resampler_i::continue_processing()
255{
256    omni_mutex_lock l(processing_mutex);
257    return thread_started;
258}
259
260
Note: See TracBrowser for help on using the browser.