GCC Code Coverage Report


Directory: ./
File: channeloutput/stringtesters/PixelCountStringTester.h
Date: 2026-10-29 08:11:58
Exec Total Coverage
Lines: 4 4 100.0%
Functions: 2 2 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 #pragma once
2 /*
3 * This file is part of the Falcon Player (FPP) and is Copyright (C)
4 * 2013-2022 by the Falcon Player Developers.
5 *
6 * The Falcon Player (FPP) is free software, and is covered under
7 * multiple Open Source licenses. Please see the included 'LICENSES'
8 * file for descriptions of what files are covered by each license.
9 *
10 * This source file is covered under the GPL v2 as described in the
11 * included LICENSE.GPL file.
12 */
13
14 #include "PixelStringTester.h"
15 #include <cstdint>
16 #include <vector>
17
18 class PixelCountPixelStringTester : public PixelStringTester {
19 protected:
20 4692 PixelCountPixelStringTester(bool byString) :
21 4692 PixelStringTester(), m_byString(byString) {}
22
23 const bool m_byString;
24
25 public:
26 virtual uint8_t* createTestData(PixelString* ps, int cycleCount, float percentOfCycle, uint8_t* inChannelData, uint32_t& newLen) override;
27
28 static PixelCountPixelStringTester INSTANCE_BYSTRING;
29 static PixelCountPixelStringTester INSTANCE_BYPORT;
30 };
31
32 // Counts the pixels on each port from its current sensor.
33 //
34 // One sensor group at a time (OutputMonitor::lockToGroup), every port in the
35 // group searched in parallel. Each measurement reads the port dark, then
36 // with a pattern lit, then dark again, and uses the lit reading less the
37 // mean of the dark ones: a port's dark current climbs for a while after it
38 // powers on, and a string powered at both ends does not return to the same
39 // dark current once lit. Pixels are only ever lit in windows of WINDOW at
40 // full white, or one at a time at the very end: enough current for a seed
41 // pixel to register, too little to reach the top of the sensor's range.
42 //
43 // A window is lit if it draws more than half what a pixel does, taken from
44 // the windows the search has proven full, so nothing depends on a fixed mA
45 // threshold. A measurement is only decided once it clears that by twice its
46 // uncertainty, worked out from the spread of the port's readings and how far
47 // the dark current moved; until then it is taken again. A seed pixel draws
48 // less than a noisy sensor's spread, so the readings, not a fixed number of
49 // them, decide how long a port takes.
50 //
51 // The end is found by doubling then halving the window position, and then
52 // pixel by pixel inside the last window, starting where its current puts
53 // the end. Null nodes are counted as the pixels they are, and taken off the
54 // count reported.
55 class CurrentBasedPixelCountPixelStringTester : public PixelStringTester {
56 public:
57 static CurrentBasedPixelCountPixelStringTester INSTANCE;
58
59 enum Status {
60 NotRun,
61 Running,
62 Complete
63 };
64 Status getCurrentStatus() const;
65
66 protected:
67 2346 CurrentBasedPixelCountPixelStringTester() :
68 2346 PixelStringTester() {}
69
70 struct PortSearch {
71 int configured = -1; // pixels, as configured
72 int nulls = 0; // null nodes configured on the port
73 int maxPixels = 0; // the furthest this port is searched, on the wire
74 bool testing = false;
75 int phase = 0;
76 float base = 0; // mA, port dark
77 float perPixel = 0; // mA one pixel adds at full white
78 std::vector<float> fullWindows; // windows a later lit one proved full
79 std::vector<float> spreads; // of each reading, for the sensor's noise
80 int lo = 0; // a window start known to hold pixels
81 int hi = 0; // a window start known to hold none
82 float loCurrent = 0;
83 int litPixel = 0; // finding the last pixel: one known lit...
84 int unlitPixel = 0; // ...one known not...
85 int guess = 0; // ...and where the current puts the end
86 int count = -1; // the answer, once known
87 int repeats = 0; // readings of an unclear measurement so far
88 float dSum = 0;
89 float errSq = 0;
90 int litStart = 0; // what this port shows now
91 int litLen = 0;
92 std::vector<float> samples;
93 std::vector<float> darkSamples; // before the lit reading
94 std::vector<float> darkAfterSamples; // and after it
95 };
96 std::vector<PortSearch> ports;
97
98 int state = -1;
99 int lastCycleCount = 0;
100 int curGroup = 0;
101 uint32_t frameInMeasure = 0;
102 uint32_t sampleFrames = 0;
103 // each measurement reads the port dark, lit, then dark again
104 int part = 0;
105 uint64_t stateStartMS = 0;
106
107 void startGroup();
108 bool step(PortSearch& p, int port, float d, float err);
109 void measureWindow(PortSearch& p, int start, int len);
110
111 public:
112 virtual void prepareTestData(int cycleCount, float percentOfCycle) override;
113 virtual uint8_t* createTestData(PixelString* ps, int cycleCount, float percentOfCycle, uint8_t* inChannelData, uint32_t& newLen) override;
114 };
115