Index: /SigProc/trunk/SigProc/SigProc.h
===================================================================
--- /SigProc/trunk/SigProc/SigProc.h	(revision 4146)
+++ /SigProc/trunk/SigProc/SigProc.h	(revision 4147)
@@ -34,4 +34,151 @@
 
 namespace SigProc {
+//-----------------------------------------------------------------------------
+//
+// Convolutional coding definitions
+//
+//-----------------------------------------------------------------------------
+
+/** \brief Defines the basic entry for building the trellis at the decoder
+*/
+class TrellisEntry{
+    public:
+        unsigned int previousState; ///< The state prior to the current state, used for tracing back the trellis
+        unsigned short int symbolNo; ///< The symbol that caused the change of state to the currrent state
+        signed int distance; ///< The total distance of the current state
+};
+
+/** \brief Includes all the necessary information for encoding and decoding the symbols
+ *
+ * The contructor has to be ALWAYS be used. The generator polynomials for each code rate have to be specified in DECIMAL, not OCTAL format
+ *
+ * For more information for the meaning of the symbols used and for generator polynomials look at
+ * Proakis Digital Communications book 4th Edition, pages 471 & 492 respectively.
+*/
+class trellisTable{
+    public:
+        /// The contructor has to be always used
+        trellisTable(unsigned int * generatorPolynomials, unsigned short int k, unsigned short int n, unsigned short K);
+
+        /// =The destructor
+        ~trellisTable();
+
+        unsigned short int k;///<the input bits at a time
+        unsigned short int n;///< the output bits at a time
+        unsigned short int K;///<the contraint length
+        unsigned short int numberOfInputStates;///< Based on k, how many different input states exist
+        unsigned int numberOfTrellisStates;///<Number of different trellis states, defined by k & K
+
+        unsigned int **output; ///< The rows are the trellis states and the columns the symbols, gives the output given the current state and symbol.
+        unsigned int **nextState;///< The sane as output, gives the the next state given the current state and synbol
+
+    protected:
+        ///Generates the trellis table given the generator polynomials in DECIMAL not OCTAL
+        void GenerateTrellisTable(unsigned int * generatorPolynomials);
+
+        ///Peforms modulo 2 addition to the bits of the input number (symbol)
+        unsigned short int Modulo2BitWiseAdd(unsigned short int inputNumber);
+};
+
+/** \brief Defines the basic functionality for the convolution encoding/decoding
+*/
+
+class fec_conv{
+    public:
+        /// It accepts the pointer to the trellis Table
+        void SetTrellisTable(trellisTable *theTrellisTableIn);
+
+    protected:
+        /// It converts a decimal numnber (symbol) into a vector of bits
+        void Dec2Bin(unsigned int decNumber,unsigned short int * outputData,unsigned short int numberOfBits);
+
+        trellisTable * theTrellisTable;///< It holds the trellis table used for encoding/decoding
+};
+
+/** \brief It defines the encoding functionality
+ *
+ * To use this class, first pass the trellis table pointer
+ *
+ * To encode: reset the state, feed data & get encoded data, repeat for the next packet.
+ *
+ * To make the encoder to return at the zero state during encoding, feed K 0 symbols after the encoding of the data is done.
+*/
+class fec_conv_encoder : public fec_conv{
+    public:
+        ///Default constructor
+        fec_conv_encoder();
+
+        ///Default destructor
+        ~fec_conv_encoder();
+
+        /// Resets the state of the encoder to the zero state
+        void ResetState();
+
+        ///It gets the current state of the encoder
+        unsigned int GetState();
+
+        ///It accepts a vector of k bits and returns a vector of n bits
+        void Encode(unsigned short int * inputData,unsigned short int * outputData);
+
+    protected:
+        unsigned int currentState;///<The current state of the encoder
+};
+
+/** \brief It defines the decoding functionality
+ *
+ * The following cycle should be followed to use this class:
+ *
+ * 1. Set the trellis table
+ *
+ * 2. Set the traceback length
+ *
+ * 3. Set mode
+ *
+ * 4. Feed symbols into the decoder
+ *
+ * 5. Trace back trellis
+ *
+ * 6. Get the decoded symbols
+ *
+ * 7. Reset and repeat from 4 for the next packet. If the decoding parameters change, might need to repeat from 1.
+*/
+class fec_conv_decoder:public fec_conv {
+    public:
+        ///Default contructor
+        fec_conv_decoder();
+
+        ///Default destructor
+        ~fec_conv_decoder();
+
+        /// Set the numbers of the input symbols to be decoded, this equals to the total bits on the output of the encoder divided by k
+        void SetNoOfSymbols2TraceBack(unsigned int tracebackLength);
+
+        /// Feeds a symbol (in a vector of n bits) at time for decoding
+        void Symbol2Decode(unsigned short int * inputData);
+
+        /// After all symbols were fed in the decoder, it will tracesback the trellis to the begining.
+        void TraceBackTrellis();
+
+        ///After the trellis was traced back, it returns a decoded symbol, starting from the beggining each time is called.
+        void GetDecodedSymbol(unsigned short int * outputData);
+
+        ///It resets the state of the decoder in order to be able to start a new decoding session
+        void Reset();
+
+        ///Sets the mode of the decoder 0: the encoded data start from zero state 1: the encoded data start from the the zero state and end at the zero state.
+        void SetMode(unsigned short int mode);
+
+    protected:
+        ///Calculates the distance between the input bits (symbol) to the current trellis symbol
+        signed int CalculateDistance(unsigned short int inBits, unsigned short int symbol);
+
+        unsigned int currentTrellisIndex;///<The current trellis stage used when building and tracing back the trellis.
+        unsigned int decodedSymbolIndex;///<The next symbol to be returned when the GetDecodedSymbol is called.
+        unsigned int noOfSymbols2TraceBack;///<Number of symbols to trace back, should be equal to the symbols used in the encoding process.
+        unsigned int mode;///<The mode of the encoder
+
+        unsigned int *tracedBackSymbols;///<A vector array with the symbols traced back
+        TrellisEntry **theTrellis; ///<A two dimensional array making the trellis, states are rows, and columns are each trellis stage.
+};
 
 //-----------------------------------------------------------------------------
@@ -132,8 +279,8 @@
     /// if buffer is full
     void Push(T _value) {
-        
+
         // OK to push value
         headPtr[i_head++] = _value;
-        
+
         // Ensure head index does not equal or exceed bufferSize (wrap)
         i_head = i_head % bufferSize;
@@ -293,8 +440,8 @@
             float & _gmin,
             float & _gmax);
-    
+
     /// Get status
     void GetStatus(float & _gain, float & _energy);
-    
+
     /// track signal energy and apply gain (real)
     void ApplyGain(short & I);
@@ -346,5 +493,5 @@
  public:
     phase_detect(float scale_factor);
- 
+
     void do_work(short I_in, short Q_in, short I_nco, short Q_nco, short &out);
 
@@ -785,4 +932,5 @@
 
 }
