root/ossiedev/branches/0.7.x/components/Conv_Enc/Conv_Enc.cpp @ 9422

Revision 9422, 17.0 KB (checked in by shereef, 4 years ago)

fixed an error in Conv_Enc, too many brackets

Line 
1/****************************************************************************
2
3Copyright 2007 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Conv_Enc.
6
7OSSIE Conv_Enc 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 Conv_Enc 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 Conv_Enc; 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 "Conv_Enc.h"
27
28Conv_Enc_i::Conv_Enc_i(const char *uuid, omni_condition *condition) :
29    Resource_impl(uuid), component_running(condition)
30{
31    dataOut_0 = new standardInterfaces_i::realChar_u("encoded_bits");
32    dataIn_0 = new standardInterfaces_i::realChar_p("bits_to_enc_in");
33
34    inputGeneratorPolynomialsLength = 2;
35    inputGeneratorPolynomials = new unsigned int[inputGeneratorPolynomialsLength];
36    inputGeneratorPolynomials[0]=0;
37    inputGeneratorPolynomials[1]=0;
38    encoder=new SigProc::fec_conv_encoder();
39    configured=false;
40    //Create the thread for the writer's processing function
41    processing_thread = new omni_thread(Run, (void *) this);
42
43    //Start the thread containing the writer's processing function
44    processing_thread->start();
45
46}
47
48Conv_Enc_i::~Conv_Enc_i(void)
49{   
50    delete dataOut_0;
51    delete dataIn_0;
52    delete []inputGeneratorPolynomials;
53    delete trellisTables;
54    delete encoder;
55}
56
57// Static function for omni thread
58void Conv_Enc_i::Run( void * data )
59{
60    ((Conv_Enc_i*)data)->ProcessData();
61}
62
63CORBA::Object_ptr Conv_Enc_i::getPort( const char* portName ) throw (
64    CORBA::SystemException, CF::PortSupplier::UnknownPort)
65{
66    DEBUG(3, Conv_Enc, "getPort() invoked with " << portName)
67   
68    CORBA::Object_var p;
69
70    p = dataOut_0->getPort(portName);
71
72    if (!CORBA::is_nil(p))
73        return p._retn();
74
75    p = dataIn_0->getPort(portName);
76
77    if (!CORBA::is_nil(p))
78        return p._retn();
79
80    /*exception*/
81    throw CF::PortSupplier::UnknownPort();
82}
83
84void Conv_Enc_i::start() throw (CORBA::SystemException,
85    CF::Resource::StartError)
86{
87    DEBUG(3, Conv_Enc, "start() invoked")
88}
89
90void Conv_Enc_i::stop() throw (CORBA::SystemException, CF::Resource::StopError)
91
92    DEBUG(3, Conv_Enc, "stop() invoked")
93}
94
95void Conv_Enc_i::releaseObject() throw (CORBA::SystemException,
96    CF::LifeCycle::ReleaseError)
97{
98    DEBUG(3, Conv_Enc, "releaseObject() invoked")
99   
100    component_running->signal();
101}
102
103void Conv_Enc_i::initialize() throw (CF::LifeCycle::InitializeError,
104    CORBA::SystemException)
105{
106    DEBUG(3, Conv_Enc, "initialize() invoked")
107}
108
109void
110Conv_Enc_i::query (CF::Properties & configProperties)
111throw (CORBA::SystemException, CF::UnknownProperties)
112{
113    if (configProperties.length () == 0)
114    {
115        configProperties.length (propertySet.length ());
116        for (unsigned int i = 0; i < propertySet.length (); i++)
117        {
118            configProperties[i].id = CORBA::string_dup (propertySet[i].id);
119            configProperties[i].value = propertySet[i].value;
120        }
121
122        return ;
123    }
124    else {
125        for (unsigned int i = 0; i < configProperties.length(); i++) {
126            for (unsigned int j=0; j < propertySet.length(); j++) {
127                if ( strcmp(configProperties[i].id, propertySet[i].id) == 0 ){
128                    configProperties[i].value = propertySet[i].value;
129                }
130            }
131        }
132    }
133}
134
135void Conv_Enc_i::configure(const CF::Properties& props)
136throw (CORBA::SystemException,
137    CF::PropertySet::InvalidConfiguration,
138    CF::PropertySet::PartialConfiguration)
139{
140        static int init = 0;
141    DEBUG(3, Conv_Enc, "configure() invoked")
142   
143    if (init == 0){
144        if ( props.length() <= 0 ){
145            std::cout << "Conv_Enc: configure called with invalid props.length() - " << props.length() << std::endl;
146            return;
147        }
148
149        propertySet.length(props.length());
150        for (unsigned int i=0; i < props.length(); i++) {
151            propertySet[i].id = CORBA::string_dup(props[i].id);
152            propertySet[i].value = props[i].value;
153        }
154        init = 1;
155    }
156        for (unsigned int i = 0; i <props.length(); i++)
157        {
158            if (strcmp(props[i].id, "DCE:345df262-1611-11dc-a219-0016769e497b") == 0)
159            {
160                CORBA::Short simple_temp;
161                props[i].value >>= simple_temp;
162                rate_index = simple_temp;
163                for (unsigned int j=0; j < propertySet.length(); j++ ) {
164                    if ( strcmp(propertySet[j].id, props[i].id) == 0 ) {
165                        propertySet[i].value = props[i].value;
166                        break;
167                    }
168                }
169            }
170            if (strcmp(props[i].id, "DCE:7be7e584-1611-11dc-b945-0016769e497b") == 0)
171            {
172                CORBA::Short simple_temp;
173                props[i].value >>= simple_temp;
174                mode = simple_temp;
175                for (unsigned int j=0; j < propertySet.length(); j++ ) {
176                    if ( strcmp(propertySet[j].id, props[i].id) == 0 ) {
177                        propertySet[i].value = props[i].value;
178                        break;
179                    }
180                }
181            }
182            if (strcmp(props[i].id, "DCE:d2ee004a-18ee-11dc-8925-0016769e497b") == 0)
183            {
184                CORBA::Short simple_temp;
185                props[i].value >>= simple_temp;
186                k = simple_temp;
187                for (unsigned int j=0; j < propertySet.length(); j++ ) {
188                    if ( strcmp(propertySet[j].id, props[i].id) == 0 ) {
189                        propertySet[i].value = props[i].value;
190                        break;
191                    }
192                }
193            }
194            if (strcmp(props[i].id, "DCE:04aaa5ac-18ef-11dc-83ea-0016769e497b") == 0)
195            {
196                CORBA::Short simple_temp;
197                props[i].value >>= simple_temp;
198                K = simple_temp;
199                for (unsigned int j=0; j < propertySet.length(); j++ ) {
200                    if ( strcmp(propertySet[j].id, props[i].id) == 0 ) {
201                        propertySet[i].value = props[i].value;
202                        break;
203                    }
204                }
205            }
206            if (strcmp(props[i].id, "DCE:2d17e716-18ef-11dc-bf5c-0016769e497b") == 0)
207            {
208                CORBA::Short simple_temp;
209                props[i].value >>= simple_temp;
210                n = simple_temp;
211                for (unsigned int j=0; j < propertySet.length(); j++ ) {
212                    if ( strcmp(propertySet[j].id, props[i].id) == 0 ) {
213                        propertySet[i].value = props[i].value;
214                        break;
215                    }
216                }
217            }
218            if (strcmp(props[i].id, "DCE:4ef1b3b0-18f1-11dc-99b1-0016769e497b") == 0)
219            {
220                CORBA::ShortSeq *simplesequence;
221                props[i].value >>= simplesequence;
222                inputGeneratorPolynomialsLength = simplesequence->length();
223                std::cout << "inputGeneratorPolynomials has length : " <<
224                 inputGeneratorPolynomialsLength << std::endl;
225               
226                        delete []inputGeneratorPolynomials;
227
228                         DEBUG(4, Conv_Enc, "does delete fails?")           
229                        inputGeneratorPolynomials = new unsigned int [inputGeneratorPolynomialsLength];
230                       
231                         DEBUG(4, Conv_Enc, "the new?")
232
233                        for (unsigned int j = 0; j < inputGeneratorPolynomialsLength; j++)
234                        {
235                          DEBUG(3, Conv_Enc, "get the input from the simplesequence")
236                            inputGeneratorPolynomials[j] = (*simplesequence)[j];
237                        }
238
239                        for (unsigned int j=0; j < propertySet.length(); j++ ) {
240                            if ( strcmp(propertySet[j].id, props[i].id) == 0 ) {
241                                propertySet[i].value = props[i].value;
242                                break;
243                            }
244                        }
245                     }
246                }
247
248         DEBUG(3, Conv_Enc, "Configure is done, generate the trellis etc")
249          switch (rate_index){
250            unsigned int genPoly[10];
251            case 0:
252                trellisTables=new SigProc::trellisTable(inputGeneratorPolynomials,
253                (short unsigned int)k,
254                (short unsigned int)n,
255                (short unsigned int)K);
256
257                DEBUG(3, Conv_Dec, "custom trellis table generated")
258                break;
259            case 1:
260                //Rate 1, no trellis needed;           
261                DEBUG(3, Conv_Dec, "Pass through mode")
262                break;
263            case 2:
264                //4/5
265                genPoly[0]=237;
266                genPoly[1]=274;
267                genPoly[2]=156;
268                genPoly[3]=255;
269                genPoly[4]=337;
270                trellisTables=new SigProc::trellisTable(genPoly,
271                (short unsigned int)4,
272                (short unsigned int)5,
273                (short unsigned int)2);
274                DEBUG(3, Conv_Dec, "4/5 trellis table generated")
275                break;
276            case 3:
277                 //2/3
278                genPoly[0]=236;
279                genPoly[1]=155;
280                genPoly[2]=337;
281                trellisTables=new SigProc::trellisTable(genPoly,
282                (short unsigned int)2,
283                (short unsigned int)3,
284                (short unsigned int)4);
285                DEBUG(3, Conv_Dec, "2/3 trellis table generated")
286                break;
287            case 4:
288                 //1/2
289                genPoly[0]=133;
290                genPoly[1]=171;
291               
292                trellisTables=new SigProc::trellisTable(genPoly,
293                (short unsigned int)1,
294                (short unsigned int)2,
295                (short unsigned int)7);
296                DEBUG(3, Conv_Dec, "1/2 trellis table generated")
297                break;
298            case 5:
299                 //1/3
300                genPoly[0]=133;
301                genPoly[1]=145;
302                genPoly[2]=175;
303                trellisTables=new SigProc::trellisTable(genPoly,
304                (short unsigned int)1,
305                (short unsigned int)3,
306                (short unsigned int)7);
307                DEBUG(3, Conv_Dec, "1/3 trellis table generated")
308                break;
309            case 6:   
310                 //1/4
311                genPoly[0]=135;
312                genPoly[1]=135;
313                genPoly[2]=147;
314                genPoly[3]=163;
315                trellisTables=new SigProc::trellisTable(genPoly,
316                (short unsigned int)1,
317                (short unsigned int)4,
318                (short unsigned int)7);
319                DEBUG(3, Conv_Dec, "1/4 trellis table generated")
320                break;
321            case 7:
322                 //1/5
323                genPoly[0]=175;
324                genPoly[1]=131;
325                genPoly[2]=135;
326                genPoly[3]=135;
327                genPoly[4]=147;
328
329                trellisTables=new SigProc::trellisTable(genPoly,
330                (short unsigned int)1,
331                (short unsigned int)5,
332                (short unsigned int)7);
333                DEBUG(3, Conv_Dec, "1/5 trellis table generated")
334                break;
335            case 8:
336                 //1/6
337                genPoly[0]=173;
338                genPoly[1]=151;
339                genPoly[2]=135;
340                genPoly[3]=135;
341                genPoly[4]=163;
342                genPoly[5]=137;
343               
344                trellisTables=new SigProc::trellisTable(genPoly,
345                (short unsigned int)1,
346                (short unsigned int)6,
347                (short unsigned int)7);
348                DEBUG(3, Conv_Dec, "1/6 trellis table generated")
349                break;
350            case 9:
351                 //1/7
352                genPoly[0]=165;
353                genPoly[1]=145;
354                genPoly[2]=173;
355                genPoly[3]=135;
356                genPoly[4]=135;
357                genPoly[5]=147;
358                genPoly[6]=137;
359               
360                trellisTables=new SigProc::trellisTable(genPoly,
361                (short unsigned int)1,
362                (short unsigned int)7,
363                (short unsigned int)7);
364                DEBUG(3, Conv_Dec, "1/7 trellis table generated")
365                break;
366            case 10:
367                 //1/8
368                genPoly[0]=153;
369                genPoly[1]=111;
370                genPoly[2]=165;
371                genPoly[3]=173;
372                genPoly[4]=135;
373                genPoly[5]=135;
374                genPoly[6]=147;
375                genPoly[7]=137;
376                trellisTables=new SigProc::trellisTable(genPoly,
377                (short unsigned int)1,
378                (short unsigned int)8,
379                (short unsigned int)7);
380                DEBUG(3, Conv_Dec, "1/8 trellis table generated")
381                break;
382            default:
383                //Unknown rate
384                throw 0;
385        };         
386       
387          if (rate_index!=1)  {
388            encoder->SetTrellisTable(trellisTables);
389
390             DEBUG(4, Conv_Enc, "the trellis was sent to the encoder")
391            }
392            configured=true;
393
394}
395
396void Conv_Enc_i::ProcessData()
397{
398    DEBUG(3, Conv_Enc, "ProcessData() invoked")
399
400    PortTypes::CharSequence I_out_0;
401
402
403    PortTypes::CharSequence *I_in_0(NULL);
404    CORBA::UShort I_in_0_length;
405    unsigned short int data2Enc[20],encData[20],noOfSymbols=0;
406    signed short int tmp;
407    unsigned short int numberOfBits=0, numberOfOutBits=0;
408    SigProc::trellisTable *theTrellisTable;
409
410
411
412    while(1)
413    {
414               
415        dataIn_0->getData(I_in_0);
416           
417       
418        if (!configured) throw 0;
419
420        I_in_0_length = I_in_0->length();
421       
422        numberOfBits=I_in_0_length;
423
424        if (rate_index==1){
425            I_out_0.length(I_in_0_length);
426            for (unsigned int i=0;i<I_in_0_length;i++) {
427                I_out_0[i]=(*I_in_0)[i];
428            };
429            DEBUG(4, Conv_Enc, "Pass through mode, no encoding will done")
430        }else {
431
432            DEBUG(4, Conv_Enc, numberOfBits<<" bits received")
433            theTrellisTable=trellisTables;           
434           
435            if (numberOfBits % theTrellisTable->k>0){
436                std::cout<<"ERROR Conv_Enc::ProcessData number of input bits don't match the selected rate"<<theTrellisTable->k <<"/"<<theTrellisTable->n<<"\n";
437             throw 0;
438            }
439
440            noOfSymbols=numberOfBits/theTrellisTable->k;
441
442            ///Adjust the output lengh according to the encoding mode
443            switch (mode){
444                case 0:
445                    ///The encoder starts from zero state
446                    numberOfOutBits=noOfSymbols*theTrellisTable->n;
447                    break;
448                case 1:
449                    ///The encoder starts and ends at the zero state       
450                    numberOfOutBits=(noOfSymbols+theTrellisTable->K)*theTrellisTable->n;
451                    break;
452                default:
453                    std::cout<<"ERROR Conv_Enc::ProcessData Unknown mode "<<mode<<"\n";
454                    throw 0;
455            };
456            I_out_0.length(numberOfOutBits);
457            DEBUG(6, Conv_Enc, " Output length set to:"<<numberOfOutBits<<" mode:"<< mode <<" rate:"<<theTrellisTable->k <<"/"<<theTrellisTable->n)
458            ///Set the encoder state to 0
459            encoder->ResetState();
460            DEBUG(6, Conv_Enc, " Encoder state was reset")
461            /*insert code here to do work*/
462            for (unsigned int i=0;i<noOfSymbols;i++){
463                 for (unsigned int j=0;j<theTrellisTable->k;j++){
464                    data2Enc[j]=(*I_in_0)[i*theTrellisTable->k +j];
465                 }
466           
467                DEBUG(11, Conv_Enc, i+1<<" symbol to be encoded")
468           
469                encoder->Encode(data2Enc,encData);
470       
471                for (int j=0;j<theTrellisTable->n;j++){
472                     tmp=(short int )encData[j];
473                   I_out_0[i*theTrellisTable->n+j]=tmp;
474                 }
475                DEBUG(11, Conv_Enc, i+1<<" symbol encoded")
476            }
477
478            ///If mode=1 add additional symbols to make the last state of the encoder zero
479            if (mode==1){
480                   
481                 for (unsigned int j=0;j<theTrellisTable->k;j++){
482                    data2Enc[j]=0;
483                 }
484
485                  for (unsigned int i=noOfSymbols;i<noOfSymbols+theTrellisTable->K;i++){
486                           
487                         encoder->Encode(data2Enc,encData);
488       
489                        for (int j=0;j<theTrellisTable->n;j++){
490                         tmp=(short int )encData[j];
491                         I_out_0[i*theTrellisTable->n+j]=tmp;
492                        }
493                        DEBUG(11, Conv_Enc, i+1<<" (zero) symbol encoded")
494                }
495
496            };           
497
498        }//else
499
500        DEBUG(6, Conv_Enc, "Trying to push packet")
501        dataOut_0->pushPacket(I_out_0);
502       
503        DEBUG(6, Conv_Enc, "Now trying to empty the buffer")
504        dataIn_0->bufferEmptied();
505       
506        DEBUG(6, Conv_Enc, "buffer emptied")               
507               
508        if (rate_index!=1){
509        DEBUG(4, Conv_Enc, numberOfOutBits<<" Bits sent to the next component")
510               
511        } else {
512        DEBUG(4, Conv_Enc, numberOfBits<<" Bits sent to the next component")       
513        }
514    }
515}
516
517
Note: See TracBrowser for help on using the browser.