GNU Radio 3.6.5 C++ API
|
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 */