GNU Radio 3.6.5 C++ API

volk_32f_s32f_calc_spectral_noise_floor_32f_a.h

Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
00002 #define INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H
00003 
00004 #include <volk/volk_common.h>
00005 #include <inttypes.h>
00006 #include <stdio.h>
00007 
00008 #ifdef LV_HAVE_SSE
00009 #include <xmmintrin.h>
00010 /*!
00011   \brief Calculates the spectral noise floor of an input power spectrum
00012 
00013   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.
00014 
00015   \param realDataPoints The input power spectrum
00016   \param num_points The number of data points in the input power spectrum vector
00017   \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
00018   \param noiseFloorAmplitude The noise floor of the input spectrum, in dB
00019 */
00020 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){
00021   unsigned int number = 0;
00022   const unsigned int quarterPoints = num_points / 4;
00023 
00024   const float* dataPointsPtr = realDataPoints;
00025   __VOLK_ATTR_ALIGNED(16) float avgPointsVector[4];
00026 
00027   __m128 dataPointsVal;
00028   __m128 avgPointsVal = _mm_setzero_ps();
00029   // Calculate the sum (for mean) for all points
00030   for(; number < quarterPoints; number++){
00031 
00032     dataPointsVal = _mm_load_ps(dataPointsPtr);
00033 
00034     dataPointsPtr += 4;
00035 
00036     avgPointsVal = _mm_add_ps(avgPointsVal, dataPointsVal);
00037   }
00038 
00039   _mm_store_ps(avgPointsVector, avgPointsVal);
00040 
00041   float sumMean = 0.0;
00042   sumMean += avgPointsVector[0];
00043   sumMean += avgPointsVector[1];
00044   sumMean += avgPointsVector[2];
00045   sumMean += avgPointsVector[3];
00046 
00047   number = quarterPoints * 4;
00048   for(;number < num_points; number++){
00049     sumMean += realDataPoints[number];
00050   }
00051 
00052   // calculate the spectral mean
00053   // +20 because for the comparison below we only want to throw out bins
00054   // that are significantly higher (and would, thus, affect the mean more
00055   const float meanAmplitude = (sumMean / ((float)num_points)) + spectralExclusionValue;
00056 
00057   dataPointsPtr = realDataPoints; // Reset the dataPointsPtr
00058   __m128 vMeanAmplitudeVector = _mm_set_ps1(meanAmplitude);
00059   __m128 vOnesVector = _mm_set_ps1(1.0);
00060   __m128 vValidBinCount = _mm_setzero_ps();
00061   avgPointsVal = _mm_setzero_ps();
00062   __m128 compareMask;
00063   number = 0;
00064   // Calculate the sum (for mean) for any points which do NOT exceed the mean amplitude
00065   for(; number < quarterPoints; number++){
00066 
00067     dataPointsVal = _mm_load_ps(dataPointsPtr);
00068 
00069     dataPointsPtr += 4;
00070 
00071     // Identify which items do not exceed the mean amplitude
00072     compareMask = _mm_cmple_ps(dataPointsVal, vMeanAmplitudeVector);
00073 
00074     // Mask off the items that exceed the mean amplitude and add the avg Points that do not exceed the mean amplitude
00075     avgPointsVal = _mm_add_ps(avgPointsVal, _mm_and_ps(compareMask, dataPointsVal));
00076 
00077     // Count the number of bins which do not exceed the mean amplitude
00078     vValidBinCount = _mm_add_ps(vValidBinCount, _mm_and_ps(compareMask, vOnesVector));
00079   }
00080 
00081   // Calculate the mean from the remaining data points
00082   _mm_store_ps(avgPointsVector, avgPointsVal);
00083 
00084   sumMean = 0.0;
00085   sumMean += avgPointsVector[0];
00086   sumMean += avgPointsVector[1];
00087   sumMean += avgPointsVector[2];
00088   sumMean += avgPointsVector[3];
00089 
00090   // Calculate the number of valid bins from the remaning count
00091   __VOLK_ATTR_ALIGNED(16) float validBinCountVector[4];
00092   _mm_store_ps(validBinCountVector, vValidBinCount);
00093 
00094   float validBinCount = 0;
00095   validBinCount += validBinCountVector[0];
00096   validBinCount += validBinCountVector[1];
00097   validBinCount += validBinCountVector[2];
00098   validBinCount += validBinCountVector[3];
00099 
00100   number = quarterPoints * 4;
00101   for(;number < num_points; number++){
00102     if(realDataPoints[number] <= meanAmplitude){
00103       sumMean += realDataPoints[number];
00104       validBinCount += 1.0;
00105     }
00106   }
00107 
00108   float localNoiseFloorAmplitude = 0;
00109   if(validBinCount > 0.0){
00110     localNoiseFloorAmplitude = sumMean / validBinCount;
00111   }
00112   else{
00113     localNoiseFloorAmplitude = meanAmplitude; // For the odd case that all the amplitudes are equal...
00114   }
00115 
00116   *noiseFloorAmplitude = localNoiseFloorAmplitude;
00117 }
00118 #endif /* LV_HAVE_SSE */
00119 
00120 #ifdef LV_HAVE_GENERIC
00121 /*!
00122   \brief Calculates the spectral noise floor of an input power spectrum
00123 
00124   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.
00125 
00126   \param realDataPoints The input power spectrum
00127   \param num_points The number of data points in the input power spectrum vector
00128   \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
00129   \param noiseFloorAmplitude The noise floor of the input spectrum, in dB
00130 */
00131 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){
00132   float sumMean = 0.0;
00133   unsigned int number;
00134   // find the sum (for mean), etc
00135   for(number = 0; number < num_points; number++){
00136     // sum (for mean)
00137     sumMean += realDataPoints[number];
00138   }
00139 
00140   // calculate the spectral mean
00141   // +20 because for the comparison below we only want to throw out bins
00142   // that are significantly higher (and would, thus, affect the mean more)
00143   const float meanAmplitude = (sumMean / num_points) + spectralExclusionValue;
00144 
00145   // now throw out any bins higher than the mean
00146   sumMean = 0.0;
00147   unsigned int newNumDataPoints = num_points;
00148   for(number = 0; number < num_points; number++){
00149     if (realDataPoints[number] <= meanAmplitude)
00150       sumMean += realDataPoints[number];
00151     else
00152       newNumDataPoints--;
00153   }
00154 
00155   float localNoiseFloorAmplitude = 0.0;
00156   if (newNumDataPoints == 0)             // in the odd case that all
00157     localNoiseFloorAmplitude = meanAmplitude; // amplitudes are equal!
00158   else
00159     localNoiseFloorAmplitude = sumMean / ((float)newNumDataPoints);
00160 
00161   *noiseFloorAmplitude = localNoiseFloorAmplitude;
00162 }
00163 #endif /* LV_HAVE_GENERIC */
00164 
00165 
00166 
00167 
00168 #endif /* INCLUDED_volk_32f_s32f_calc_spectral_noise_floor_32f_a_H */