Use a latch pattern for trackActive: the audio thread sets it true
whenever a voice is active, and the UI timer atomically reads and
clears it via exchange(false). This eliminates the race where the
flag was cleared at the start of every processBlock, causing the
30Hz timer to miss brief activations from short samples.