Il y avait des problèmes dans la libraire...

Dependencies:   ST_FREQUENCY_DIVIDER ST_I2S USBDEVICE

Fork of X_NUCLEO_CCA02M1 by ST

Revision:
16:4ab2eac7be21
Parent:
15:17bdadc6aa9c
Child:
20:9952bef19da1
--- a/Middlewares/OpenPDM2PCM/OpenPDMFilter.c	Tue May 02 18:06:58 2017 +0200
+++ b/Middlewares/OpenPDM2PCM/OpenPDMFilter.c	Wed May 03 18:10:29 2017 +0200
@@ -35,26 +35,24 @@
 
 /* Definitions ---------------------------------------------------------------*/
 
-#define maxVol 64
-#define FilterGain 16;
-#define RoundDiv(a, b) (((a)>0)?(((a)+(b)/2)/(b)):(((a)-(b)/2)/(b)))
+#define RoundDiv(a, b)    (((a)>0)?(((a)+(b)/2)/(b)):(((a)-(b)/2)/(b)))
 #define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
 
-#define SINCN_MAX 3
+#define VOLUME_MAX     64
+#define FILTER_GAIN    16
+
+#define SINCN_MAX       3
 #define DECIMATION_MAX 64
 
 
 /* Variables -----------------------------------------------------------------*/
 
-uint32_t DivideConst = 0;
-int64_t SubConst = 0;
+uint32_t div_const = 0;
+int64_t sub_const = 0;
+uint32_t sinc[DECIMATION_MAX * SINCN_MAX];
 uint32_t sinc1[DECIMATION_MAX];
-uint32_t sinc2[DECIMATION_MAX*2];
-uint32_t sinc3[DECIMATION_MAX*3];
-uint32_t sinc4[DECIMATION_MAX*4];
-uint32_t sinc[DECIMATION_MAX*5];              
-int64_t Z = 0;
-uint32_t coef[5][DECIMATION_MAX]; // Max sinc 5 with Param->Decimation = 128.
+uint32_t sinc2[DECIMATION_MAX * 2];
+uint32_t coef[SINCN_MAX][DECIMATION_MAX];
 #ifdef USE_LUT
 int32_t lut[256][DECIMATION_MAX / 8][SINCN_MAX];
 #endif
@@ -62,36 +60,47 @@
 
 /* Functions -----------------------------------------------------------------*/
 
-int64_t filterTable(uint8_t *data, uint8_t SincN, uint8_t decimation, uint8_t channels);
+int32_t filter_table(uint8_t *data, uint8_t sincn, uint8_t channels);
 
 void convolve(uint32_t Signal[/* SignalLen */], unsigned short SignalLen,
               uint32_t Kernel[/* KernelLen */], unsigned short KernelLen,
               uint32_t Result[/* SignalLen + KernelLen - 1 */]);
 
 #ifdef USE_LUT
-inline int64_t filterTable(uint8_t *data, uint8_t SincN, uint8_t decimation, uint8_t channels)
+int32_t filter_table_mono(uint8_t *data, uint8_t sincn)
+{
+  return (int32_t)
+    lut[data[0]][0][sincn] +
+    lut[data[1]][1][sincn] +
+    lut[data[2]][2][sincn] +
+    lut[data[3]][3][sincn] +
+    lut[data[4]][4][sincn] +
+    lut[data[5]][5][sincn] +
+    lut[data[6]][6][sincn] +
+    lut[data[7]][7][sincn];
+}
+int32_t filter_table_stereo(uint8_t *data, uint8_t sincn)
 {
-  uint8_t c, d;
-  uint16_t data_index = 0;
-  int64_t F = 0;
-
-  for (d = 0; d < (decimation >> 3); d++)
-  {
-    c = data[data_index];
-    F += lut[c][d][SincN];
-    data_index += channels;
-  }
-  return F;
+  return (int32_t)
+    lut[data[0]][0][sincn] +
+    lut[data[2]][1][sincn] +
+    lut[data[4]][2][sincn] +
+    lut[data[6]][3][sincn] +
+    lut[data[8]][4][sincn] +
+    lut[data[10]][5][sincn] +
+    lut[data[12]][6][sincn] +
+    lut[data[14]][7][sincn];
 }
