Statistics
| Branch: | Tag: | Revision:

root / volk / include / volk / volk_32f_s32f_calc_spectral_noise_floor_32f_a.h @ d825bb2b

History | View | Annotate | Download (6.4 kB)

1
#ifndef INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
2
#define INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
3
4
#include <volk/volk_common.h>
5
#include <inttypes.h>
6
#include <stdio.h>
7
8
#ifdef LV_HAVE_SSE
9
#include <xmmintrin.h>
10
/*!
11
  \brief Calculates the spectral noise floor of an input power spectrum
12
13
  Calculates the spectral noise floor of an input power spectrum by determining the mean of the input power spectrum, then recalculating the mean excluding any power spectrum values that exceed the mean by the spectralExclusionValue (in dB).  Provides a rough estimation of the signal noise floor.
14
15
  \param realDataPoints The input power spectrum
16
  \param num_points The number of data points in the input power spectrum vector
17
  \param spectralExclusionValue The number of dB above the noise floor that a data point must be to be excluded from the noise floor calculation - default value is 20
18
  \param noiseFloorAmplitude The noise floor of the input spectrum, in dB
19
*/
20
static inline void volk_32f_s32f_calc_spectral_noise_floor_32f_a_sse(float* noiseFloorAmplitude, const float* realDataPoints, const float spectralExclusionValue, const unsigned int num_points){
21
  unsigned int number = 0;
22
  const unsigned int quarterPoints = num_points / 4;
23
24
  const float* dataPointsPtr = realDataPoints;
25
  __VOLK_ATTR_ALIGNED(16) float avgPointsVector[4];
26
    
27
  __m128 dataPointsVal;
28
  __m128 avgPointsVal = _mm_setzero_ps();
29
  // Calculate the sum (for mean) for all points
30
  for(; number < quarterPoints; number++){
31
32
    dataPointsVal = _mm_load_ps(dataPointsPtr);
33
34
    dataPointsPtr += 4;
35
36
    avgPointsVal = _mm_add_ps(avgPointsVal, dataPointsVal);
37
  }
38
39
  _mm_store_ps(avgPointsVector, avgPointsVal);
40
41
  float sumMean = 0.0;
42
  sumMean += avgPointsVector[0];
43
  sumMean += avgPointsVector[1];
44
  sumMean += avgPointsVector[2];
45
  sumMean += avgPointsVector[3];
46
47
  number = quarterPoints * 4;
48
  for(;number < num_points; number++){
49
    sumMean += realDataPoints[number];
50
  }
51
52
  // calculate the spectral mean
53
  // +20 because for the comparison below we only want to throw out bins
54
  // that are significantly higher (and would, thus, affect the mean more
55
  const float meanAmplitude = (sumMean / ((float)num_points)) + spectralExclusionValue;
56
57
  dataPointsPtr = realDataPoints; // Reset the dataPointsPtr
58
  __m128 vMeanAmplitudeVector = _mm_set_ps1(meanAmplitude);
59
  __m128 vOnesVector = _mm_set_ps1(1.0);
60
  __m128 vValidBinCount = _mm_setzero_ps();
61
  avgPointsVal = _mm_setzero_ps();
62
  __m128 compareMask;
63
  number = 0;
64
  // Calculate the sum (for mean) for any points which do NOT exceed the mean amplitude
65
  for(; number < quarterPoints; number++){
66
67
    dataPointsVal = _mm_load_ps(dataPointsPtr);
68
69
    dataPointsPtr += 4;
70
71
    // Identify which items do not exceed the mean amplitude
72
    compareMask = _mm_cmple_ps(dataPointsVal, vMeanAmplitudeVector);
73
74
    // Mask off the items that exceed the mean amplitude and add the avg Points that do not exceed the mean amplitude
75
    avgPointsVal = _mm_add_ps(avgPointsVal, _mm_and_ps(compareMask, dataPointsVal));
76
      
77
    // Count the number of bins which do not exceed the mean amplitude
78
    vValidBinCount = _mm_add_ps(vValidBinCount, _mm_and_ps(compareMask, vOnesVector));
79
  }
80
    
81
  // Calculate the mean from the remaining data points
82
  _mm_store_ps(avgPointsVector, avgPointsVal);
83
84
  sumMean = 0.0;
85
  sumMean += avgPointsVector[0];
86
  sumMean += avgPointsVector[1];
87
  sumMean += avgPointsVector[2];
88
  sumMean += avgPointsVector[3];
89
90
  // Calculate the number of valid bins from the remaning count
91
  __VOLK_ATTR_ALIGNED(16) float validBinCountVector[4];
92
  _mm_store_ps(validBinCountVector, vValidBinCount);
93
94
  float validBinCount = 0;
95
  validBinCount += validBinCountVector[0];
96
  validBinCount += validBinCountVector[1];
97
  validBinCount += validBinCountVector[2];
98
  validBinCount += validBinCountVector[3];
99
100
  number = quarterPoints * 4;
101
  for(;number < num_points; number++){
102
    if(realDataPoints[number] <= meanAmplitude){
103
      sumMean += realDataPoints[number];
104
      validBinCount += 1.0;
105
    }
106
  }
107
    
108
  float localNoiseFloorAmplitude = 0;
109
  if(validBinCount > 0.0){
110
    localNoiseFloorAmplitude = sumMean / validBinCount;
111
  }
112
  else{
113
    localNoiseFloorAmplitude = meanAmplitude; // For the odd case that all the amplitudes are equal...
114
  }
115
116
  *noiseFloorAmplitude = localNoiseFloorAmplitude;
117
}
118
#endif /* LV_HAVE_SSE */
119
120
#ifdef LV_HAVE_GENERIC
121
/*!
122
  \brief Calculates the spectral noise floor of an input power spectrum
123
124
  Calculates the spectral noise floor of an input power spectrum by determining the mean of the input power spectrum, then recalculating the mean excluding any power spectrum values that exceed the mean by the spectralExclusionValue (in dB).  Provides a rough estimation of the signal noise floor.
125
126
  \param realDataPoints The input power spectrum
127
  \param num_points The number of data points in the input power spectrum vector
128
  \param spectralExclusionValue The number of dB above the noise floor that a data point must be to be excluded from the noise floor calculation - default value is 20
129
  \param noiseFloorAmplitude The noise floor of the input spectrum, in dB
130
*/
131
static inline void volk_32f_s32f_calc_spectral_noise_floor_32f_a_generic(float* noiseFloorAmplitude, const float* realDataPoints, const float spectralExclusionValue, const unsigned int num_points){
132
  float sumMean = 0.0;
133
  unsigned int number;
134
  // find the sum (for mean), etc
135
  for(number = 0; number < num_points; number++){
136
    // sum (for mean)
137
    sumMean += realDataPoints[number];
138
  }
139
140
  // calculate the spectral mean
141
  // +20 because for the comparison below we only want to throw out bins
142
  // that are significantly higher (and would, thus, affect the mean more)
143
  const float meanAmplitude = (sumMean / num_points) + spectralExclusionValue;
144
145
  // now throw out any bins higher than the mean
146
  sumMean = 0.0;
147
  unsigned int newNumDataPoints = num_points;
148
  for(number = 0; number < num_points; number++){
149
    if (realDataPoints[number] <= meanAmplitude)
150
      sumMean += realDataPoints[number];
151
    else
152
      newNumDataPoints--;
153
  }
154
155
  float localNoiseFloorAmplitude = 0.0;
156
  if (newNumDataPoints == 0)             // in the odd case that all
157
    localNoiseFloorAmplitude = meanAmplitude; // amplitudes are equal!
158
  else
159
    localNoiseFloorAmplitude = sumMean / ((float)newNumDataPoints);
160
161
  *noiseFloorAmplitude = localNoiseFloorAmplitude;
162
}
163
#endif /* LV_HAVE_GENERIC */
164
165
166
167
168
#endif /* INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H */