signal_energy.c 6.38 KB
Newer Older
1 2
#include "defs.h"

3
#include "PHY/sse_intrin.h"
4 5 6 7 8 9

// Compute Energy of a complex signal vector, removing the DC component!
// input  : points to vector
// length : length of vector in complex samples

#define shift 4
10
//#define shift_DC 0
11

12
#if defined(__x86_64__) || defined(__i386__)
13
#ifdef LOCALIZATION
14 15
int32_t subcarrier_energy(int32_t *input,uint32_t length, int32_t *subcarrier_energy, uint16_t rx_power_correction)
{
16 17 18

  int32_t i, subcarrier_pwr;
  register __m64 mm0,mm1, subcarrier;
19
  subcarrier = _mm_setzero_si64();//_m_pxor(subcarrier,subcarrier);
20 21 22 23 24 25
  __m64 *in = (__m64 *)input;

#ifdef MAIN
  int16_t *printb;
#endif

26
  mm0 = _mm_setzero_si64();//pxor(mm0,mm0);
27

28 29 30
  for (i=0; i<length>>1; i++) {

    mm1 = in[i];
31 32 33 34 35 36 37 38 39 40
    mm1 = _m_pmaddwd(mm1,mm1);
    mm1 = _m_psradi(mm1,shift);// shift any 32 bits blocs of the word by the value shift
    subcarrier = mm1;
    subcarrier = _m_psrlqi(subcarrier,32);
    subcarrier = _m_paddd(subcarrier,mm1);
    subcarrier_pwr = _m_to_int(subcarrier);
    subcarrier_pwr<<=shift;
    subcarrier_pwr = (unsigned short) dB_fixed(subcarrier_pwr);
    subcarrier_energy[i] = subcarrier_pwr*rx_power_correction;
  }
41

roux's avatar
roux committed
42 43 44
  _mm_empty();
  _m_empty();

45 46 47
  return i;
}
#endif
48

49 50
int32_t signal_energy(int32_t *input,uint32_t length)
{
51

gauthier's avatar
gauthier committed
52 53
  int32_t i;
  int32_t temp,temp2;
54 55 56 57
  register __m64 mm0,mm1,mm2,mm3;
  __m64 *in = (__m64 *)input;


58 59
  mm0 = _mm_setzero_si64();//pxor(mm0,mm0);
  mm3 = _mm_setzero_si64();//pxor(mm3,mm3);
60

61 62 63
  for (i=0; i<length>>1; i++) {

    mm1 = in[i];
64 65 66 67
    mm2 = mm1;
    mm1 = _m_pmaddwd(mm1,mm1);
    mm1 = _m_psradi(mm1,shift);// shift any 32 bits blocs of the word by the value shift
    mm0 = _m_paddd(mm0,mm1);// add the two 64 bits words 4 bytes by 4 bytes
68
    //    mm2 = _m_psrawi(mm2,shift_DC);
69 70 71 72 73 74 75 76 77 78 79
    mm3 = _m_paddw(mm3,mm2);// add the two 64 bits words 2 bytes by 2 bytes
  }

  mm1 = mm0;
  mm0 = _m_psrlqi(mm0,32);
  mm0 = _m_paddd(mm0,mm1);
  temp = _m_to_int(mm0);
  temp/=length;
  temp<<=shift;   // this is the average of x^2

  // now remove the DC component
80

81 82 83 84 85 86

  mm2 = _m_psrlqi(mm3,32);
  mm2 = _m_paddw(mm2,mm3);
  mm2 = _m_pmaddwd(mm2,mm2);
  temp2 = _m_to_int(mm2);
  temp2/=(length*length);
87
  //  temp2<<=(2*shift_DC);
88 89
  temp -= temp2;

roux's avatar
roux committed
90 91 92
  _mm_empty();
  _m_empty();

93 94 95
  return((temp>0)?temp:1);
}

96 97
int32_t signal_energy_nodc(int32_t *input,uint32_t length)
{
98

gauthier's avatar
gauthier committed
99 100
  int32_t i;
  int32_t temp;
101
  register __m64 mm0,mm1;//,mm2,mm3;
102 103 104
  __m64 *in = (__m64 *)input;

#ifdef MAIN
gauthier's avatar
gauthier committed
105
  int16_t *printb;
106 107
#endif

108 109
  mm0 = _mm_setzero_si64();//_pxor(mm0,mm0);
  //  mm3 = _mm_setzero_si64();//pxor(mm3,mm3);
110

111 112 113
  for (i=0; i<length>>1; i++) {

    mm1 = in[i];
114 115 116 117 118 119 120
    mm1 = _m_pmaddwd(mm1,mm1);// SIMD complex multiplication
    mm1 = _m_psradi(mm1,shift);
    mm0 = _m_paddd(mm0,mm1);
    //    temp2 = mm0;
    //    printf("%d %d\n",((int *)&in[i])[0],((int *)&in[i])[1]);


gauthier's avatar
gauthier committed
121
    //    printb = (int16_t *)&mm2;
122 123 124 125 126 127
    //    printf("mm2 %d : %d %d %d %d\n",i,printb[0],printb[1],printb[2],printb[3]);


  }

  /*
128
  #ifdef MAIN
gauthier's avatar
gauthier committed
129
  printb = (int16_t *)&mm3;
130
  printf("%d %d %d %d\n",printb[0],printb[1],printb[2],printb[3]);
131
  #endif
132 133 134 135 136 137 138 139 140 141 142 143 144
  */
  mm1 = mm0;

  mm0 = _m_psrlqi(mm0,32);

  mm0 = _m_paddd(mm0,mm1);

  temp = _m_to_int(mm0);

  temp/=length;
  temp<<=shift;   // this is the average of x^2

#ifdef MAIN
145
  printf("E x^2 = %d\n",temp);
146 147 148 149 150 151 152 153 154
#endif
  _mm_empty();
  _m_empty();



  return((temp>0)?temp:1);
}