+int32_t (* filter_tables[2]) (uint8_t *data, uint8_t sincn) = {filter_table_mono, filter_table_stereo};
 #else
-inline int64_t filterTable(uint8_t *data, uint8_t table, uint8_t decimation, uint8_t channels)
+int64_t filter_table(uint8_t *data, uint8_t sincn, uint8_t channels)
 {
   uint8_t c, i;
   uint16_t data_index = 0;
   uint32_t *coef_p = &coef[table][0];
   int64_t F = 0;
 
-  for (i = 0; i < decimation; i += 8)
+  for (i = 0; i < DECIMATION_MAX; i += 8)
   {
     c = data[data_index];
     F += ((c >> 7)       ) * coef_p[i    ] +
@@ -110,122 +119,39 @@
 
 void Open_PDM_Filter_Init(TPDMFilter_InitStruct *Param)
 {
-  uint16_t i,j;
+  uint16_t i, j;
   int64_t sum = 0;
-  Param->Coef[0] = Param->Coef[1] = Param->Coef[2] = Param->Coef[3] = Param->Coef[4] = 0;        
-  for(i=0;i<5;i++)
-  {
-    Param->bit[i]=0;
-  }
-  
-  for(i=0;i<Param->Decimation;i++)
+  for (i = 0; i < SINCN_MAX; i++)
   {
-    sinc1[i]=1;
-  }       
-  Param->OldOut = Param->OldIn = Param->OldZ = 0;
-  if(Param->LP_HZ!=0)
-  {
-    Param->LP_ALFA = (uint16_t)(Param->LP_HZ*256 / (Param->LP_HZ +  Param->Fs/(2*3.14)));
-  }else
-  {
-    Param->LP_ALFA = 0;
+    Param->Coef[i] = 0;
+    Param->bit[i] = 0;
   }
-  
-  if(Param->HP_HZ!=0)
-  {
-    Param->HP_ALFA = (uint16_t)(Param->Fs*256 / (2*3.14*Param->HP_HZ +  Param->Fs));
-  }else
+  for (i = 0; i < DECIMATION_MAX; i++)
   {
-    Param->HP_ALFA = 0;
+    sinc1[i] = 1;
   }
-  
-  switch(Param->SincN)
+
+  Param->OldOut = Param->OldIn = Param->OldZ = 0;
+  Param->LP_ALFA = (Param->LP_HZ != 0 ? (uint16_t) (Param->LP_HZ * 256 / (Param->LP_HZ + Param->Fs / (2 * 3.14))) : 0);
+  Param->HP_ALFA = (Param->HP_HZ != 0 ? (uint16_t) (Param->Fs * 256 / (2 * 3.14 * Param->HP_HZ + Param->Fs)) : 0);
+
+  Param->FilterLen = DECIMATION_MAX * 3;       
+  sinc[0] = 0;
+  sinc[DECIMATION_MAX * 3 - 1] = 0;      
+  convolve(sinc1, DECIMATION_MAX, sinc1, DECIMATION_MAX, sinc2);
+  convolve(sinc2, DECIMATION_MAX * 2 - 1, sinc1, DECIMATION_MAX, &sinc[1]);     
+  for(j = 0; j < 3; j++)
   {
-  case 1:
-    Param->FilterLen = Param->Decimation;
-    
-    for(i=0;i<Param->Decimation;i++)
+    for (i = 0; i < DECIMATION_MAX ;i++)
     {
-      coef[0][i]=1;
-      sum+= 1;
-    }
-    break;
-  case 2:
-    Param->FilterLen = Param->Decimation * 2;
-    
-    sinc[0] = 0;
-    
-    convolve(sinc1, Param->Decimation,sinc1,Param->Decimation,&sinc[1]);
-    
-    for(j=0;j<2;j++)
-    {
-      for(i=0;i<Param->Decimation;i++)
-      {
-        coef[j][i] = sinc[j*Param->Decimation+i];
-        sum+= sinc[j*Param->Decimation+i];
-      }
+      coef[j][i] = sinc[j * DECIMATION_MAX + i];
+      sum += sinc[j * DECIMATION_MAX + i];
     }
-    
-    break;
-  case 3:
-    Param->FilterLen = Param->Decimation * 3; 			
-    sinc[0] = 0;
-    sinc[Param->Decimation*3-1] = 0;			
-    convolve(sinc1, Param->Decimation,sinc1,Param->Decimation,sinc2);
-    convolve(sinc2, Param->Decimation*2-1,sinc1,Param->Decimation,&sinc[1]);			
-    for(j=0;j<3;j++)
-    {
-      for(i=0;i<Param->Decimation;i++)
-      {
-        coef[j][i] = sinc[j*Param->Decimation+i];
-        sum+= sinc[j*Param->Decimation+i];
-      }
-    }			
-    break;
-  case 4:
-    Param->FilterLen =  Param->Decimation * 4; 			
-    sinc[0] = 0;
-    sinc[1] = 0;
-    sinc[Param->Decimation*4-1] = 0;
-    convolve(sinc1, Param->Decimation,sinc1,Param->Decimation,sinc2);
-    convolve(sinc2, Param->Decimation*2-1,sinc1,Param->Decimation,sinc3);
-    convolve(sinc3, Param->Decimation*3-2,sinc1,Param->Decimation,&sinc[2]);			
-    for(j=0;j<4;j++)
-    {
-      for(i=0;i<Param->Decimation;i++)
-      {
-        coef[j][i] = sinc[j*Param->Decimation+i];
-        sum+= sinc[j*Param->Decimation+i];
-      }
-    }
-    
-    break;
-  case 5:
-    Param->FilterLen = Param->Decimation*5;  // Dec * 5 - 2			
-    sinc[0] = 0;
-    sinc[1] = 0;
-    sinc[Param->Decimation*5-2] = 0;
-    sinc[Param->Decimation*5-1] = 0;
-    
-    convolve(sinc1, Param->Decimation,sinc1,Param->Decimation,sinc2);
-    convolve(sinc2, Param->Decimation*2-1,sinc1,Param->Decimation,sinc3);
-    convolve(sinc3, Param->Decimation*3-2,sinc1,Param->Decimation,sinc4);
-    convolve(sinc4, Param->Decimation*4-3,sinc1,Param->Decimation,&sinc[2]);
-    
-    for(j=0;j<5;j++)
-    {
-      for(i=0;i<Param->Decimation;i++)
-      {
-        coef[j][i] = sinc[j*Param->Decimation+i];
-        sum+= sinc[j*Param->Decimation+i];
-      }
-    }			
-    break;
   }
-  SubConst = sum  / 2;
-  DivideConst = SubConst*maxVol/32768/FilterGain;
-  if (DivideConst == 0)
-    DivideConst = 1;
+
+  sub_const = sum >> 1;
+  div_const = sub_const * VOLUME_MAX / 32768 / FILTER_GAIN;
+  div_const = (div_const == 0 ? 1 : div_const);
 
 #ifdef USE_LUT
   /* Look-Up Table. */
@@ -268,72 +194,50 @@
   }
 }
 
-void Open_PDM_Filter(uint8_t* data, uint16_t* dataOut, uint16_t MicGain, TPDMFilter_InitStruct *Param)
+void Open_PDM_Filter(uint8_t* data, uint16_t* dataOut, uint16_t volume, TPDMFilter_InitStruct *Param)
 {
-  uint32_t i;
+  uint8_t i, data_out_index;
+  uint8_t decimation = DECIMATION_MAX;
+  uint8_t channels = Param->In_MicChannels;
+  uint8_t data_inc = ((decimation >> 3) * channels);
+  int64_t Z, Z0, Z1, Z2;
   int64_t OldOut, OldIn, OldZ;       
-  OldOut=Param->OldOut;
-  OldIn=Param->OldIn;
-  OldZ=Param->OldZ;
-  
-  for (i = 0; i < Param->Fs/1000; i++) 
+
+  OldOut = Param->OldOut;
+  OldIn = Param->OldIn;
+  OldZ = Param->OldZ;
+
+  for (i = 0, data_out_index = 0; i < Param->Fs / 1000; i++, data_out_index += channels) 
   {
-    switch(Param->SincN)
-    {
-    case 1:
-      Z = filterTable(data, 0, Param->Decimation, Param->In_MicChannels);
-      break;
-    case 2:
-      Z = Param->Coef[0] + filterTable(data, 1, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[0] = filterTable(data, 0, Param->Decimation, Param->In_MicChannels);
-      break;
-    case 3:
-      Z = Param->Coef[1] + filterTable(data, 2, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[1] = Param->Coef[0] + filterTable(data, 1, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[0] = filterTable(data, 0, Param->Decimation, Param->In_MicChannels);
-      break;
-    case 4:
-      Z = Param->Coef[2] + filterTable(data, 3, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[2] = Param->Coef[1] + filterTable(data, 2, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[1] = Param->Coef[0] + filterTable(data, 1, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[0] = filterTable(data, 0, Param->Decimation, Param->In_MicChannels);
-      break;			
-    case 5:
-      Z = Param->Coef[3] + filterTable(data, 4, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[3] = Param->Coef[2] + filterTable(data, 3, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[2] = Param->Coef[1] + filterTable(data, 2, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[1] = Param->Coef[0] + filterTable(data, 1, Param->Decimation, Param->In_MicChannels);
-      Param->Coef[0] = filterTable(data, 0, Param->Decimation, Param->In_MicChannels);
-      break;	
-    }
-    
-    Z -= SubConst;
-    
-    if (Param->HP_ALFA!= 0)
-    {
-      OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn))/256;
-      OldIn = Z;
-      Z = OldOut;
-    }
-    
-    if (Param->LP_ALFA != 0)
-    {
-      OldZ = ((256-Param->LP_ALFA)*OldZ+Param->LP_ALFA*Z)/256;
-      Z = OldZ;
-    }
-    
-    //                if(Param->SincN>=3){
-    //                  Z = RoundDiv(Z, DivideConst);
-    //                  Z *= MicGain;
-    //                }else{
-    Z *= MicGain;
-    Z = RoundDiv(Z, DivideConst);
-    //                }   
-    Z = SaturaLH(Z, -32700, 32700); // saturation		
-    dataOut[i*Param->Out_MicChannels] = Z ;                  
-    data += ((Param->Decimation / 8) * Param->In_MicChannels);
-  }        
-  Param->OldOut=OldOut;
-  Param->OldIn=OldIn;
-  Param->OldZ=OldZ;
+#ifdef USE_LUT
+    Z0 = filter_tables[channels - 1](data, 0);
+    Z1 = filter_tables[channels - 1](data, 1);
+    Z2 = filter_tables[channels - 1](data, 2);
+#else
+    Z0 = filter_table(data, 0, channels);
+    Z1 = filter_table(data, 1, channels);
+    Z2 = filter_table(data, 2, channels);
+#endif
+
+    Z = Param->Coef[1] + Z2 - sub_const;
+    Param->Coef[1] = Param->Coef[0] + Z1;
+    Param->Coef[0] = Z0;
+
+    OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8;
+    OldIn = Z;
+    Z = OldOut;
+    OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * Z) >> 8;
+    Z = OldZ;
+
+    Z *= volume;
+    Z = RoundDiv(Z, div_const);
+    Z = SaturaLH(Z, -32700, 32700);
+
+    dataOut[data_out_index] = Z;
+    data += data_inc;
+  }
+
+  Param->OldOut = OldOut;
+  Param->OldIn = OldIn;
+  Param->OldZ = OldZ;
 }