Index: trunk/AddOn/TAcq/brpaqu.cc
===================================================================
--- trunk/AddOn/TAcq/brpaqu.cc	(revision 3538)
+++ trunk/AddOn/TAcq/brpaqu.cc	(revision 3592)
@@ -11,26 +11,154 @@
 }
 
-BRPaquet::BRPaquet(Byte* src, Byte* dst, int paqsz)
+/* --Methode__ */
+BRPaquet::BRPaquet(Byte* src, Byte* dst, int paqsz, BRDataFmtConv fgswap)
+  // swapall = true -> on swap tout le paquet, sinon swap entete seulement
 {
   dst_ = dst;
   sz_ = paqsz;
-  if ((src==NULL)||(dst==NULL))  return;
-  // On copie l'entete sans swapper 
-  for(int k=0; k<BRHDRSIZE; k++)  dst_[k] = src[k];
-  // On copie la zone donnees en faisant un byte-swap correspondant a 4 octets 
-   for(int ka=BRHDRSIZE; ka<sz_-BRTRLSIZE; ka+=4) {
-    for(int kb=0; kb<4; kb++)
-      dst_[ka+kb] = src[ka+3-kb];
+  if ((src == NULL) || (dst == NULL)) return;
+  // Il faut mettre une protection (throw) si dst==NULL ou sz==0
+
+  UInt32* src32 = (UInt32*)src;
+  UInt32* dst32 = (UInt32*)dst;
+
+  switch ( fgswap ) {
+  case BR_DoNothing :  // rien a faire
+    break;
+  case BR_Copy : // copie directe 
+    memcpy(dst_, src, sz_); 
+    break;
+  case BR_Swap32 : // On swappe toutes les donnees du paquet 
+  //  les bytes sont dans l'ordre par paquet de 4 octets (Int32) , les deux Int32 de 
+  // On copie la zone donnees en faisant un byte-swap correspondant a 8 octets (4->8 Reza/firmware SGDMA) 
+    for(int ka=0; ka<sz_/4; ka+=2) {
+      dst32[ka] = src32[ka+1];
+      dst32[ka+1] = src32[ka];
+    }
+   
+    break;
+  case BR_SwapAll:
+  for(int ka=0; ka<sz_; ka+=8) {
+      for(int kb=0; kb<4; kb++) {
+        dst_[ka+kb] = src[ka+3-kb+4];    
+        dst_[ka+kb+4] = src[ka+3-kb];    
+      }
+    }
+    for(int ka=HeaderSize()+DataSize(); ka<sz_; ka+=8) {
+      for(int kb=0; kb<4; kb++) {
+	dst_[ka+kb] = src[ka+3-kb+4];    
+        dst_[ka+kb+4] = src[ka+3-kb];    
+      }
+    }
+    break;
+  case BR_SwapHDR :
+  case BR_FFTOneChan :
+  case BR_FFTTwoChan :
+    // ByteSwap 8 (4->8 Reza/firmware SGDMA) de l'enete 
+    for(int ka=0; ka<BRHDRSIZE; ka+=8) {
+      for(int kb=0; kb<4; kb++) {
+	dst_[ka+kb] = src[ka+3-kb+4];    
+        dst_[ka+kb+4] = src[ka+3-kb];    
+      }
+    }
+
+    if (fgswap == BR_FFTOneChan) ReorderFFTData(src+HeaderSize(), dst_+HeaderSize(), DataSize());
+    else if (fgswap == BR_FFTTwoChan) {
+      ReorderFFTData(src+HeaderSize(), dst_+HeaderSize(), DataSize()/2);
+      ReorderFFTData(src+HeaderSize()+DataSize()/2, dst_+HeaderSize()+DataSize()/2, DataSize()/2);
+    }
+    for(int ka=HeaderSize()+DataSize(); ka<sz_; ka+=8) {
+      for(int kb=0; kb<4; kb++) {
+	dst_[ka+kb] = src[ka+3-kb+4];    
+        dst_[ka+kb+4] = src[ka+3-kb];    
+      }
+    }
+    break;
+ 
+  case BR_FFTOneChan32 :
+  case BR_FFTTwoChan32 :
+    // on swappe tout  en attendant le swap general sinon il faut encore crÃ©er une fonctiondifferente de ReorderFFT
+    // swapp du header uniquement
+    for(int ka=0; ka<BRHDRSIZE/4; ka+=2) {
+      dst32[ka] = src32[ka+1];
+      dst32[ka+1] = src32[ka];
+    }
+  
+    // on reoordonne et on swappe en mem temps
+    if (fgswap == BR_FFTOneChan32) ReorderFFTData32(src+HeaderSize(), dst_+HeaderSize(), DataSize());
+    else if (fgswap == BR_FFTTwoChan32) {
+      ReorderFFTData32(src+HeaderSize(), dst_+HeaderSize(), DataSize()/2);
+      ReorderFFTData32(src+HeaderSize()+DataSize()/2, dst_+HeaderSize()+DataSize()/2, DataSize()/2);
+    }
+    // swap du trailler uniquement
+    for(int ka=(HeaderSize()+DataSize())/4;ka < sz_/4; ka+=2) {
+      dst32[ka] = src32[ka+1];
+      dst32[ka+1] = src32[ka];
+    }
+    
+  case BR_FFTOneChanNoSwap :
+  case BR_FFTTwoChanNoSwap :
+    // on a plus de swapdonc il faut copier dans dst
+    memcpy(dst_, src, sz_); 
+    // on reoordonne et on swappe en mem temps
+    if (fgswap == BR_FFTOneChanNoSwap) ReorderFFTDataNoSwap(src+HeaderSize(), dst_+HeaderSize(), DataSize());
+    else if (fgswap == BR_FFTTwoChanNoSwap) {
+      ReorderFFTDataNoSwap(src+HeaderSize(), dst_+HeaderSize(), DataSize()/2);
+      ReorderFFTDataNoSwap(src+HeaderSize()+DataSize()/2, dst_+HeaderSize()+DataSize()/2, DataSize()/2);
+    }
+    
+    break;
+  }  // Fin switch 
+
+}
+
+/* --Methode__ */
+BRPaquet::BRPaquet(Byte* srcdst, int paqsz)
+{
+  dst_ = srcdst;
+  sz_ = paqsz;
+  // Il faut mettre une protection (throw) si srcdst==NULL ou sz==0
+}
+
+
+/* --Methode__ */
+UInt16 BRPaquet::ChannelID()
+{
+
+  UInt16 ChnId=ChanId();
+  UInt16 ChpId=ChipId();
+ 
+     
+  if (ChpId == 2) 
+    {
+      if (ChnId == 1) ChnId = Ch3;
+      if (ChnId == 2) ChnId = Ch4;
+      if (ChnId == 3) ChnId = Ch3_4;
+    }
+  return(ChnId);
+}
+
+/* --Methode__ */
+UInt16 BRPaquet::ModeAcquisition()
+{
+  UInt16 ModAq;
+  printf("Mod Acq %x \n",ModeAcq());
+  ModAq = ((ModeAcq() & 0x30)>> 4);
+  return(ModAq);
+  
+}
+
+/* --Methode__ */
+void BRPaquet::Print(ostream & os, int nelt, bool prht)
+{
+  os << endl << "BRPaquet::Print() PaqSz=" << PaquetSize() << " DataSize=" << DataSize() 
+     << " dst_pointer=(hex)" << hex << (unsigned long)dst_ << dec << endl;
+  if (dst_ == NULL) {
+    os << " ...NULL paquet " << endl;
+    return; 
   }
-  // On copie le trailer sans swapper 
-  for(int k=sz_-1; k>=sz_-BRTRLSIZE; k--)  dst_[k] = src[k];
-
-}
-
-
-void BRPaquet::Print(ostream & os, int nelt, bool prht)
-{
-  os << "BRPaquet::Print() PaqSz=" << PaquetSize() << " DataSize=" << DataSize() 
-     << " dst_pointer=(hex)" << hex << (unsigned long)dst_ << dec << endl;
+
+  os << endl << " BR AcqMode: " << ModeAcquisition() << " Channel: " << ChannelID()  << endl;
+
   if (TrailerSize() > 0) 
     os << " ...HDRMarker(hex)=" << hex <<  HDRMarker() << " TRLMarker=" << TRLMarker() << dec << endl;
@@ -38,14 +166,15 @@
     os << " ...HDRMarker(hex)=" << hex <<  HDRMarker() << " NO TRLMarker=" << dec << endl;
   UInt32 tt1, tt2; 
-//  tt2 = (TimeTag()&0xFFFFFFFF00000000) >> 32; 
-  tt2=0; 
-  tt1 = TimeTag()&0x00000000FFFFFFFF;
-  os << " ...TimeTag (hex)=" << hex << TimeTag() << " TT1= " << tt1 << " TT2=" << tt2 << dec << endl;
+  tt2 = TimeTag1(); 
+  tt1 = TimeTag2();
+  os << " ...TimeTag (hex)=" << hex << "TimeTag()" << " TT1= " << tt1 << " TT2=" << tt2 << dec << endl;
+  // os << " ...Position Chariot (hex)= " << hex << PositionChariot() << endl;
   if (nelt > DataSize()/2) nelt = DataSize()/2;
   os << " ...Data[1.." << nelt << "]= ";
-  for(int k=0; k<nelt; k++) os << (int)(*(Data()+k)) << " , ";
+
+  for(int k=0; k<nelt; k++) os << (int)(*(Data1()+k)) << " , ";
   os << endl;
   os << " ...Data[" << DataSize()-nelt << ".." << DataSize()-1 << "]= ";
-  for(int k=DataSize()-nelt; k<DataSize(); k++) os << (int)(*(Data()+k)) << " , ";
+  for(int k=DataSize()-nelt; k<DataSize(); k++) os << (int)(*(Data1()+k)) << " , ";
   os << endl;
   if (prht) {   // Impression header / trailer
@@ -64,2 +193,238 @@
   }
 }
+
+
+// ---------------------------------------------------------
+//  **** REMARQUE   N/2+1 complexes -> N/2 complexes *****
+// N = Nb d'echantillon en temps -> N/2 paires (real, imag)
+// Il y a le continu, et N/2 frequences ---> N/2+1 nombres complexes,
+// mais avec la contrainte Z(0).imag = 0  Z(N/2).imag = 0 
+// f(i) i=0...N-1   ===> Z(k) ( Z complexe , k=0...N/2 )
+// mais avec la contrainte Z(0).imag = 0  Z(N/2).imag = 0 
+// On peut donc tout mettre ds N/2 complexes en choisissant 
+// de mettre ds Z(0).imag  Z(N/2).real 
+// ---------------------------------------------------------- 
+
+// Fonction magique qui donne le pointeur permettant de tenir compte du byte-swp sur 8 octets
+static inline int IndexByteSwap8(int idx) 
+{
+  return ( (idx-(idx%8))+(7-idx%8) ) ;
+}
+
+/* --Methode__ */
+void BRPaquet::ReorderFFTData(Byte* src, Byte* dst, int N)
+{
+  // Code recopie depuis /Dev/DisplayData/HistoWindow.cc 
+  // fonction TraceWind::DisplayBaoDatasFFT() et adapte aux structures BRPaquet et Cie 
+  // Modif par rapport au code de Bruno : N/2 elements complexes au lieu de N/2+1 - Remarque ci-dessus
+ 
+  int nCoef = N / 2; // to change
+  int debutIndex = N / 4 + 1;
+  int fifoSize =  N / 4 - 1;
+  int i; 
+
+  TwoByteComplex* dstcmplx = (TwoByteComplex*)dst;
+  
+  //   cout << " Display BAO Datas FFT (" << N << ")" << " : from 0 to "<< nCoef << endl;
+  //   cout << " Variables : debutIndex, fifoSize " << debutIndex << ", " << fifoSize << endl;
+
+  
+  // Sortie 1
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[debutIndex + i].realB() = src[IndexByteSwap8(2*i)];
+      dstcmplx[debutIndex + i].imagB() = src[IndexByteSwap8(2*i + 1)];
+    }
+
+  // element au milieu
+  dstcmplx[N / 4].realB() = src[IndexByteSwap8(2*fifoSize)];
+  dstcmplx[N / 4].imagB() = src[IndexByteSwap8(2*fifoSize + 1)];
+
+  // Sortie 2
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[fifoSize - i].realB() = src[IndexByteSwap8(nCoef + 2*i)];
+      dstcmplx[fifoSize - i].imagB() = src[IndexByteSwap8(nCoef + 2*i + 1)];
+    }
+
+  // k = 0 et k = N/2  
+  dstcmplx[0].realB() = src[IndexByteSwap8(N - 2)];
+  // Voir Remarque ci-dessus Z(N/2).real -> Z(0).image
+  dstcmplx[0].imagB() = src[IndexByteSwap8(N - 1)];  // Attention, on met ici la real(fmax)
+
+  return ; 
+}
+
+static inline int IndexByteSwap8_32(int idx) 
+{
+  return ( (idx-(idx%8))+((4+idx%8)%8) ) ;
+}
+
+void BRPaquet::ReorderFFTData32(Byte* src, Byte* dst, int N)
+{
+  // Code recopie depuis /Dev/DisplayData/HistoWindow.cc 
+  // fonction TraceWind::DisplayBaoDatasFFT() et adapte aux structures BRPaquet et Cie 
+  // Modif par rapport au code de Bruno : N/2 elements complexes au lieu de N/2+1 - Remarque ci-dessus
+
+  int nCoef = N / 2; // to change
+  int debutIndex = N / 4 + 1;
+  int fifoSize =  N / 4 - 1;
+  int i; 
+
+  TwoByteComplex* dstcmplx = (TwoByteComplex*)dst;
+  
+  //   cout << " Display BAO Datas FFT (" << N << ")" << " : from 0 to "<< nCoef << endl;
+  //   cout << " Variables : debutIndex, fifoSize " << debutIndex << ", " << fifoSize << endl;
+
+  
+  // Sortie 1
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[debutIndex + i].realB() = src[IndexByteSwap8_32(2*i)];
+      dstcmplx[debutIndex + i].imagB() = src[IndexByteSwap8_32(2*i + 1)];
+    }
+
+  // element au milieu
+  dstcmplx[N / 4].realB() = src[IndexByteSwap8_32(2*fifoSize)];
+  dstcmplx[N / 4].imagB() = src[IndexByteSwap8_32(2*fifoSize + 1)];
+
+  // Sortie 2
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[fifoSize - i].realB() = src[IndexByteSwap8_32(nCoef + 2*i)];
+      dstcmplx[fifoSize - i].imagB() = src[IndexByteSwap8_32(nCoef + 2*i + 1)];
+    }
+
+  // k = 0 et k = N/2  
+  dstcmplx[0].realB() = src[IndexByteSwap8_32(N - 2)];
+  // Voir Remarque ci-dessus Z(N/2).real -> Z(0).image
+  dstcmplx[0].imagB() = src[IndexByteSwap8_32(N - 1)];  // Attention, on met ici la real(fmax)
+
+  return ; 
+}
+void BRPaquet::ReorderFFTDataNoSwap(Byte* src, Byte* dst, int N)
+{
+  // Code recopie depuis /Dev/DisplayData/HistoWindow.cc 
+  // fonction TraceWind::DisplayBaoDatasFFT() et adapte aux structures BRPaquet et Cie 
+  // Modif par rapport au code de Bruno : N/2 elements complexes au lieu de N/2+1 - Remarque ci-dessus
+ 
+  int nCoef = N / 2; // to change
+  int debutIndex = N / 4 + 1;
+  int fifoSize =  N / 4 - 1;
+  int i; 
+
+  TwoByteComplex* dstcmplx = (TwoByteComplex*)dst;
+  
+  //   cout << " Display BAO Datas FFT (" << N << ")" << " : from 0 to "<< nCoef << endl;
+  //   cout << " Variables : debutIndex, fifoSize " << debutIndex << ", " << fifoSize << endl;
+
+  
+  // Sortie 1
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[debutIndex + i].realB() = src[(2*i)];
+      dstcmplx[debutIndex + i].imagB() = src[(2*i + 1)];
+    }
+
+  // element au milieu
+  dstcmplx[N / 4].realB() = src[(2*fifoSize)];
+  dstcmplx[N / 4].imagB() = src[(2*fifoSize + 1)];
+
+  // Sortie 2
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[fifoSize - i].realB() = src[(nCoef + 2*i)];
+      dstcmplx[fifoSize - i].imagB() = src[(nCoef + 2*i + 1)];
+    }
+
+  // k = 0 et k = N/2  
+  dstcmplx[0].realB() = src[(N - 2)];
+  // Voir Remarque ci-dessus Z(N/2).real -> Z(0).image
+  dstcmplx[0].imagB() = src[(N - 1)];  // Attention, on met ici la real(fmax)
+
+  return ; 
+}
+
+/* --Methode__ */
+const char* BRPaquet::FmtConvToString(BRDataFmtConv fgswap)
+{
+  const char * rs="";
+  switch ( fgswap ) {
+  case BR_DoNothing :  
+    rs = "BR_DoNothing";
+    break;
+  case BR_Copy : 
+    rs = "BR_Copy";
+    break;
+  case BR_SwapAll : 
+    rs = "BR_SwapAll";
+    break;
+  case BR_SwapHDR :
+    rs = "BR_SwapHDR";
+    break;
+  case BR_FFTOneChan :
+    rs = "BR_FFTOneChan";
+    break;
+  case BR_FFTTwoChan :
+    rs = "BR_FFTTwoChan";
+    break;
+  case BR_Swap32 :
+    rs = "BR_Swap32";
+    break;
+  case BR_FFTOneChan32 :
+    rs = "BR_FFTOneChan32";
+    break;
+  case BR_FFTTwoChan32 :
+    rs = "BR_FFTTwoChan32";
+    break;
+  case BR_FFTOneChanNoSwap :
+    rs = "BR_FFTOneChanNoSwap";
+    break;
+  case BR_FFTTwoChanNoSwap :
+    rs = "BR_FFTTwoChanNoSwap";
+    break;
+  default:
+    rs = "?????";
+    break;
+  }  // Fin switch 
+  return rs;
+}
+
+// --------------------------------------------------------------------------
+// Classe pour effectuer des verifications d'integrite sur les paquets/frames
+// --------------------------------------------------------------------------
+
+BRPaqChecker::BRPaqChecker()
+{
+  totnframes = 0;
+  nframeok = 0;
+  lostframes = 0;
+  frclst = 0;
+}
+
+BRPaqChecker::~BRPaqChecker()
+{
+}
+
+bool BRPaqChecker::Check(BRPaquet& paq)
+{
+  totnframes++; 
+  if (paq.HDRMarker() != 0x76543210) return false;
+  unsigned int curfc = paq.FrameCounter();
+  unsigned int delfc = 0;
+  if (nframeok > 0) {
+    if (curfc>frclst)  delfc = (curfc-frclst);
+    else delfc = (65535-frclst+curfc);
+    lostframes += (unsigned long long)delfc - 1;
+  }
+  nframeok++; frclst = curfc; 
+  return true;
+}
+
+ostream& BRPaqChecker::Print(ostream& os)
+{
+  os << "BRPaqChecker:  Tot.Nb.Frames.Proc=" << totnframes << " NbFrameOK=" << nframeok 
+     << " LostFrames=" << lostframes 
+     << " Loss=" << (double)lostframes*100./(double)totnframes << " %" << endl;
+  return os;
+}
