Hadamard code: Difference between revisions

From ciapini
Jump to navigation Jump to search
(Created page with "codice FEC")
 
No edit summary
Line 1: Line 1:
codice FEC
codice FEC
<source lang="C">
// Hadamard codec - gnugo@hacari.org - 06/2012
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
uint8_t BlockDecodeChar(int16_t *DataMatrix, uint16_t HadamardCodeSize);
void BlockEncodeChar(int16_t *DataMatrix, uint8_t Input, uint16_t HadamardCodeSize);
void main(void){ 
  uint16_t HadamardCodeSize,
    BitsPerModulationSymbol,
    ModulationSymbols,
    CharactersPerModulationBlock,
    ModulationBlockSize;
 
  uint8_t BitsPerCharacter,
    CharPosition;
 
  BitsPerCharacter = 7; // dimensione singolo dato in ingresso
  HadamardCodeSize = 1 << (BitsPerCharacter - 1); // dimensione  del singolo codice hadamard in uscita 2^(n-1)
 
  BitsPerModulationSymbol = 6; // bit rappresentati da un simbolo della modulazione
  ModulationSymbols = 1 << BitsPerModulationSymbol; // dimensione alfabeto modulato
 
  CharactersPerModulationBlock = BitsPerModulationSymbol; // caratteri in un blocco modulazione
  ModulationBlockSize = BitsPerModulationSymbol * HadamardCodeSize; // dimensioni blocco modulazione
 
  printf("HadamardCodeSize %u\n", HadamardCodeSize); 
  printf("ModulationSymbols %u\n", ModulationSymbols); 
 
  // buffer matrici
  int16_t *FHT_Buffer;
  FHT_Buffer = malloc(HadamardCodeSize*sizeof(int16_t));
  // buffer modulazione
  int16_t *ModulationSymbolsBuffer;
  ModulationSymbolsBuffer = malloc(HadamardCodeSize*sizeof(int16_t));
  // dato in ingresso
  unsigned char InString[16];
  strcpy(InString,"ciao mondo"); 
 
  // impacchetta un modulation block
  for (uint8_t CharPosition = 0; CharPosition < BitsPerModulationSymbol; CharPosition++){
      printf("encoding char %c pos %d\n", InString[CharPosition], CharPosition);
      BlockEncodeChar(FHT_Buffer, InString[CharPosition], HadamardCodeSize);     
      OrthogonalPack(FHT_Buffer, ModulationSymbolsBuffer, CharPosition, HadamardCodeSize);
  }
  // pulisci buffer
  memset(FHT_Buffer, 0, HadamardCodeSize*sizeof(int16_t));
  printbuf(ModulationSymbolsBuffer, HadamardCodeSize, 8);
 
  //ModulationSymbolsBuffer[15] = ModulationSymbolsBuffer[25];
  //ModulationSymbolsBuffer[19] = ModulationSymbolsBuffer[22];
 
  // disimpacchetta un modulation block
  for (uint8_t CharPosition = 0; CharPosition < BitsPerModulationSymbol; CharPosition++){
      OrthogonalUnPack(FHT_Buffer, ModulationSymbolsBuffer, CharPosition, HadamardCodeSize);
     
      uint8_t OutChar;
      OutChar = BlockDecodeChar(FHT_Buffer, HadamardCodeSize);
     
  }
}
// Forward Fast Hadamard Transform
void FastHadamardTransform(int16_t *Data, uint16_t Len){
  int16_t Bit1, Bit2, NewBit1, NewBit2 = 0;
  for (uint16_t Step = 1; Step < Len; Step <<= 1) {
      for (uint16_t Ptr = 0; Ptr < Len; Ptr += (Step << 1)) {
for (uint16_t Ptr2 = Ptr; Ptr2 - Ptr < Step; ++ Ptr2) {
    Bit1      = Data[Ptr2]; 
    Bit2      = Data[Ptr2+Step];
    NewBit1    = Bit2;
    NewBit1  += Bit1;
    NewBit2    = Bit2;
    NewBit2  -= Bit1;
    Data[Ptr2] = NewBit1;
    Data[Ptr2+Step]=NewBit2;
}
      }
  }
}
// Inverse Fast Hadamard Transform
void InverseFastHadamardTransform(int16_t *Data, uint16_t Len){
  int16_t Bit1, Bit2, NewBit1, NewBit2 = 0;
  for (uint16_t Step = (Len >> 1); Step; Step >>= 1) {
      for (uint16_t Ptr = 0; Ptr < Len; Ptr += (Step << 1)) {
for (uint16_t Ptr2 = Ptr; Ptr2 - Ptr < Step; ++ Ptr2) {
    Bit1              = Data[Ptr2];
    Bit2              = Data[Ptr2 + Step];
    NewBit1            = Bit1;
    NewBit1            -= Bit2;
    NewBit2            = Bit1;
    NewBit2            += Bit2;
    Data[Ptr2]        = NewBit1;
    Data[Ptr2+Step] = NewBit2;
}
      }
  }
}
void printbuf(int16_t *Data, uint16_t Len, uint16_t Step){
  for(uint16_t i=0; i<Len; i++){
      if(i % (Step)== 0) printf("\n");
      printf("%d\t",Data[i]);
  }
  printf("\n");
}
// genera block code FEC
void BlockEncodeChar(int16_t *DataMatrix, uint8_t Input, uint16_t HadamardCodeSize){
  // pulisci buffer
  memset(DataMatrix, 0, HadamardCodeSize*sizeof(int16_t));
  // inserimento carattere nella matrice, alti negativi, bassi positivi
  // il valore massimo del dato e' 2 * size(matrice)
  if(Input < (HadamardCodeSize * 2)){
      if (Input < HadamardCodeSize) DataMatrix[Input] = 1;
      else DataMatrix[Input - HadamardCodeSize] = -1;
  }
 
  // codifica
  InverseFastHadamardTransform(DataMatrix, HadamardCodeSize); 
 
  // printbuf(FHT_Buffer,HadamardCodeSize,BitsPerCharacter);           
  //   
  // riduci a binario
  for (uint16_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){
      if(DataMatrix[TimeBit] < 0) DataMatrix[TimeBit] = 0;
  }
}
// decodifica block code FEC
uint8_t BlockDecodeChar(int16_t *DataMatrix, uint16_t HadamardCodeSize){
  for (uint16_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){
      if(DataMatrix[TimeBit] == 0) DataMatrix[TimeBit] = -1;
  }
 
  // decodifica
  FastHadamardTransform(DataMatrix, HadamardCodeSize);
 
  // printbuf(DataMatrix,HadamardCodeSize,BitsPerCharacter);                 
  // estrae dalla matrice
  int16_t Peak = 0;
  uint8_t PeakPos = 0;
  uint16_t SqrSum = 0;
  for (uint8_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){
      int16_t Signal = DataMatrix[TimeBit];
      SqrSum += Signal * Signal;
      if (fabs(Signal) > fabs(Peak)){
Peak = Signal;
PeakPos = TimeBit;
      }
  }
 
  uint8_t OutChar = PeakPos;
  if (Peak < 0) OutChar += HadamardCodeSize;
  SqrSum -= Peak * Peak;
  printf("OutChar %c (Peak %d, PeakPos %d, SqrSum %d)\n", OutChar, Peak, PeakPos, SqrSum);
  return OutChar;
}
// todo: rotazione posizione carattere, altrimenti un fischio distrugge un carattere
// impacca con alfabeto ortogonale a tempo
void OrthogonalPack(int16_t *DataMatrix, int16_t *ModulationSymbolsBuffer, uint8_t CharPosition, uint16_t HadamardCodeSize){
  for (uint8_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){
      ModulationSymbolsBuffer[TimeBit] |= (DataMatrix[TimeBit] << CharPosition);
  }
}
// disimpacca con alfabeto ortogonale a tempo
void OrthogonalUnPack(int16_t *DataMatrix, int16_t *ModulationSymbolsBuffer, uint8_t CharPosition, uint16_t HadamardCodeSize){
  for (uint8_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){
      DataMatrix[TimeBit] = (ModulationSymbolsBuffer[TimeBit] >> CharPosition) & 0b1;
  }
}
</source>