-
 #endif
+
+
Index: /SigProc/trunk/SigProc/fec_conv.cpp
===================================================================
--- /SigProc/trunk/SigProc/fec_conv.cpp	(revision 4147)
+++ /SigProc/trunk/SigProc/fec_conv.cpp	(revision 4147)
@@ -0,0 +1,357 @@
+/****************************************************************************
+
+Copyright 2007, Virginia Polytechnic Institute and State University
+
+This file is part of the OSSIE Signal Processing Library.
+
+OSSIE Core Framework is free software; you can redistribute it and/or modify
+it under the terms of the Lesser GNU General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+The OSSIE Signal Processing library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+Lesser GNU General Public License for more details.
+
+You should have received a copy of the Lesser GNU General Public License
+along with OSSIE Core Framework; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+****************************************************************************/
+
+#include "SigProc.h"
+
+#include <math.h>
+
+using namespace SigProc;
+
+
+trellisTable::trellisTable(
+unsigned int * generatorPolynomials,
+unsigned short int k,
+unsigned short int n,
+unsigned short K)
+{
+    //Build trellis table
+    trellisTable::k=k;
+    trellisTable::n=n;
+    trellisTable::K=K;
+
+    //std::cout<<"Constructor, generatorPolynomials:";
+    for (int i=0;i<n;i++){
+
+        std::cout<<generatorPolynomials[i]<<" ";
+    }
+    //std::cout<<std::endl;
+
+    //std::cout<<"Input bits:"<<k<<" Contraint Length:"<<K<<std::endl;
+    trellisTable::GenerateTrellisTable(generatorPolynomials);
+}
+
+trellisTable::~trellisTable()
+{
+    //Deallocate memory
+    for (unsigned int i = 0; i < trellisTable::numberOfTrellisStates; i++){
+        delete []trellisTable::nextState[i];
+    }
+    delete []trellisTable::nextState;
+
+
+    for (unsigned int i = 0; i < trellisTable::numberOfTrellisStates; i++){
+        delete []trellisTable::output[i];
+    }
+    delete []trellisTable::output;
+}
+
+
+void trellisTable::GenerateTrellisTable(unsigned int * generatorPolynomials)
+{
+
+    numberOfTrellisStates=int(pow(2,(k*(K-1))));
+    numberOfInputStates=int(pow(2,k));
+    //std::cout<<"NumberOfTrellisStates="<<numberOfTrellisStates<<std::endl;
+    //std::cout<<"numberOfInputStates="<<numberOfInputStates<<std::endl;
+
+    nextState = new unsigned int *[numberOfTrellisStates];
+
+    for (unsigned int i = 0; i < numberOfTrellisStates; i++){
+        nextState[i] = new unsigned int[numberOfInputStates];
+    }
+
+    output = new unsigned int *[numberOfTrellisStates];
+
+    for (unsigned int i = 0; i < numberOfTrellisStates; i++){
+        output[i] = new unsigned int[numberOfInputStates];
+    }
+
+    unsigned int ENCregister, tempOut;
+
+    for (unsigned int tstate=0;tstate<numberOfTrellisStates;tstate++){
+        //std::cout<<tstate<<":";
+        for (unsigned short int inputIdx=0;inputIdx<numberOfInputStates;inputIdx++){
+            ENCregister=inputIdx*numberOfTrellisStates+tstate;
+            nextState[tstate][inputIdx]=(unsigned int)floor(ENCregister/pow(2,k));
+            tempOut=0;
+
+            for (unsigned short int bitNo=0;bitNo<n;bitNo++){
+                // std::cout<<"\nBitNo:"<<bitNo<<" ENCregister:"<<ENCregister<<" g:"<<generatorPolynomials[bitNo]<<" &:"<<(ENCregister&generatorPolynomials[bitNo])
+                //	<<"power:"<<(unsigned short int)pow(2,n-bitNo-1)<<"tempOut:"<<tempOut<<"\n";
+                // std::cout<<"Mod2add:"<<Modulo2BitWiseAdd((ENCregister&generatorPolynomials[bitNo])*(unsigned short int)pow(2,n-bitNo-1))<<"\n";
+                tempOut+=Modulo2BitWiseAdd(ENCregister&generatorPolynomials[bitNo])* (unsigned short int)pow(2,n-bitNo-1);
+            }
+            output[tstate][inputIdx]=tempOut;
+            //std::cout<<output[tstate][inputIdx]<<" ("<<nextState[tstate][inputIdx]<<") ";
+
+
+        }
+        //std::cout<<std::endl;
+    }
+}
+
+unsigned short int trellisTable::Modulo2BitWiseAdd(unsigned short int inputNumber)
+{
+    //std::cout<<"IN:"<<inputNumber;
+    unsigned int tempOut;
+    tempOut=inputNumber % 2;
+    inputNumber>>=1;
+    while (inputNumber>0)
+    {
+        tempOut^=inputNumber % 2;
+        inputNumber>>=1;
+    }
+    // std::cout<<" Out:"<<tempOut<<" ";
+    return tempOut;
+}
+
+void fec_conv::SetTrellisTable(trellisTable *theTrellisTableIn)
+{
+    theTrellisTable=theTrellisTableIn;
+}
+
+void fec_conv::Dec2Bin(unsigned int decNumber,unsigned short int * outputData,unsigned short int numberOfBits)
+{
+    unsigned short int i;
+    for (i=numberOfBits;i>0;i--)
+    {
+        outputData[i-1]=decNumber % 2;
+        decNumber>>=1;
+    }
+}
+
+fec_conv_encoder::fec_conv_encoder(){
+    currentState=0;
+}
+
+fec_conv_encoder::~fec_conv_encoder(){
+
+}
+void SigProc::fec_conv_encoder::ResetState(){
+    currentState=0;
+}
+
+unsigned int fec_conv_encoder::GetState(){
+    return currentState;
+}
+
+void fec_conv_encoder::Encode(unsigned short int * inputData,unsigned short int * outputData)
+{
+    unsigned int inbits=0,tmp=0,outbits=0;
+
+    for (unsigned short int i=0;i<theTrellisTable->k;i++)
+    {
+        tmp=inputData[i];
+        //std::cout<<"inputData:"<<tmp<<"\n";
+        tmp<<=theTrellisTable->k-i-1;
+        //std::cout<<"temp"<<tmp<<"\n";
+        inbits+=tmp;
+    }
+    //std::cout<<"state:"<<currentState<<" inbits:"<<inbits<<" outbits:"<<outbits<<"\n";
+    outbits=theTrellisTable->output[currentState][inbits];
+
+    currentState=theTrellisTable->nextState[currentState][inbits];
+    Dec2Bin(outbits,outputData,theTrellisTable->n);
+
+}
+
+void fec_conv_decoder::SetMode(unsigned short int mode)
+{
+    fec_conv_decoder::mode=mode;
+};
+
+void fec_conv_decoder::SetNoOfSymbols2TraceBack(unsigned int traceBackLength){
+    //std::cout<<theTrellis;
+    if (theTrellis!=NULL){
+        for (unsigned int i = 0; i < theTrellisTable->numberOfTrellisStates; i++){
+            delete theTrellis[i];
+        };
+        delete []theTrellis;
+        theTrellis=NULL;
+    }
+    //std::cout<<theTrellis;
+    //int dummy;
+    //std::cin>>dummy;
+
+    fec_conv_decoder::noOfSymbols2TraceBack=traceBackLength;
+
+    theTrellis= new TrellisEntry*[theTrellisTable->numberOfTrellisStates];
+    for (unsigned int i = 0; i < theTrellisTable->numberOfTrellisStates; i++){
+        theTrellis[i] =new TrellisEntry[noOfSymbols2TraceBack+1];
+    };
+
+    if (tracedBackSymbols!=NULL){
+        delete []tracedBackSymbols;
+        tracedBackSymbols=NULL;
+    };
+    tracedBackSymbols = new unsigned int [noOfSymbols2TraceBack];
+
+    currentTrellisIndex=0;
+    for (unsigned int i=0;i<theTrellisTable->numberOfTrellisStates;i++)
+        for (unsigned int j=0;j<=noOfSymbols2TraceBack;j++){
+            theTrellis[i][j].previousState=0;
+            theTrellis[i][j].symbolNo=0;
+            theTrellis[i][j].distance=(signed int)-1;
+        }
+    theTrellis[0][0].distance=0;
+
+}
+
+void fec_conv_decoder::Symbol2Decode(unsigned short int * inputData)
+{
+
+    unsigned int inbits=0,tmp=0,newState=0;
+    unsigned short int symbol;
+    signed int distance;
+
+    inbits=0;
+    for (unsigned short int i=0;i<theTrellisTable->n;i++){
+        tmp=inputData[i];
+        //std::cout<<"inputData:"<<tmp<<"\n";
+        tmp<<=theTrellisTable->n-i-1;
+        //std::cout<<"temp"<<tmp<<"\n";
+        inbits+=tmp;
+    }
+    //std::cout<<"inbits:"<<inbits<<"\n";
+    currentTrellisIndex++;
+    //std::cout<<"currentTrellisIndex:"<<currentTrellisIndex<<"\n";
+    for (unsigned int tstate=0;tstate<theTrellisTable->numberOfTrellisStates;tstate++){
+        if (theTrellis[tstate][currentTrellisIndex-1].distance!=-1){
+            for (unsigned short int inputBits=0;inputBits<theTrellisTable->numberOfInputStates;inputBits++){
+                newState=theTrellisTable->nextState[tstate][inputBits];
+                symbol=theTrellisTable->output[tstate][inputBits];
+
+                distance=CalculateDistance(inbits,symbol)+theTrellis[tstate][currentTrellisIndex-1].distance; //Have to calculate;
+                if ((theTrellis[newState][currentTrellisIndex].distance==-1)||
+                        ((distance<theTrellis[newState][currentTrellisIndex].distance))||
+                        (theTrellis[newState][currentTrellisIndex].distance<0)){
+                    theTrellis[newState][currentTrellisIndex].distance=distance;
+                    theTrellis[newState][currentTrellisIndex].previousState=tstate;
+                    theTrellis[newState][currentTrellisIndex].symbolNo=inputBits;
+                };
+            };
+        }
+        else{
+        };
+
+    }
+
+    /*
+        for (unsigned int tstate=0;tstate<numberOfTrellisStates;tstate++)
+        {
+                    std::cout<<"["<<tstate<<"]["<<currentTrellisIndex<<"].previousState:"
+                       <<theTrellis[tstate][currentTrellisIndex].previousState<<".distance:"
+                        <<theTrellis[tstate][currentTrellisIndex].distance<<".symbol:"<<
+                        theTrellis[tstate][currentTrellisIndex].symbolNo<<"\n";
+        };
+    */
+};
+
+signed int fec_conv_decoder::CalculateDistance(unsigned short int inBits, unsigned short int symbol){
+    unsigned short int tmp;
+    signed int distance=0;
+    tmp=inBits^symbol;
+
+    while (tmp>0){
+        distance+=(signed int)(tmp % 2);
+        tmp>>=1;
+    };
+    return distance;
+
+}
+
+void fec_conv_decoder::TraceBackTrellis(){
+    //std::cout<<"cTi:"<<currentTrellisIndex<<"; cS:"<<currentState<<";";
+    unsigned int currentState;
+    signed int minDistance=9999;
+    unsigned int minDistState=0;
+
+    if (currentTrellisIndex==noOfSymbols2TraceBack){
+        if (mode==1){
+            currentState=0;
+        } else{
+            for (unsigned int tstate=0;tstate<theTrellisTable->numberOfTrellisStates;tstate++)
+                if ((theTrellis[tstate][currentTrellisIndex].distance!=-1)
+                        &&(theTrellis[tstate][currentTrellisIndex].distance<minDistance)){
+                    minDistance=theTrellis[tstate][currentTrellisIndex].distance;
+                    minDistState=tstate;
+                };
+
+            currentState=minDistState;
+        }
+        std::cout<<"\nMinDistance:"<<minDistance<<" minDistState:"<<minDistState<<"\n";
+
+
+        unsigned short int symbol;
+        while (currentTrellisIndex>0)
+        {
+            symbol=theTrellis[currentState][currentTrellisIndex].symbolNo;
+            currentState=theTrellis[currentState][currentTrellisIndex].previousState;
+            currentTrellisIndex--;
+            //Dec2Bin(symbol,outputData,k);
+            tracedBackSymbols[currentTrellisIndex]=symbol;
+            // std::cout<<"\nsymbol:"<<symbol<<"outputData"<<outputData[0]<<"\n";
+        }
+
+        decodedSymbolIndex=0;
+    }
+}
+
+void fec_conv_decoder::GetDecodedSymbol(unsigned short int * outputData)
+{
+    if (currentTrellisIndex==0)
+    {
+
+        if (decodedSymbolIndex<noOfSymbols2TraceBack)
+        {
+            Dec2Bin(tracedBackSymbols[decodedSymbolIndex],outputData,theTrellisTable->k);
+        }
+        decodedSymbolIndex++;
+    }
+    else
+    {
+    }
+}
+
+fec_conv_decoder::fec_conv_decoder()
+{
+    tracedBackSymbols=NULL;
+    theTrellis=NULL;
+    decodedSymbolIndex=0;
+    currentTrellisIndex=0;
+    mode=0;
+}
+
+fec_conv_decoder::~fec_conv_decoder()
+{
+    if (tracedBackSymbols!=NULL) delete  []tracedBackSymbols;
+
+    if (theTrellis!=NULL)
+    {
+        for (unsigned int i = 0; i < theTrellisTable->numberOfTrellisStates; i++)
+        {
+            delete theTrellis[i];
+        };
+        delete []fec_conv_decoder::theTrellis;
+    }
+
+};
Index: /SigProc/trunk/SigProc/Makefile.am
===================================================================
--- /SigProc/trunk/SigProc/Makefile.am	(revision 4016)
+++ /SigProc/trunk/SigProc/Makefile.am	(revision 4147)
@@ -6,4 +6,5 @@
     sources.cpp                     \
     utility.cpp                     \
+    fec_conv.cpp                    \
     fixed.c                         \
     modem.cpp
