1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * [Sample Rate Estimator] 19 * This module periodically estimates the mean sampling rate of a uniformly 20 * sampled signal. Note, this estimator uses a floating point accumulator for 21 * the timing intervals. This trades-off some accumulation of finite precision 22 * error to enhance the range of estimated sampling rates and prevent overflow 23 * when an equivalent 32bit integer accumulator is used. In typical use cases 24 * (sample rates: 5Hz - 2kHz, num_intervals_to_collect 10 - 100), the sample 25 * rate accuracy is typically much better than 0.1Hz. 26 * 27 * FUNCTIONALITY: 28 * sampleRateEstimatorInit -- Initializes the estimator. Sets the number of time 29 * intervals require to compute the sample rate mean, and the upper limit for 30 * the acceptable time interval. 31 * 32 * new_sampling_rate_estimate_ready -- Check this boolean flag if polling for 33 * new estimates is desired. 34 * 35 * sampleRateEstimatorGetHz -- Returns the latest sample rate estimate and 36 * resets the polling flag. 37 * 38 * sampleRateEstimatorUpdate -- Processes new timestamp data and computes new 39 * sample rate estimates. 40 */ 41 42 #ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_SAMPLE_RATE_ESTIMATOR_SAMPLE_RATE_ESTIMATOR_H_ 43 #define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_SAMPLE_RATE_ESTIMATOR_SAMPLE_RATE_ESTIMATOR_H_ 44 45 #include <stdbool.h> 46 #include <stddef.h> 47 #include <stdint.h> 48 #include <sys/types.h> 49 50 #ifdef __cplusplus 51 extern "C" { 52 #endif 53 54 // Designates the value used to indicate an invalid sample rate estimate. 55 #define SAMPLE_RATE_ESTIMATOR_INVALID_SAMPLE_RATE_HZ (-1.0f) 56 57 // Sample rate estimator data structure. 58 struct SampleRateEstimator { 59 // Used to compute sample intervals to estimate the sampling rate. 60 uint64_t last_timestamp_nanos; 61 62 // Accumulator used for computing the mean sampling interval. 63 float interval_accumulator_nanos; 64 65 // The upper limit on the acceptance of valid time intervals (in nanoseconds). 66 // Larger time deltas result in a reset of the interval accumulator. 67 float max_interval_nanos; 68 69 // The most recent mean sampling rate estimate. 70 float mean_sampling_rate_estimate_hz; 71 72 /* 73 * The targeted number of time intervals required for a new sample rate mean 74 * calculation. 75 * 76 * NOTE: Assuming that the time interval noise is independent and identically 77 * distributed and drawn from a zero-mean normal distribution with variance 78 * 'Sigma^2'. The expected noise reduction is related to the choice of 79 * 'num_intervals_to_collect' as: 80 * 81 * Output RMS Noise = Sigma / sqrt(num_intervals_to_collect). 82 * 83 * Example, a value of 100 for a 100Hz signal would provide updates once every 84 * second and provide a 90% reduction (i.e., [1 - 1/sqrt(100)] * 100%) in time 85 * interval noise. 86 */ 87 size_t num_intervals_to_collect; 88 89 // The number of time intervals currently collected. 90 size_t num_intervals_collected; 91 92 // Polling flag used to signal that a new estimate is ready. This flag is 93 // reset when 'sampleRateEstimatorGetHz' is called. 94 bool new_sampling_rate_estimate_ready; 95 }; 96 97 // Initializes the sample rate estimator, sets the number of time intervals 98 // for the mean sample rate calculation, and defines the tolerable gap in timing 99 // data (in seconds). 100 void sampleRateEstimatorInit(struct SampleRateEstimator* sample_rate_estimator, 101 size_t num_intervals_to_collect, 102 float max_interval_sec); 103 104 // Rather than using a function to poll for new sample rate estimates, which 105 // would incur an additional function call, simply check 106 // 'new_sampling_rate_estimate_ready' directly. 107 108 // Returns the most recent sampling rate estimate, and resets the 109 // 'new_sampling_rate_estimate_ready' polling flag. Note, if polling is not 110 // used, one may access the sample rate estimate directly from the struct and 111 // avoid this function call. 112 float sampleRateEstimatorGetHz( 113 struct SampleRateEstimator* sample_rate_estimator); 114 115 // Takes in a new timestamp and updates the sampling rate estimator. 116 void sampleRateEstimatorUpdate( 117 struct SampleRateEstimator* sample_rate_estimator, 118 uint64_t timestamp_nanos); 119 120 #ifdef __cplusplus 121 } 122 #endif 123 124 #endif // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_SAMPLE_RATE_ESTIMATOR_SAMPLE_RATE_ESTIMATOR_H_ 125