Revision as of 16:38, 11 June 2012

codice FEC

// Hadamard codec - gnugo@hacari.org - 06/2012

#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <string.h>
#include <stdio.h>

uint8_t BlockDecodeChar(int16_t *DataMatrix, uint16_t HadamardCodeSize);
void BlockEncodeChar(int16_t *DataMatrix, uint8_t Input, uint16_t HadamardCodeSize);

void main(void){  
   uint16_t HadamardCodeSize, 
     BitsPerModulationSymbol, 
     ModulationSymbols, 
     CharactersPerModulationBlock, 
     ModulationBlockSize;
   
   uint8_t BitsPerCharacter, 
     CharPosition;
   
   BitsPerCharacter = 7; // dimensione singolo dato in ingresso
   HadamardCodeSize = 1 << (BitsPerCharacter - 1); // dimensione  del singolo codice hadamard in uscita 2^(n-1)
   
   BitsPerModulationSymbol = 6; // bit rappresentati da un simbolo della modulazione
   ModulationSymbols = 1 << BitsPerModulationSymbol; // dimensione alfabeto modulato
   
   CharactersPerModulationBlock = BitsPerModulationSymbol; // caratteri in un blocco modulazione
   ModulationBlockSize = BitsPerModulationSymbol * HadamardCodeSize; // dimensioni blocco modulazione
   
   printf("HadamardCodeSize %u\n", HadamardCodeSize);  
   printf("ModulationSymbols %u\n", ModulationSymbols);  
   
   // buffer matrici 
   int16_t *FHT_Buffer;
   FHT_Buffer = malloc(HadamardCodeSize*sizeof(int16_t));

   // buffer modulazione 
   int16_t *ModulationSymbolsBuffer;
   ModulationSymbolsBuffer = malloc(HadamardCodeSize*sizeof(int16_t));

   // dato in ingresso
   unsigned char InString[16];
   strcpy(InString,"ciao mondo");  
   
   // impacchetta un modulation block
   for (uint8_t CharPosition = 0; CharPosition < BitsPerModulationSymbol; CharPosition++){
      printf("encoding char %c pos %d\n", InString[CharPosition], CharPosition);
      BlockEncodeChar(FHT_Buffer, InString[CharPosition], HadamardCodeSize);      
      OrthogonalPack(FHT_Buffer, ModulationSymbolsBuffer, CharPosition, HadamardCodeSize);
   }

   // pulisci buffer
   memset(FHT_Buffer, 0, HadamardCodeSize*sizeof(int16_t));
   printbuf(ModulationSymbolsBuffer, HadamardCodeSize, 8);
   
   //ModulationSymbolsBuffer[15] = ModulationSymbolsBuffer[25];
   //ModulationSymbolsBuffer[19] = ModulationSymbolsBuffer[22];
   
   // disimpacchetta un modulation block
   for (uint8_t CharPosition = 0; CharPosition < BitsPerModulationSymbol; CharPosition++){
      OrthogonalUnPack(FHT_Buffer, ModulationSymbolsBuffer, CharPosition, HadamardCodeSize);
      
      uint8_t OutChar;
      OutChar = BlockDecodeChar(FHT_Buffer, HadamardCodeSize);
      
   }
}

