* Tries to guess the clock by finding the smallest common interval. * Returns nanoseconds. */
| 179 | * Returns nanoseconds. |
| 180 | */ |
| 181 | FluxmapReader::ClockData FluxmapReader::guessClock( |
| 182 | double noiseFloorFactor, double signalLevelFactor) |
| 183 | { |
| 184 | ClockData data = {}; |
| 185 | |
| 186 | while (!eof()) |
| 187 | { |
| 188 | unsigned interval; |
| 189 | findEvent(F_BIT_PULSE, interval); |
| 190 | if (interval > 0xff) |
| 191 | continue; |
| 192 | data.buckets[interval]++; |
| 193 | } |
| 194 | |
| 195 | uint32_t max = |
| 196 | *std::max_element(std::begin(data.buckets), std::end(data.buckets)); |
| 197 | uint32_t min = |
| 198 | *std::min_element(std::begin(data.buckets), std::end(data.buckets)); |
| 199 | data.noiseFloor = min + (max - min) * noiseFloorFactor; |
| 200 | data.signalLevel = min + (max - min) * signalLevelFactor; |
| 201 | |
| 202 | /* Find a point solidly within the first pulse. */ |
| 203 | |
| 204 | int pulseindex = 0; |
| 205 | while (pulseindex < 256) |
| 206 | { |
| 207 | if (data.buckets[pulseindex] > data.signalLevel) |
| 208 | break; |
| 209 | pulseindex++; |
| 210 | } |
| 211 | if (pulseindex == -1) |
| 212 | return data; |
| 213 | |
| 214 | /* Find the upper and lower bounds of the pulse. */ |
| 215 | |
| 216 | int peaklo = pulseindex; |
| 217 | while (peaklo > 0) |
| 218 | { |
| 219 | if (data.buckets[peaklo] < data.noiseFloor) |
| 220 | break; |
| 221 | peaklo--; |
| 222 | } |
| 223 | |
| 224 | int peakhi = pulseindex; |
| 225 | while (peakhi < 255) |
| 226 | { |
| 227 | if (data.buckets[peakhi] < data.noiseFloor) |
| 228 | break; |
| 229 | peakhi++; |
| 230 | } |
| 231 | |
| 232 | /* Find the total accumulated size of the pulse. */ |
| 233 | |
| 234 | uint32_t total_size = 0; |
| 235 | for (int i = peaklo; i < peakhi; i++) |
| 236 | total_size += data.buckets[i]; |
| 237 | |
| 238 | /* Now find the median. */ |
no outgoing calls