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

Function drawWaveform

examples/Audio/advanced/advanced.h:268–338  ·  view source on GitHub ↗

Visualization: Logarithmic Waveform (prevents saturation)

Source from the content-addressed store, hash-verified

266
267// Visualization: Logarithmic Waveform (prevents saturation)
268void drawWaveform(const fl::span<const int16_t>& pcm, float /* peak */) {
269 clearDisplay();
270 fl::CRGBPalette16 palette = getCurrentPalette();
271
272 int samplesPerPixel = pcm.size() / WIDTH;
273 int centerY = HEIGHT / 2;
274
275 for (size_t x = 0; x < WIDTH; x++) {
276 size_t sampleIndex = x * samplesPerPixel;
277 if (sampleIndex >= pcm.size()) break;
278
279 // Get the raw sample value
280 float sample = float(pcm[sampleIndex]) / 32768.0f; // Normalize to -1.0 to 1.0
281
282 // Apply logarithmic scaling to prevent saturation
283 float absSample = fl::fabsf(sample);
284 float logAmplitude = 0.0f;
285
286 if (absSample > 0.001f) { // Avoid log(0)
287 // Logarithmic compression: log10(1 + gain * sample)
288 float scaledSample = absSample * audioGain.value() * autoGainValue;
289 logAmplitude = fl::log10f(1.0f + scaledSample * 9.0f) / fl::log10f(10.0f); // Normalize to 0-1
290 }
291
292 // Apply smooth sensitivity curve
293 logAmplitude = fl::powf(logAmplitude, 0.7f); // Gamma correction for better visual response
294
295 // Calculate amplitude in pixels
296 int amplitude = int(logAmplitude * (HEIGHT / 2));
297 amplitude = fl::clamp(amplitude, 0, HEIGHT / 2);
298
299 // Preserve the sign for proper waveform display
300 if (sample < 0) amplitude = -amplitude;
301
302 // Color mapping based on amplitude intensity
303 uint8_t colorIndex = fl::map_range<int, uint8_t>(abs(amplitude), 0, HEIGHT/2, 40, 255);
304 fl::CRGB color = ColorFromPalette(palette, colorIndex + hue);
305
306 // Apply brightness scaling for low amplitudes
307 if (abs(amplitude) < HEIGHT / 4) {
308 color.fadeToBlackBy(128 - (abs(amplitude) * 512 / HEIGHT));
309 }
310
311 // Draw vertical line from center
312 if (amplitude == 0) {
313 // Draw center point for zero amplitude
314 int ledIndex = xyMap(x, centerY);
315 if (ledIndex >= 0 && ledIndex < NUM_LEDS) {
316 leds[ledIndex] = color.fadeToBlackBy(200);
317 }
318 } else {
319 // Draw line from center to amplitude
320 int startY = (amplitude > 0) ? centerY : centerY + amplitude;
321 int endY = (amplitude > 0) ? centerY + amplitude : centerY;
322
323 for (int y = startY; y <= endY; y++) {
324 if (y >= 0 && y < HEIGHT) {
325 int ledIndex = xyMap(x, y);

Callers 1

loopFunction · 0.85

Calls 10

clearDisplayFunction · 0.85
getCurrentPaletteFunction · 0.85
fabsfFunction · 0.85
log10fFunction · 0.85
powfFunction · 0.85
clampFunction · 0.85
ColorFromPaletteFunction · 0.85
absFunction · 0.50
sizeMethod · 0.45
valueMethod · 0.45

Tested by

no test coverage detected