// Forward Fast Hadamard Transform
void FastHadamardTransform(int16_t *Data, uint16_t Len){ 
   int16_t Bit1, Bit2, NewBit1, NewBit2 = 0;
   for (uint16_t Step = 1; Step < Len; Step <<= 1) {
      for (uint16_t Ptr = 0; Ptr < Len; Ptr += (Step << 1)) { 
	 for (uint16_t Ptr2 = Ptr; Ptr2 - Ptr < Step; ++ Ptr2) {
	    Bit1       = Data[Ptr2];  
	    Bit2       = Data[Ptr2+Step];
	    NewBit1    = Bit2; 
	    NewBit1   += Bit1;
	    NewBit2    = Bit2; 
	    NewBit2   -= Bit1;
	    Data[Ptr2] = NewBit1;
	    Data[Ptr2+Step]=NewBit2;
	 }
      }
   }
}	

// Inverse Fast Hadamard Transform
void InverseFastHadamardTransform(int16_t *Data, uint16_t Len){
   int16_t Bit1, Bit2, NewBit1, NewBit2 = 0;
   for (uint16_t Step = (Len >> 1); Step; Step >>= 1) {
      for (uint16_t Ptr = 0; Ptr < Len; Ptr += (Step << 1)) {
	 for (uint16_t Ptr2 = Ptr; Ptr2 - Ptr < Step; ++ Ptr2) {
	    Bit1               = Data[Ptr2];
	    Bit2               = Data[Ptr2 + Step];
	    NewBit1            = Bit1;
	    NewBit1            -= Bit2;
	    NewBit2            = Bit1;
	    NewBit2            += Bit2;
	    Data[Ptr2]         = NewBit1;
	    Data[Ptr2+Step] = NewBit2;
	 }
      }
   }
}

