root/SigProc/trunk/SigProc/fec_conv.cpp @ 4154

Revision 4154, 11.6 KB (checked in by hvolos, 6 years ago)

Added decoder::Reset()

Line 
1/****************************************************************************
2
3Copyright 2007, Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Signal Processing Library.
6
7OSSIE Core Framework is free software; you can redistribute it and/or modify
8it under the terms of the Lesser GNU General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or
10(at your option) any later version.
11
12The OSSIE Signal Processing library 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
15Lesser GNU General Public License for more details.
16
17You should have received a copy of the Lesser GNU General Public License
18along with OSSIE Core Framework; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21****************************************************************************/
22
23#include "SigProc.h"
24
25#include <math.h>
26
27using namespace SigProc;
28
29
30trellisTable::trellisTable(
31unsigned int * generatorPolynomials,
32unsigned short int k,
33unsigned short int n,
34unsigned short K)
35{
36    //Build trellis table
37    trellisTable::k=k;
38    trellisTable::n=n;
39    trellisTable::K=K;
40
41    //std::cout<<"Constructor, generatorPolynomials:";
42    for (int i=0;i<n;i++){
43
44        std::cout<<generatorPolynomials[i]<<" ";
45    }
46    //std::cout<<std::endl;
47
48    //std::cout<<"Input bits:"<<k<<" Contraint Length:"<<K<<std::endl;
49    trellisTable::GenerateTrellisTable(generatorPolynomials);
50}
51
52trellisTable::~trellisTable()
53{
54    //Deallocate memory
55    for (unsigned int i = 0; i < trellisTable::numberOfTrellisStates; i++){
56        delete []trellisTable::nextState[i];
57    }
58    delete []trellisTable::nextState;
59
60
61    for (unsigned int i = 0; i < trellisTable::numberOfTrellisStates; i++){
62        delete []trellisTable::output[i];
63    }
64    delete []trellisTable::output;
65}
66
67
68void trellisTable::GenerateTrellisTable(unsigned int * generatorPolynomials)
69{
70
71    numberOfTrellisStates=int(pow(2,(k*(K-1))));
72    numberOfInputStates=int(pow(2,k));
73    //std::cout<<"NumberOfTrellisStates="<<numberOfTrellisStates<<std::endl;
74    //std::cout<<"numberOfInputStates="<<numberOfInputStates<<std::endl;
75
76    nextState = new unsigned int *[numberOfTrellisStates];
77
78    for (unsigned int i = 0; i < numberOfTrellisStates; i++){
79        nextState[i] = new unsigned int[numberOfInputStates];
80    }
81
82    output = new unsigned int *[numberOfTrellisStates];
83
84    for (unsigned int i = 0; i < numberOfTrellisStates; i++){
85        output[i] = new unsigned int[numberOfInputStates];
86    }
87
88    unsigned int ENCregister, tempOut;
89
90    for (unsigned int tstate=0;tstate<numberOfTrellisStates;tstate++){
91        //std::cout<<tstate<<":";
92        for (unsigned short int inputIdx=0;inputIdx<numberOfInputStates;inputIdx++){
93            ENCregister=inputIdx*numberOfTrellisStates+tstate;
94            nextState[tstate][inputIdx]=(unsigned int)floor(ENCregister/pow(2,k));
95            tempOut=0;
96
97            for (unsigned short int bitNo=0;bitNo<n;bitNo++){
98                // std::cout<<"\nBitNo:"<<bitNo<<" ENCregister:"<<ENCregister<<" g:"<<generatorPolynomials[bitNo]<<" &:"<<(ENCregister&generatorPolynomials[bitNo])
99                //      <<"power:"<<(unsigned short int)pow(2,n-bitNo-1)<<"tempOut:"<<tempOut<<"\n";
100                // std::cout<<"Mod2add:"<<Modulo2BitWiseAdd((ENCregister&generatorPolynomials[bitNo])*(unsigned short int)pow(2,n-bitNo-1))<<"\n";
101                tempOut+=Modulo2BitWiseAdd(ENCregister&generatorPolynomials[bitNo])* (unsigned short int)pow(2,n-bitNo-1);
102            }
103            output[tstate][inputIdx]=tempOut;
104            //std::cout<<output[tstate][inputIdx]<<" ("<<nextState[tstate][inputIdx]<<") ";
105
106
107        }
108        //std::cout<<std::endl;
109    }
110}
111
112unsigned short int trellisTable::Modulo2BitWiseAdd(unsigned short int inputNumber)
113{
114    //std::cout<<"IN:"<<inputNumber;
115    unsigned int tempOut;
116    tempOut=inputNumber % 2;
117    inputNumber>>=1;
118    while (inputNumber>0){
119        tempOut^=inputNumber % 2;
120        inputNumber>>=1;
121    }
122    // std::cout<<" Out:"<<tempOut<<" ";
123    return tempOut;
124}
125
126void fec_conv::SetTrellisTable(trellisTable *theTrellisTableIn)
127{
128    theTrellisTable=theTrellisTableIn;
129}
130
131void fec_conv::Dec2Bin(unsigned int decNumber,unsigned short int * outputData,unsigned short int numberOfBits)
132{
133    unsigned short int i;
134    for (i=numberOfBits;i>0;i--){
135        outputData[i-1]=decNumber % 2;
136        decNumber>>=1;
137    }
138}
139
140fec_conv_encoder::fec_conv_encoder()
141{
142    currentState=0;
143}
144
145fec_conv_encoder::~fec_conv_encoder()
146{
147
148}
149
150void fec_conv_encoder::ResetState()
151{
152    currentState=0;
153}
154
155unsigned int fec_conv_encoder::GetState()
156{
157    return currentState;
158}
159
160void fec_conv_encoder::Encode(unsigned short int * inputData,unsigned short int * outputData)
161{
162    unsigned int inbits=0,tmp=0,outbits=0;
163
164    for (unsigned short int i=0;i<theTrellisTable->k;i++)    {
165        tmp=inputData[i];
166        //std::cout<<"inputData:"<<tmp<<"\n";
167        tmp<<=theTrellisTable->k-i-1;
168        //std::cout<<"temp"<<tmp<<"\n";
169        inbits+=tmp;
170    }
171    //std::cout<<"state:"<<currentState<<" inbits:"<<inbits<<" outbits:"<<outbits<<"\n";
172    outbits=theTrellisTable->output[currentState][inbits];
173
174    currentState=theTrellisTable->nextState[currentState][inbits];
175    Dec2Bin(outbits,outputData,theTrellisTable->n);
176
177}
178
179void fec_conv_decoder::SetMode(unsigned short int mode)
180{
181    fec_conv_decoder::mode=mode;
182};
183
184void fec_conv_decoder::Reset()
185{
186    decodedSymbolIndex=0;
187    currentTrellisIndex=0;
188     for (unsigned int i=0;i<theTrellisTable->numberOfTrellisStates;i++)
189        for (unsigned int j=0;j<=noOfSymbols2TraceBack;j++){
190            theTrellis[i][j].previousState=0;
191            theTrellis[i][j].symbolNo=0;
192            theTrellis[i][j].distance=(signed int)-1;
193        }
194    theTrellis[0][0].distance=0;
195};
196
197void fec_conv_decoder::SetNoOfSymbols2TraceBack(unsigned int traceBackLength){
198    //std::cout<<theTrellis;
199    if (theTrellis!=NULL){
200        for (unsigned int i = 0; i < theTrellisTable->numberOfTrellisStates; i++){
201            delete theTrellis[i];
202        };
203        delete []theTrellis;
204        theTrellis=NULL;
205    }
206    //std::cout<<theTrellis;
207    //int dummy;
208    //std::cin>>dummy;
209
210    fec_conv_decoder::noOfSymbols2TraceBack=traceBackLength;
211
212    theTrellis= new TrellisEntry*[theTrellisTable->numberOfTrellisStates];
213    for (unsigned int i = 0; i < theTrellisTable->numberOfTrellisStates; i++){
214        theTrellis[i] =new TrellisEntry[noOfSymbols2TraceBack+1];
215    };
216
217    if (tracedBackSymbols!=NULL){
218        delete []tracedBackSymbols;
219        tracedBackSymbols=NULL;
220    };
221    tracedBackSymbols = new unsigned int [noOfSymbols2TraceBack];
222
223    currentTrellisIndex=0;
224    for (unsigned int i=0;i<theTrellisTable->numberOfTrellisStates;i++)
225        for (unsigned int j=0;j<=noOfSymbols2TraceBack;j++){
226            theTrellis[i][j].previousState=0;
227            theTrellis[i][j].symbolNo=0;
228            theTrellis[i][j].distance=(signed int)-1;
229        }
230    theTrellis[0][0].distance=0;
231
232}
233
234void fec_conv_decoder::Symbol2Decode(unsigned short int * inputData)
235{
236
237    unsigned int inbits=0,tmp=0,newState=0;
238    unsigned short int symbol;
239    signed int distance;
240
241    inbits=0;
242    for (unsigned short int i=0;i<theTrellisTable->n;i++){
243        tmp=inputData[i];
244        //std::cout<<"inputData:"<<tmp<<"\n";
245        tmp<<=theTrellisTable->n-i-1;
246        //std::cout<<"temp"<<tmp<<"\n";
247        inbits+=tmp;
248    }
249    //std::cout<<"inbits:"<<inbits<<"\n";
250    currentTrellisIndex++;
251    //std::cout<<"currentTrellisIndex:"<<currentTrellisIndex<<"\n";
252    for (unsigned int tstate=0;tstate<theTrellisTable->numberOfTrellisStates;tstate++){
253        if (theTrellis[tstate][currentTrellisIndex-1].distance!=-1){
254            for (unsigned short int inputBits=0;inputBits<theTrellisTable->numberOfInputStates;inputBits++){
255                newState=theTrellisTable->nextState[tstate][inputBits];
256                symbol=theTrellisTable->output[tstate][inputBits];
257
258                distance=CalculateDistance(inbits,symbol)+theTrellis[tstate][currentTrellisIndex-1].distance; //Have to calculate;
259                if ((theTrellis[newState][currentTrellisIndex].distance==-1)||
260                        ((distance<theTrellis[newState][currentTrellisIndex].distance))||
261                        (theTrellis[newState][currentTrellisIndex].distance<0)){
262                    theTrellis[newState][currentTrellisIndex].distance=distance;
263                    theTrellis[newState][currentTrellisIndex].previousState=tstate;
264                    theTrellis[newState][currentTrellisIndex].symbolNo=inputBits;
265                };
266            };
267        }
268        else{
269        };
270
271    }
272
273    /*
274        for (unsigned int tstate=0;tstate<numberOfTrellisStates;tstate++)
275        {
276                    std::cout<<"["<<tstate<<"]["<<currentTrellisIndex<<"].previousState:"
277                       <<theTrellis[tstate][currentTrellisIndex].previousState<<".distance:"
278                        <<theTrellis[tstate][currentTrellisIndex].distance<<".symbol:"<<
279                        theTrellis[tstate][currentTrellisIndex].symbolNo<<"\n";
280        };
281    */
282};
283
284signed int fec_conv_decoder::CalculateDistance(unsigned short int inBits, unsigned short int symbol)
285{
286    unsigned short int tmp;
287    signed int distance=0;
288    tmp=inBits^symbol;
289
290    while (tmp>0){
291        distance+=(signed int)(tmp % 2);
292        tmp>>=1;
293    };
294    return distance;
295
296}
297
298void fec_conv_decoder::TraceBackTrellis(){
299    //std::cout<<"cTi:"<<currentTrellisIndex<<"; cS:"<<currentState<<";";
300    unsigned int currentState;
301    signed int minDistance=9999;
302    unsigned int minDistState=0;
303
304    if (currentTrellisIndex==noOfSymbols2TraceBack){
305        if (mode==1){
306            currentState=0;
307        } else{
308            for (unsigned int tstate=0;tstate<theTrellisTable->numberOfTrellisStates;tstate++)
309                if ((theTrellis[tstate][currentTrellisIndex].distance!=-1)
310                        &&(theTrellis[tstate][currentTrellisIndex].distance<minDistance)){
311                    minDistance=theTrellis[tstate][currentTrellisIndex].distance;
312                    minDistState=tstate;
313                };
314
315            currentState=minDistState;
316        }
317       // std::cout<<"\nMinDistance:"<<minDistance<<" minDistState:"<<minDistState<<"\n";
318
319
320        unsigned short int symbol;
321        while (currentTrellisIndex>0)
322        {
323            symbol=theTrellis[currentState][currentTrellisIndex].symbolNo;
324            currentState=theTrellis[currentState][currentTrellisIndex].previousState;
325            currentTrellisIndex--;
326            //Dec2Bin(symbol,outputData,k);
327            tracedBackSymbols[currentTrellisIndex]=symbol;
328            // std::cout<<"\nsymbol:"<<symbol<<"outputData"<<outputData[0]<<"\n";
329        }
330
331        decodedSymbolIndex=0;
332    }
333}
334
335void fec_conv_decoder::GetDecodedSymbol(unsigned short int * outputData)
336{
337    if (currentTrellisIndex==0){
338
339        if (decodedSymbolIndex<noOfSymbols2TraceBack){
340            Dec2Bin(tracedBackSymbols[decodedSymbolIndex],
341            outputData,
342            theTrellisTable->k);
343        }
344       
345        decodedSymbolIndex++;
346       
347    } else {
348    }
349}
350
351fec_conv_decoder::fec_conv_decoder()
352{
353    tracedBackSymbols=NULL;
354    theTrellis=NULL;
355    decodedSymbolIndex=0;
356    currentTrellisIndex=0;
357    mode=0;
358}
359
360fec_conv_decoder::~fec_conv_decoder()
361{
362    if (tracedBackSymbols!=NULL) delete  []tracedBackSymbols;
363
364    if (theTrellis!=NULL){
365        for (unsigned int i = 0; i < theTrellisTable->numberOfTrellisStates; i++){
366            delete theTrellis[i];
367        };
368       
369        delete []theTrellis;
370    }
371
372};
Note: See TracBrowser for help on using the browser.