GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_32f_s32f_calc_spectral_noise_floor_32f.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2014 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
24 #define INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
25 
26 #include <volk/volk_common.h>
27 #include <inttypes.h>
28 #include <stdio.h>
29 
30 #ifdef LV_HAVE_SSE
31 #include <xmmintrin.h>
32 /*!
33  \brief Calculates the spectral noise floor of an input power spectrum
34 
35  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.
36 
37  \param realDataPoints The input power spectrum
38  \param num_points The number of data points in the input power spectrum vector
39  \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
40  \param noiseFloorAmplitude The noise floor of the input spectrum, in dB
41 */
42 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){
43  unsigned int number = 0;
44  const unsigned int quarterPoints = num_points / 4;
45 
46  const float* dataPointsPtr = realDataPoints;
47  __VOLK_ATTR_ALIGNED(16) float avgPointsVector[4];
48 
49  __m128 dataPointsVal;
50  __m128 avgPointsVal = _mm_setzero_ps();
51  // Calculate the sum (for mean) for all points
52  for(; number < quarterPoints; number++){
53 
54  dataPointsVal = _mm_load_ps(dataPointsPtr);
55 
56  dataPointsPtr += 4;
57 
58  avgPointsVal = _mm_add_ps(avgPointsVal, dataPointsVal);
59  }
60 
61  _mm_store_ps(avgPointsVector, avgPointsVal);
62 
63  float sumMean = 0.0;
64  sumMean += avgPointsVector[0];
65  sumMean += avgPointsVector[1];
66  sumMean += avgPointsVector[2];
67  sumMean += avgPointsVector[3];
68 
69  number = quarterPoints * 4;
70  for(;number < num_points; number++){
71  sumMean += realDataPoints[number];
72  }
73 
74  // calculate the spectral mean
75  // +20 because for the comparison below we only want to throw out bins
76  // that are significantly higher (and would, thus, affect the mean more
77  const float meanAmplitude = (sumMean / ((float)num_points)) + spectralExclusionValue;
78 
79  dataPointsPtr = realDataPoints; // Reset the dataPointsPtr
80  __m128 vMeanAmplitudeVector = _mm_set_ps1(meanAmplitude);
81  __m128 vOnesVector = _mm_set_ps1(1.0);
82  __m128 vValidBinCount = _mm_setzero_ps();
83  avgPointsVal = _mm_setzero_ps();
84  __m128 compareMask;
85  number = 0;
86  // Calculate the sum (for mean) for any points which do NOT exceed the mean amplitude
87  for(; number < quarterPoints; number++){
88 
89  dataPointsVal = _mm_load_ps(dataPointsPtr);
90 
91  dataPointsPtr += 4;
92 
93  // Identify which items do not exceed the mean amplitude
94  compareMask = _mm_cmple_ps(dataPointsVal, vMeanAmplitudeVector);
95 
96  // Mask off the items that exceed the mean amplitude and add the avg Points that do not exceed the mean amplitude
97  avgPointsVal = _mm_add_ps(avgPointsVal, _mm_and_ps(compareMask, dataPointsVal));
98 
99  // Count the number of bins which do not exceed the mean amplitude
100  vValidBinCount = _mm_add_ps(vValidBinCount, _mm_and_ps(compareMask, vOnesVector));
101  }
102 
103  // Calculate the mean from the remaining data points
104  _mm_store_ps(avgPointsVector, avgPointsVal);
105 
106  sumMean = 0.0;
107  sumMean += avgPointsVector[0];
108  sumMean += avgPointsVector[1];
109  sumMean += avgPointsVector[2];
110  sumMean += avgPointsVector[3];
111 
112  // Calculate the number of valid bins from the remaning count
113  __VOLK_ATTR_ALIGNED(16) float validBinCountVector[4];
114  _mm_store_ps(validBinCountVector, vValidBinCount);
115 
116  float validBinCount = 0;
117  validBinCount += validBinCountVector[0];
118  validBinCount += validBinCountVector[1];
119  validBinCount += validBinCountVector[2];
120  validBinCount += validBinCountVector[3];
121 
122  number = quarterPoints * 4;
123  for(;number < num_points; number++){
124  if(realDataPoints[number] <= meanAmplitude){
125  sumMean += realDataPoints[number];
126  validBinCount += 1.0;
127  }
128  }
129 
130  float localNoiseFloorAmplitude = 0;
131  if(validBinCount > 0.0){
132  localNoiseFloorAmplitude = sumMean / validBinCount;
133  }
134  else{
135  localNoiseFloorAmplitude = meanAmplitude; // For the odd case that all the amplitudes are equal...
136  }
137 
138  *noiseFloorAmplitude = localNoiseFloorAmplitude;
139 }
140 #endif /* LV_HAVE_SSE */
141 
142 #ifdef LV_HAVE_GENERIC
143 /*!
144  \brief Calculates the spectral noise floor of an input power spectrum
145 
146  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.
147 
148  \param realDataPoints The input power spectrum
149  \param num_points The number of data points in the input power spectrum vector
150  \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
151  \param noiseFloorAmplitude The noise floor of the input spectrum, in dB
152 */
153 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){
154  float sumMean = 0.0;
155  unsigned int number;
156  // find the sum (for mean), etc
157  for(number = 0; number < num_points; number++){
158  // sum (for mean)
159  sumMean += realDataPoints[number];
160  }
161 
162  // calculate the spectral mean
163  // +20 because for the comparison below we only want to throw out bins
164  // that are significantly higher (and would, thus, affect the mean more)
165  const float meanAmplitude = (sumMean / num_points) + spectralExclusionValue;
166 
167  // now throw out any bins higher than the mean
168  sumMean = 0.0;
169  unsigned int newNumDataPoints = num_points;
170  for(number = 0; number < num_points; number++){
171  if (realDataPoints[number] <= meanAmplitude)
172  sumMean += realDataPoints[number];
173  else
174  newNumDataPoints--;
175  }
176 
177  float localNoiseFloorAmplitude = 0.0;
178  if (newNumDataPoints == 0) // in the odd case that all
179  localNoiseFloorAmplitude = meanAmplitude; // amplitudes are equal!
180  else
181  localNoiseFloorAmplitude = sumMean / ((float)newNumDataPoints);
182 
183  *noiseFloorAmplitude = localNoiseFloorAmplitude;
184 }
185 #endif /* LV_HAVE_GENERIC */
186 
187 
188 
189 
190 #endif /* INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H */
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:27