void printbuf(int16_t *Data, uint16_t Len, uint16_t Step){
   for(uint16_t i=0; i<Len; i++){
      if(i % (Step)== 0) printf("\n");
      printf("%d\t",Data[i]);
   }
   printf("\n");
}

// genera block code FEC
void BlockEncodeChar(int16_t *DataMatrix, uint8_t Input, uint16_t HadamardCodeSize){
   // pulisci buffer
   memset(DataMatrix, 0, HadamardCodeSize*sizeof(int16_t));

   // inserimento carattere nella matrice, alti negativi, bassi positivi
   // il valore massimo del dato e' 2 * size(matrice)
   if(Input < (HadamardCodeSize * 2)){
      if (Input < HadamardCodeSize) DataMatrix[Input] = 1;
      else DataMatrix[Input - HadamardCodeSize] = -1;
   }
   
   // codifica
   InverseFastHadamardTransform(DataMatrix, HadamardCodeSize);  
   
   // printbuf(FHT_Buffer,HadamardCodeSize,BitsPerCharacter);            
   //    
   // riduci a binario
   for (uint16_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){
      if(DataMatrix[TimeBit] < 0) DataMatrix[TimeBit] = 0;
   }
}

// decodifica block code FEC
uint8_t BlockDecodeChar(int16_t *DataMatrix, uint16_t HadamardCodeSize){
   for (uint16_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){
      if(DataMatrix[TimeBit] == 0) DataMatrix[TimeBit] = -1;
   }
   
   // decodifica
   FastHadamardTransform(DataMatrix, HadamardCodeSize);
   
   // printbuf(DataMatrix,HadamardCodeSize,BitsPerCharacter);                  
   // estrae dalla matrice
   int16_t Peak = 0;
   uint8_t PeakPos = 0;
   uint16_t SqrSum = 0;
   for (uint8_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){
      int16_t Signal = DataMatrix[TimeBit];
      SqrSum += Signal * Signal;
      if (fabs(Signal) > fabs(Peak)){
	 Peak = Signal;
	 PeakPos = TimeBit;
      }
   }
   
   uint8_t OutChar = PeakPos;
   if (Peak < 0) OutChar += HadamardCodeSize;
   SqrSum -= Peak * Peak;
   printf("OutChar %c (Peak %d, PeakPos %d, SqrSum %d)\n", OutChar, Peak, PeakPos, SqrSum);
   return OutChar;
}

// todo: rotazione posizione carattere, altrimenti un fischio distrugge un carattere

// impacca con alfabeto ortogonale a tempo
void OrthogonalPack(int16_t *DataMatrix, int16_t *ModulationSymbolsBuffer, uint8_t CharPosition, uint16_t HadamardCodeSize){
   for (uint8_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){ 
      ModulationSymbolsBuffer[TimeBit] |= (DataMatrix[TimeBit] << CharPosition);
   }
}

// disimpacca con alfabeto ortogonale a tempo
void OrthogonalUnPack(int16_t *DataMatrix, int16_t *ModulationSymbolsBuffer, uint8_t CharPosition, uint16_t HadamardCodeSize){
   for (uint8_t TimeBit = 0; TimeBit < HadamardCodeSize; TimeBit++){ 
      DataMatrix[TimeBit] = (ModulationSymbolsBuffer[TimeBit] >> CharPosition) & 0b1;
   }
}