GNU Radio 3.7.2 C++ API
volk_32f_s32f_calc_spectral_noise_floor_32f.h
Go to the documentation of this file.
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_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 */
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:27