155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
#elif defined(__arm__)

int32_t signal_energy(int32_t *input,uint32_t length)
{

  int32_t i;
  int32_t temp,temp2;
  register int32x4_t tmpE,tmpDC;
  int32x2_t tmpE2,tmpDC2;
  int16x4_t *in = (int16x4_t *)input;

  tmpE  = vdupq_n_s32(0);
  tmpDC = vdupq_n_s32(0);

  for (i=0; i<length>>1; i++) {

    tmpE = vqaddq_s32(tmpE,vshrq_n_s32(vmull_s16(*in,*in),shift));
172
    //tmpDC = vaddw_s16(tmpDC,vshr_n_s16(*in++,shift_DC));
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229

  }

  tmpE2 = vpadd_s32(vget_low_s32(tmpE),vget_high_s32(tmpE));

  temp=(vget_lane_s32(tmpE2,0)+vget_lane_s32(tmpE2,1))/length;
  temp<<=shift;   // this is the average of x^2

  // now remove the DC component


  tmpDC2 = vpadd_s32(vget_low_s32(tmpDC),vget_high_s32(tmpDC));

  temp2=(vget_lane_s32(tmpDC2,0)+vget_lane_s32(tmpDC2,1))/(length*length);

  //  temp2<<=(2*shift_DC);
#ifdef MAIN
  printf("E x^2 = %d\n",temp);
#endif
  temp -= temp2;
#ifdef MAIN
  printf("(E x)^2=%d\n",temp2);
#endif

  return((temp>0)?temp:1);
}

int32_t signal_energy_nodc(int32_t *input,uint32_t length)
{

  int32_t i;
  int32_t temp;
  register int32x4_t tmpE;
  int32x2_t tmpE2;
  int16x4_t *in = (int16x4_t *)input;

  tmpE = vdupq_n_s32(0);

  for (i=0; i<length>>1; i++) {

    tmpE = vqaddq_s32(tmpE,vshrq_n_s32(vmull_s16(*in,*in),shift));

  }

  tmpE2 = vpadd_s32(vget_low_s32(tmpE),vget_high_s32(tmpE));

  temp=(vget_lane_s32(tmpE2,0)+vget_lane_s32(tmpE2,1))/length;
  temp<<=shift;   // this is the average of x^2

#ifdef MAIN
  printf("E x^2 = %d\n",temp);
#endif

  return((temp>0)?temp:1);
}

#endif
knopp's avatar
knopp committed
230
double signal_energy_fp(double *s_re[2],double *s_im[2],uint32_t nb_antennas,uint32_t length,uint32_t offset)
231
{
232

gauthier's avatar
gauthier committed
233
  int32_t aa,i;
234 235
  double V=0.0;

236 237 238
  for (i=0; i<length; i++) {
    for (aa=0; aa<nb_antennas; aa++) {
      V= V + (s_re[aa][i+offset]*s_re[aa][i+offset]) + (s_im[aa][i+offset]*s_im[aa][i+offset]);
239 240
    }
  }
241

242 243 244
  return(V/length/nb_antennas);
}

245 246
double signal_energy_fp2(struct complex *s,uint32_t length)
{
247

gauthier's avatar
gauthier committed
248
  int32_t i;
249 250
  double V=0.0;

251
  for (i=0; i<length; i++) {
252
    //    printf("signal_energy_fp2 : %f,%f => %f\n",s[i].x,s[i].y,V);
253 254 255 256
    //      V= V + (s[i].y*s[i].x) + (s[i].y*s[i].x);
    V= V + (s[i].x*s[i].x) + (s[i].y*s[i].y);
  }

257 258 259 260 261 262 263 264 265
  return(V/length);
}

#ifdef MAIN
#define LENGTH 256
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
266 267
main(int argc,char **argv)
{
268 269 270

  int input[LENGTH];
  int energy=0,dc_r=0,dc_i=0;
gauthier's avatar
gauthier committed
271
  int16_t s=1,i;
272 273 274
  int amp;

  amp = atoi(argv[1]);// arguments to integer
275

276 277 278
  if (argc>1)
    printf("Amp = %d\n",amp);

279
  for (i=0; i<LENGTH; i++) {
280
    s = -s;
gauthier's avatar
gauthier committed
281 282 283 284 285
    ((int16_t*)input)[2*i]     = 31 + (int16_t)(amp*sin(2*M_PI*i/LENGTH));
    ((int16_t*)input)[1+(2*i)] = 30 + (int16_t)(amp*cos(2*M_PI*i/LENGTH));
    energy += (((int16_t*)input)[2*i]*((int16_t*)input)[2*i]) + (((int16_t*)input)[1+(2*i)]*((int16_t*)input)[1+(2*i)]);
    dc_r += ((int16_t*)input)[2*i];
    dc_i += ((int16_t*)input)[1+(2*i)];
286 287 288


  }
289

290 291 292 293 294 295 296 297 298
  energy/=LENGTH;
  dc_r/=LENGTH;
  dc_i/=LENGTH;

  printf("signal_energy = %d dB(%d,%d,%d,%d)\n",dB_fixed(signal_energy(input,LENGTH)),signal_energy(input,LENGTH),energy-(dc_r*dc_r+dc_i*dc_i),energy,(dc_r*dc_r+dc_i*dc_i));
  printf("dc = (%d,%d)\n",dc_r,dc_i);
}
#endif