MCPcopy Create free account
hub / github.com/FastLED/FastLED / runDetectorTest

Function runDetectorTest

tests/fl/audio/detector/downbeat.hpp:134–284  ·  view source on GitHub ↗

Helper: Run detector on a beat sequence and collect metrics enableLogging: Print detailed confidence and detection info for analysis warmupMeasures: Number of measures to run before collecting metrics (default: 1)

Source from the content-addressed store, hash-verified

132// enableLogging: Print detailed confidence and detection info for analysis
133// warmupMeasures: Number of measures to run before collecting metrics (default: 1)
134DetectionMetrics runDetectorTest(audio::detector::Downbeat& detector,
135 const vector<GroundTruthMarker>& groundTruth,
136 float accentMultiplier = 1.0f,
137 int timingJitterMs = 0,
138 bool enableLogging = false,
139 int warmupMeasures = 1) {
140 DetectionMetrics metrics;
141 u32 timestamp = 0;
142 u32 frameInterval = 23; // ~43 fps
143
144 // Track confidence values for analysis
145 vector<float> confidenceValues;
146
147 // Calculate beat interval from ground truth (if available)
148 u32 beatInterval = 500; // Default: 120 BPM
149 if (groundTruth.size() >= 2) {
150 beatInterval = groundTruth[1].timestamp - groundTruth[0].timestamp;
151 if (enableLogging) {
152 FL_MESSAGE("Detected beat interval from ground truth: " << beatInterval << "ms (" << (60000.0f / beatInterval) << " BPM)");
153 }
154 }
155
156 // Phase 1: Warm-up period to let detector establish rhythm
157 // This allows audio::detector::Beat and audio::detector::Downbeat to build up history
158 if (warmupMeasures > 0 && !groundTruth.empty()) {
159 int beatsPerMeasure = detector.getBeatsPerMeasure();
160 int warmupBeats = warmupMeasures * beatsPerMeasure;
161
162 if (enableLogging) {
163 FL_MESSAGE("Warm-up phase: " << warmupBeats << " beats (" << warmupMeasures << " measures)");
164 }
165
166 for (int beat = 0; beat < warmupBeats; beat++) {
167 bool isDownbeat = (beat % beatsPerMeasure == 0);
168 u32 beatStartTime = timestamp;
169 u32 beatEndTime = timestamp + beatInterval;
170
171 // Generate frames to fill the beat interval
172 // Use fewer frames per beat: 1 quiet + 1 onset (sufficient for spectral flux)
173 u32 beatMidpoint = beatStartTime + beatInterval / 2;
174
175 // Single quiet frame
176 auto quietContext = createMockAudioContext(beatMidpoint, false, true, accentMultiplier);
177 detector.update(quietContext);
178
179 // Single beat onset frame
180 auto beatContext = createMockAudioContext(beatEndTime - frameInterval, isDownbeat, false, accentMultiplier);
181 detector.update(beatContext);
182
183 // Ensure we're exactly at the next beat boundary
184 timestamp = beatEndTime;
185 }
186
187 if (enableLogging) {
188 FL_MESSAGE("Warm-up complete at t=" << timestamp << ", starting metric collection");
189 }
190 }
191

Callers 1

downbeat.hppFile · 0.85

Calls 10

createMockAudioContextFunction · 0.85
maxFunction · 0.85
getBeatsPerMeasureMethod · 0.80
getCurrentBeatMethod · 0.80
isDownbeatMethod · 0.80
sizeMethod · 0.45
emptyMethod · 0.45
updateMethod · 0.45
getConfidenceMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected