root/ossiedev/branches/deepanns/components/ChannelDemo/ChannelDemo.cpp @ 8886

Revision 8886, 9.3 KB (checked in by deepanns, 4 years ago)

updated query and configure for components

  • Property svn:eol-style set to native
Line 
1/****************************************************************************
2
3Copyright 2007 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE ChannelDemo.
6
7OSSIE ChannelDemo 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 ChannelDemo 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 ChannelDemo; 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 "ChannelDemo.h"
27
28// Uniform random number generator, (0,1]
29float randf() {
30    float x = (float) rand();
31    return x / (float) RAND_MAX;
32}
33
34// Gaussian random number generator w/ zero mean, unit variance, N(0,1)
35void randnf(float * i, float * q)
36{
37    // generate two uniform random numbers
38    float u1, u2;
39
40    // ensure u1 does not equal zero
41    do {
42        u1 = randf();
43    } while (u1 == 0.0f);
44
45    u2 = randf();
46
47    float x = sqrt(-2*logf(u1));
48    *i = x * sinf(6.283185307*u2);
49    *q = x * cosf(6.283185307*u2);
50}
51/// Converts float to short, clipping as necessary
52short float2short(float x) {
53    short y;
54    if (x > SHRT_MAX) {
55        y = SHRT_MAX;
56    } else if (x < SHRT_MIN) {
57        y = SHRT_MIN;
58    } else {
59        y = (short) x;
60    }
61    return y;
62}
63
64// rotates a complex vector by theta radians
65void rotate(short I_in, short Q_in, float theta, short &I_out, short &Q_out) {
66    float c = cosf(theta);
67    float s = sinf(theta);
68   
69    I_out = (short)  ( (float) (I_in*c) - (float) (Q_in*s)  );
70    Q_out = (short)  ( (float) (I_in*s) + (float) (Q_in*c)  );
71}
72
73ChannelDemo_i::ChannelDemo_i(const char *uuid, omni_condition *condition) :
74    Resource_impl(uuid), component_running(condition)
75{
76    dataInPort = new standardInterfaces_i::complexShort_p("samples_in");
77    dataOutPort = new standardInterfaces_i::complexShort_u("samples_out");
78
79    // Initialize noise standard deviation
80    noise_std_dev = 1000;
81
82    // Initialize phase offset
83    phase_offset = 0.0f;
84
85    //Create the thread for the writer's processing function
86    processing_thread = new omni_thread(Run, (void *) this);
87
88    //Start the thread containing the writer's processing function
89    processing_thread->start();
90
91}
92
93ChannelDemo_i::~ChannelDemo_i(void)
94{   
95    delete dataInPort;
96    delete dataOutPort;
97}
98
99// Static function for omni thread
100void ChannelDemo_i::Run( void * data )
101{
102    ((ChannelDemo_i*)data)->ProcessData();
103}
104
105CORBA::Object_ptr ChannelDemo_i::getPort( const char* portName ) throw (
106    CORBA::SystemException, CF::PortSupplier::UnknownPort)
107{
108    DEBUG(3, ChannelDemo, "getPort() invoked with " << portName)
109   
110    CORBA::Object_var p;
111
112    p = dataInPort->getPort(portName);
113
114    if (!CORBA::is_nil(p))
115        return p._retn();
116
117    p = dataOutPort->getPort(portName);
118
119    if (!CORBA::is_nil(p))
120        return p._retn();
121
122    /*exception*/
123    throw CF::PortSupplier::UnknownPort();
124}
125
126void ChannelDemo_i::start() throw (CORBA::SystemException,
127    CF::Resource::StartError)
128{
129    DEBUG(3, ChannelDemo, "start() invoked")
130}
131
132void ChannelDemo_i::stop() throw (CORBA::SystemException, CF::Resource::StopError)
133
134    DEBUG(3, ChannelDemo, "stop() invoked")
135}
136
137void ChannelDemo_i::releaseObject() throw (CORBA::SystemException,
138    CF::LifeCycle::ReleaseError)
139{
140    DEBUG(3, ChannelDemo, "releaseObject() invoked")
141   
142    component_running->signal();
143}
144
145void ChannelDemo_i::initialize() throw (CF::LifeCycle::InitializeError,
146    CORBA::SystemException)
147{
148    DEBUG(3, ChannelDemo, "initialize() invoked")
149}
150
151void
152ChannelDemo_i::query (CF::Properties & configProperties)
153throw (CORBA::SystemException, CF::UnknownProperties)
154{
155    // for queries of zero length, return all id/value pairs in propertySet
156    if (configProperties.length () == 0)
157    {   
158        configProperties.length (propertySet.length ());
159        for (unsigned int i = 0; i < propertySet.length (); i++)
160        {
161            configProperties[i].id = CORBA::string_dup (propertySet[i].id);
162            configProperties[i].value = propertySet[i].value;
163        }
164
165        return ;
166    }   
167    else {
168        for (unsigned int i = 0; i < configProperties.length(); i++) {
169            for (unsigned int j=0; j < propertySet.length(); j++) {
170                if ( strcmp(configProperties[i].id, propertySet[i].id) == 0 ){
171                    configProperties[i].value = propertySet[i].value;
172               }
173            }
174        }
175    }   
176}
177
178void ChannelDemo_i::configure(const CF::Properties& props)
179throw (CORBA::SystemException,
180    CF::PropertySet::InvalidConfiguration,
181    CF::PropertySet::PartialConfiguration)
182{
183    static int init = 0;
184
185    DEBUG(3, ChannelDemo, "configure() invoked")
186
187    std::cout << "Component - CHANNEL DEMO" << std::endl;
188    if (init == 0){
189        std::cout << " ChannelDemo - initial configure call .." << std::endl;
190        propertySet.length(props.length());
191        for (unsigned int i=0; i < props.length(); i++) {
192            std::cout << "Property Id : " << props[i].id << std::endl;
193            propertySet[i].id = CORBA::string_dup(props[i].id);
194            propertySet[i].value = props[i].value;
195        }
196        init = 1;
197        return;
198    }
199    else {
200
201        std::cout << "props length : " << props.length() << std::endl;
202        //propertySet.length(props.length());
203        std::cout << "ChannelDemo_i::configure set propertySet.length " << propertySet.length() << std::endl;
204
205        for (unsigned int i = 0; i <props.length(); i++) {
206            if (strcmp(props[i].id, "DCE:a337c5f0-8245-11dc-860f-00123f63025f") == 0) {
207                // noise_std_dev (standard deviation of noise)
208                CORBA::Short simple_temp;
209                props[i].value >>= simple_temp;
210                // Test: setting propertySet[] to the given value.
211                noise_std_dev = simple_temp;
212
213                std::cout << "Property id : " << props[i].id << std::endl;
214                // Update value of this property in propertySet also
215                for (unsigned int j=0; j < propertySet.length(); j++ ) {
216                    if ( strcmp(propertySet[j].id, props[i].id) == 0 ) {
217                        propertySet[i].value = props[i].value;
218                        break;
219                    }
220                }
221                DEBUG(1, ChannelDemo, "Setting noise standard deviation to " << noise_std_dev);
222            }
223            else if (strcmp(props[i].id, "DCE:1c4a3eb9-9e3a-4c20-849a-90c6eaef9e5a") == 0) {
224                // phase offset (degrees)
225                CORBA::Float simple_temp;
226                props[i].value >>= simple_temp;
227                // Test: Setting propertySet[i] to the given value
228                propertySet[i].value = props[i].value;
229                phase_offset = simple_temp;
230                DEBUG(1, ChannelDemo, "Setting phase offset to " << phase_offset << " degrees");
231                // convert to radians
232                phase_offset *= M_PI/180.0f;
233
234                std::cout << "Property id : " << props[i].id << std::endl;
235                // Update value of this property in propertySet also
236                for (unsigned int j=0; j < propertySet.length(); j++ ) {
237                    if ( strcmp(propertySet[j].id, props[i].id) == 0 ) {
238                        propertySet[i].value = props[i].value;
239                        break;
240                    }
241                }
242
243            }
244            else {
245                // unknown property
246                std::cerr << "ERROR: ChannelDemo_i::configure() unknown property \""
247                << props[i].id << "\"" << std::endl;
248                throw CF::PropertySet::InvalidConfiguration();
249            }
250        }
251    }
252}
253
254void ChannelDemo_i::ProcessData()
255{
256    DEBUG(3, ChannelDemo, "ProcessData() invoked")
257
258    PortTypes::ShortSequence I_out, Q_out;
259
260
261    PortTypes::ShortSequence *I_in(NULL), *Q_in(NULL);
262    CORBA::UShort I_in_length, Q_in_length;
263
264    // input/output data length
265    unsigned int N(0);
266
267    short I_rotated, Q_rotated;
268
269    //
270    float noise_i(0.0f);
271    float noise_q(0.0f);
272
273    while(true) {
274        dataInPort->getData(I_in, Q_in);
275
276        I_in_length = I_in->length();
277        Q_in_length = Q_in->length();
278
279        if (I_in_length == Q_in_length) {
280            N = I_in_length;
281        } else {
282            std::cout << "ERROR! Input I/Q data are not the same length!" << std::endl;
283            throw 0;
284        }
285
286        I_out.length(N);
287        Q_out.length(N);
288
289        // add channel impairments
290        for (unsigned int i=0; i<N; i++) {
291            // Rotate input by phase_offset radians
292            rotate((*I_in)[i], (*Q_in)[i], phase_offset, I_rotated, Q_rotated);
293
294            // Add noise
295            randnf(&noise_i, &noise_q);
296            noise_i *= noise_std_dev;
297            noise_q *= noise_std_dev;
298            I_out[i] = I_rotated + float2short(noise_i);
299            Q_out[i] = Q_rotated + float2short(noise_q);
300        }
301
302        dataInPort->bufferEmptied();
303        dataOutPort->pushPacket(I_out, Q_out);
304    }
305}
306
307
Note: See TracBrowser for help on using the browser.