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 */ |