| 
									
										
										
										
											2022-07-20 09:07:00 +02:00
										 |  |  | // Copyright 2020 Mobilinkd LLC.
 | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <array>
 | 
					
						
							|  |  |  | #include <algorithm>
 | 
					
						
							|  |  |  | #include <cassert>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-04 23:03:07 +02:00
										 |  |  | namespace modemm17 | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Estimate the phase of a sample by estimating the | 
					
						
							|  |  |  |  * tangent of the sample point.  This is done by computing | 
					
						
							|  |  |  |  * the magnitude difference of the previous and following | 
					
						
							|  |  |  |  * samples.  We do not correct for 0-crossing errors because | 
					
						
							|  |  |  |  * these errors have not affected the performance of clock | 
					
						
							|  |  |  |  * recovery. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | struct PhaseEstimator | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-06-09 20:12:35 +02:00
										 |  |  |     using float_type = float; | 
					
						
							|  |  |  |     using samples_t = std::array<float, 3>;    // 3 samples in length
 | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     float_type dx_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-09 20:12:35 +02:00
										 |  |  |     PhaseEstimator(float sample_rate, float symbol_rate) | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  |     : dx_(2.0 * symbol_rate / sample_rate) | 
					
						
							|  |  |  |     {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * This performs a rolling estimate of the phase. | 
					
						
							| 
									
										
										
										
											2022-06-09 20:12:35 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  |      * @param samples are three samples centered around the current sample point | 
					
						
							|  |  |  |      *  (t-1, t, t+1). | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     float_type operator()(const samples_t& samples) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         assert(dx_ > 0.0); | 
					
						
							| 
									
										
										
										
											2022-06-09 20:12:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         float ratio = ((samples.at(2) - samples.at(0)) / 3.0) / dx_; | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  |         // Clamp +/-5.
 | 
					
						
							| 
									
										
										
										
											2022-06-09 20:12:35 +02:00
										 |  |  |         ratio = std::min(float(5.0), ratio); | 
					
						
							|  |  |  |         ratio = std::max(float(-5.0), ratio); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  |         return ratio; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-04 23:03:07 +02:00
										 |  |  | } // modemm17
 |