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

Revision 4153, 11.1 KB (checked in by hvolos, 6 years ago)

Some modifications

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::SetNoOfSymbols2TraceBack(unsigned int traceBackLength){
185    //std::cout<<theTrellis;
186    if (theTrellis!=NULL){
187        for (unsigned int i = 0; i < theTrellisTable->numberOfTrellisStates; i++){
188            delete theTrellis[i];
189        };
190        delete []theTrellis;
191        theTrellis=NULL;
192    }
193    //std::cout<<theTrellis;
194    //int dummy;
195    //std::cin>>dummy;
196
197    fec_conv_decoder::noOfSymbols2TraceBack=traceBackLength;
198
199    theTrellis= new TrellisEntry*[theTrellisTable->numberOfTrellisStates];
200    for (unsigned int i = 0; i < theTrellisTable->numberOfTrellisStates; i++){
201        theTrellis[i] =new TrellisEntry[noOfSymbols2TraceBack+1];
202    };
203
204    if (tracedBackSymbols!=NULL){
205        delete []tracedBackSymbols;
206        tracedBackSymbols=NULL;
207    };
208    tracedBackSymbols = new unsigned int [noOfSymbols2TraceBack];
209
210    currentTrellisIndex=0;
211    for (unsigned int i=0;i<theTrellisTable->numberOfTrellisStates;i++)
212        for (unsigned int j=0;j<=noOfSymbols2TraceBack;j++){
213            theTrellis[i][j].previousState=0;
214            theTrellis[i][j].symbolNo=0;
215            theTrellis[i][j].distance=(signed int)-1;
216        }
217    theTrellis[0][0].distance=0;
218
219}
220
221void fec_conv_decoder::Symbol2Decode(unsigned short int * inputData)
222{
223
224    unsigned int inbits=0,tmp=0,newState=0;
225    unsigned short int symbol;
226    signed int distance;
227
228    inbits=0;
229    for (unsigned short int i=0;i<theTrellisTable->n;i++){
230        tmp=inputData[i];
231        //std::cout<<"inputData:"<<tmp<<"\n";
232        tmp<<=theTrellisTable->n-i-1;
233        //std::cout<<"temp"<<tmp<<"\n";
234        inbits+=tmp;
235    }
236    //std::cout<<"inbits:"<<inbits<<"\n";
237    currentTrellisIndex++;
238    //std::cout<<"currentTrellisIndex:"<<currentTrellisIndex<<"\n";
239    for (unsigned int tstate=0;tstate<theTrellisTable->numberOfTrellisStates;tstate++){
240        if (theTrellis[tstate][currentTrellisIndex-1].distance!=-1){
241            for (unsigned short int inputBits=0;inputBits<theTrellisTable->numberOfInputStates;inputBits++){
242                newState=theTrellisTable->nextState[tstate][inputBits];
243                symbol=theTrellisTable->output[tstate][inputBits];
244
245                distance=CalculateDistance(inbits,symbol)+theTrellis[tstate][currentTrellisIndex-1].distance; //Have to calculate;
246                if ((theTrellis[newState][currentTrellisIndex].distance==-1)||
247                        ((distance<theTrellis[newState][currentTrellisIndex].distance))||
248                        (theTrellis[newState][currentTrellisIndex].distance<0)){
249                    theTrellis[newState][currentTrellisIndex].distance=distance;
250                    theTrellis[newState][currentTrellisIndex].previousState=tstate;
251                    theTrellis[newState][currentTrellisIndex].symbolNo=inputBits;
252                };
253            };
254        }
255        else{
256        };
257
258    }
259
260    /*
261        for (unsigned int tstate=0;tstate<numberOfTrellisStates;tstate++)
262        {
263                    std::cout<<"["<<tstate<<"]["<<currentTrellisIndex<<"].previousState:"
264                       <<theTrellis[tstate][currentTrellisIndex].previousState<<".distance:"
265                        <<theTrellis[tstate][currentTrellisIndex].distance<<".symbol:"<<
266                        theTrellis[tstate][currentTrellisIndex].symbolNo<<"\n";
267        };
268    */
269};
270
271signed int fec_conv_decoder::CalculateDistance(unsigned short int inBits, unsigned short int symbol)
272{
273    unsigned short int tmp;
274    signed int distance=0;
275    tmp=inBits^symbol;
276
277    while (tmp>0){
278        distance+=(signed int)(tmp % 2);
279        tmp>>=1;
280    };
281    return distance;
282
283}
284
285void fec_conv_decoder::TraceBackTrellis(){
286    //std::cout<<"cTi:"<<currentTrellisIndex<<"; cS:"<<currentState<<";";
287    unsigned int currentState;
288    signed int minDistance=9999;
289    unsigned int minDistState=0;
290
291    if (currentTrellisIndex==noOfSymbols2TraceBack){
292        if (mode==1){
293            currentState=0;
294        } else{
295            for (unsigned int tstate=0;tstate<theTrellisTable->numberOfTrellisStates;tstate++)
296                if ((theTrellis[tstate][currentTrellisIndex].distance!=-1)
297                        &&(theTrellis[tstate][currentTrellisIndex].distance<minDistance)){
298                    minDistance=theTrellis[tstate][currentTrellisIndex].distance;
299                    minDistState=tstate;
300                };
301
302            currentState=minDistState;
303        }
304       // std::cout<<"\nMinDistance:"<<minDistance<<" minDistState:"<<minDistState<<"\n";
305
306
307        unsigned short int symbol;
308        while (currentTrellisIndex>0)
309        {
310            symbol=theTrellis[currentState][currentTrellisIndex].symbolNo;
311            currentState=theTrellis[currentState][currentTrellisIndex].previousState;
312            currentTrellisIndex--;
313            //Dec2Bin(symbol,outputData,k);
314            tracedBackSymbols[currentTrellisIndex]=symbol;
315            // std::cout<<"\nsymbol:"<<symbol<<"outputData"<<outputData[0]<<"\n";
316        }
317
318        decodedSymbolIndex=0;
319    }
320}
321
322void fec_conv_decoder::GetDecodedSymbol(unsigned short int * outputData)
323{
324    if (currentTrellisIndex==0)
325    {
326
327        if (decodedSymbolIndex<noOfSymbols2TraceBack)
328        {
329            Dec2Bin(tracedBackSymbols[decodedSymbolIndex],outputData,theTrellisTable->k);
330        }
331        decodedSymbolIndex++;
332    }
333    else
334    {
335    }
336}
337
338fec_conv_decoder::fec_conv_decoder()
339{
340    tracedBackSymbols=NULL;
341    theTrellis=NULL;
342    decodedSymbolIndex=0;
343    currentTrellisIndex=0;
344    mode=0;
345}
346
347fec_conv_decoder::~fec_conv_decoder()
348{
349    if (tracedBackSymbols!=NULL) delete  []tracedBackSymbols;
350
351    if (theTrellis!=NULL){
352        for (unsigned int i = 0; i < theTrellisTable->numberOfTrellisStates; i++){
353            delete theTrellis[i];
354        };
355        delete []theTrellis;
356    }
357
358};
Note: See TracBrowser for help on using the browser.