From 82cc6d910c2de759b5ec66a63cf8d9cde95c006f Mon Sep 17 00:00:00 2001 From: Shura Fedorovskyi Date: Sat, 10 Oct 2026 13:21:57 +0400 Subject: [PATCH] Follow the screen with the lights around it Lights around a display now glow the color of the picture nearest them: a video source publishes one decoded RGB frame per tick, and an effect gives each light the mean of the rectangle mapping to it. The frame comes from a synthesized test pattern or a binary PPM, so the whole path is reviewable and testable on a desktop build. Capturing a real picture from an HDMI grabber over USB follows in its own change. **Core** - VideoService: two sources, a strict Netpbm P6 header parser, and a one-active-source seat so a service added or removed at runtime hands over rather than going dark - VideoFrame: the frame contract, borrowing the producer's buffer for one tick - Every frame carries its tone curve, sRGB here, so a consumer averages light rather than encoded bytes **Light domain** - AmbilightEffect: a per-light box filter averaged in LINEAR light, then encoded once per light, so a part-lit zone reads as bright rather than as a dim mush - Positions reaching no LED are skipped, which on a border layout is most of the box, so a backlight strip costs its perimeter rather than its bounding box - edgeDepth widens the outermost zones past the overscan junk; detectBlackBars moves them inside a letterbox, which edgeDepth cannot do - Smoothing keeps 8.8 fixed-point state per channel, with snapAbove letting a cut land whole - MappingLUT: hasDestination(), the one question the effect asks per position **Tests** - unit_VideoService: 13 cases over the header grammar, the seat election and the pattern's sweep rate - unit_AmbilightEffect: 23 cases over orientation, coverage, the linear-light mean, smoothing in both directions, bar detection and the sparse-mapping skip, with a hollow-rectangle layout local to the file - scenario_Video_source: add, configure and remove the service and its consumer under a running pipeline, which also pins the type registry, since the runner constructs every module through src/module_types.cpp **Docs/CI** - A Video card under core/services.md and an Ambilight card under light/effects.md, each with its details section - screenshot_modules captures both A strip is placed on a wall's edge pixels by the MoonLive library's backlight.mll, so this adds no layout. docgen: appendix lines 5617 to 5643, for the three new headers, which is the one rule that rises. Co-Authored-By: Claude Opus 5 (1M context) --- docs/assets/core/VideoService.png | Bin 0 -> 58936 bytes docs/assets/light/effects/AmbilightEffect.gif | Bin 0 -> 162908 bytes docs/assets/light/effects/AmbilightEffect.png | Bin 0 -> 15506 bytes docs/moonmodules/core/services.md | 34 ++ docs/moonmodules/light/effects.md | 34 ++ moondeck/docs/screenshot_modules.py | 5 + src/core/services/VideoService.h | 304 ++++++++++ src/core/util/VideoFrame.h | 41 ++ src/light/effects/AmbilightEffect.h | 374 ++++++++++++ src/light/layers/MappingLUT.h | 7 + src/module_types.cpp | 4 + test/CMakeLists.txt | 2 + .../light/scenario_Video_source.json | 317 ++++++++++ test/unit/core/unit_VideoService.cpp | 177 ++++++ test/unit/light/unit_AmbilightEffect.cpp | 567 ++++++++++++++++++ 15 files changed, 1866 insertions(+) create mode 100644 docs/assets/core/VideoService.png create mode 100644 docs/assets/light/effects/AmbilightEffect.gif create mode 100644 docs/assets/light/effects/AmbilightEffect.png create mode 100644 src/core/services/VideoService.h create mode 100644 src/core/util/VideoFrame.h create mode 100644 src/light/effects/AmbilightEffect.h create mode 100644 test/scenarios/light/scenario_Video_source.json create mode 100644 test/unit/core/unit_VideoService.cpp create mode 100644 test/unit/light/unit_AmbilightEffect.cpp diff --git a/docs/assets/core/VideoService.png b/docs/assets/core/VideoService.png new file mode 100644 index 0000000000000000000000000000000000000000..ef4879dcde29c4a2b2fd6d49da0e07ef186d6f15 GIT binary patch literal 58936 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¥U3N#GwM>QTu0^wJeO3$8q%%X09sl={kLe2F5y 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�i@e4v|aMTj-rtGg|)&gOa-e*?53Vyva?Y;X2 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­*v=jZ|0n1O_2DY6^V zfboYe6TsmV=Po?{25b;uo<*C?v4v1HKEay(U&$|gz&0nN-5|6NpJ)rGR8))`8GYv8 zZkh{x#%7~kSnx3$w>bm@X4tD_2o`O^y-*l$@fEOTW0?~BgQ3fOVjli)u{HotZa~4- z1h)o>@w@Q864Eerj^3TOwvT6>jX$~4`4qa@HVz-3EOQfkmDZ!NjHkL7rjU#u))MQ4zsE8-G zTwm)zYIHskEVjf6H@H17$QfxBa9i>GR!iA7c)qSo7J0HcE3Ah;d#290##`X_L4iOs?@ z%^{Q)=3>v@=iKm-n!yBi^c7QJqK3Ye`*5+ve1TqBR)#Gzge?tzL8$ z3B#}5Sn1sO!w0pR+r6RJex|)wzoXql4Kf(T7$$OqojV2=xuQ#bc*APzQC{kBOQs;W zGQo#8oxl^SuZTnojrehe? zhYpQ4U1DSWM+S{*xgwj*p*bDqa;=ehq_Gj`a1QqHFfTl>?^qt>QeEaEGs=l7GO6i0 z)6u0q+VDlV*X{-K`3xNFp_~`njzSMB5{G{ab3JpR3sxhI*3DO}I$A^e;TkG-xq~Fv ze{17DE@epK1c+pSd*biHSuI?X-pRfT$RgFqFw%&!;S*^5altIgp3AXipxyrsYF*tR z*-q#Zywb_VoOiniPp*Y_+~8+g4>wz1{x^EK^m8SD%!YPJ_h+-$V zn5?HFMCCxU)B6w(9;9;WdGo|RBh-QDARV)lD?YU5eBesWZk|OOk1qN6XtRlV X`9arIkK14F)Xb;W*h;{COTGUA^F3@M literal 0 HcmV?d00001 diff --git a/docs/assets/light/effects/AmbilightEffect.png b/docs/assets/light/effects/AmbilightEffect.png new file mode 100644 index 0000000000000000000000000000000000000000..fc4429f72319b3084fd7d6331969aec79c022a23 GIT binary patch literal 15506 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 u{mJO-H(){W_ctF&qa + +### Video + +Video service card + +A user-added Service: the video source a screen-follow effect reads. The counterpart of [Audio](#audio) for a picture, decoded once per tick however many effects want it. `source` decides which controls show. The pattern, the file format and the tone curve: ⌄ details. + +- `source`: `test pattern` needs no hardware, `file` reads a PPM off the filesystem. +- `patternSpeed`: (test pattern) sweep rate of the white block, in pixels per second. 0 parks it. +- `file`: (file) path to a binary PPM (P6, maxval 255), uploaded through the File Manager. +- `reload`: (file) re-read the file in place, without rebuilding the pipeline. +- status: the live frame's dimensions (`64x36`), or the reason there is no frame. + +Detail: [technical](moxygen/VideoService.md) + +[Tests](../../reference/tests/unit-tests.md#videoservice) + ### OSC @@ -249,6 +267,22 @@ A received magnitude is clamped to 255, since a real WLED source reaches ~9500 a Prior art: the WLED-MM audio-reactive usermod by **Frank ([@softhack007](https://github.com/softhack007))**, the most-used open-source audio-reactive LED implementation, whose adaptive noise-gate concept the analysis here descends from (analyzed with his permission); and **[@troyhacks](https://github.com/troyhacks/WLED)**, who reworked that DSP onto Espressif's [esp-dsp](https://github.com/espressif/esp-dsp) FFT, the same choice this service makes. The line-in path exists because **wladi ([myhome-control](https://shop.myhome-control.de))** supplied the hardware and pinout for the [MHC-WLED ESP32-P4 shield](../../reference/hardware/mhc-wled-esp32-p4-shield.md): its onboard PCM1808 I2S ADC is what `mclkPin` is for. +## Video, details + +**What reads it.** The service publishes one decoded RGB frame per tick through a static accessor, and any number of effects read that same frame: it is decoded once here however many want it. A consumer holds the frame for one tick and never across frames, and before any frame exists the pointer is non-null but its pixels are, which every reader has to tolerate. That contract is what lets a source be added and removed under a running pipeline. + +**The test pattern is a diagnostic, not decoration.** Four colored border bands (red top, green right, blue bottom, yellow left) and a white block sweeping along the top edge. On a border-mounted strip that makes orientation self-evident: a strip mapped the wrong way round shows as the wrong physical edge lighting, rather than a subtly wrong picture. The sweeping block shows liveness and which way "forward" runs. Parking it with `patternSpeed` 0 turns the pattern into a still reference, so one light can be compared against a known color without the block passing through its zone mid-read. + +**Why PPM for the file source.** There is no software JPEG decoder in this codebase, and adding one so the desktop build could open a `.jpg` would buy a dependency for a development convenience. PPM is a raw RGB dump behind a three-line ASCII header, so it needs no decoder and is one command from any source material: + +```sh +ffmpeg -i clip.mp4 -frames:v 1 -vf scale=64:36 -pix_fmt rgb24 frame.ppm +``` + +The header is parsed strictly, because the file is whatever a user uploaded: comments and whitespace runs are skipped per Netpbm, a 16-bit maxval is refused rather than misread as 8-bit, and exactly one whitespace byte is consumed before the pixels. Accepting a non-whitespace separator there would eat a pixel and shift every channel one place, which tints the whole image instead of failing. + +**Every frame carries its tone curve.** A published frame names the curve from its own encoding to linear light, and a consumer reads pixels through it. SDR is sRGB, a curve like any other, so the frame always carries one rather than leaving the reader to assume. This matters because averaging is what a screen-follow effect does, and the mean of encoded bytes is not the mean of the light: half black and half white averages to 128 as bytes where the light is 188. The table is 12-bit rather than 8, since linear has no headroom at the dark end, which is what encodings exist for. + ## OSC, details **Feedback: the device answers.** With `feedback` on, a control that changes anywhere (the web UI, a preset recall, an audio-reactive effect) is mirrored back to the surface, which is what keeps a client honest and what moves a motorized fader. `addressing` picks where it goes: `unicast` to each of `hosts`, addresses or names, or to whoever last wrote when `hosts` is empty; `multicast` to `group`, which every listening device with the same `group` joins; the default, `239.255.77.78`, sits beside discovery's own group, so multicast works with nothing to fill in, and a second rig on the same network picks another. `feedbackPort` is where that client LISTENS, which is not the port we listen on (Open Stage Control calls its own `osc-port`). diff --git a/docs/moonmodules/light/effects.md b/docs/moonmodules/light/effects.md index 0be273c3e..918d6ea6c 100644 --- a/docs/moonmodules/light/effects.md +++ b/docs/moonmodules/light/effects.md @@ -10,6 +10,28 @@ Effects are built from the shared [power functions](power-functions.md): the dra ## MoonLight effects + + +### Ambilight 📺 + +Ambilight effect preview + +Paints the layer with the live frame from the [Video](../core/services.md#video) service, so lights around a display glow the color of the picture nearest them. Each light shows the **mean** of the rectangle mapping to it. Sampling, black bars and the layout's part: ⌄ details. + +- `brightness`: scales the sampled color, dimming the video not the output. +- `saturation`: how far each channel is pushed from its zone's luma. +- `smoothing`: how much of the gap to a new color closes per frame. +- `snapAbove`: a channel moving further than this jumps instead of easing. +- `edgeDepth`: how far into the picture the outermost lights look. +- `detectBlackBars`: map the lights across the picture, not the frame. +- `barLevel`: how dark a pixel counts as bar (0 to 64). + +Origin: MoonLight original, on the Ambilight / Hyperion behavior + +Detail: [technical](moxygen/AmbilightEffect.md) + +[Tests](../../reference/tests/unit-tests.md#ambilighteffect) + ### ColorTrails 💫🖌️💨🌫️ · 3D @@ -1367,3 +1389,15 @@ Origin: MoonLight (Sinus, AI-generated) · via [MoonLight](https://github.com/ew Detail: [technical](moxygen/SineEffect.md) [Tests](../../reference/tests/unit-tests.md#sineeffect) + +## Ambilight, details + +**Two spaces, and the layout decides the shape.** The SOURCE is the video frame, counted in pixels; the DESTINATION is the layer's logical box, counted in light positions. The source is far the bigger, a 640x480 picture onto a strip of 60 positions, so each position owns a whole rectangle of pixels and shows their average. The effect asks the mapping only one question, whether a position lights anything, and skips the averaging where the answer is no. On a border layout that is most of the box: the interior of a backlight strip's bounding box maps to no LED, so the perimeter shows the frame's border for free. On a full grid the same effect is a video wall. A [MoonLive layout](layouts.md#moonlive) running the library's `backlight.mll` is how a strip gets placed on a wall's edge pixels. + +**Averaging happens in linear light.** Each zone's pixels are summed through the frame's tone curve, averaged, then encoded once per light. Averaging the raw bytes instead averages a quantity that is not proportional to light: a zone half black and half white comes out at 128 where the light is 188, which reads as a dim mush rather than a bright scene. The accumulators are 32-bit because a 640x480 frame onto 32x18 positions is about 520 pixels each, and 520 full-scale 12-bit samples overflow 16 bits many times over. + +**`edgeDepth` widens the outermost zones.** A border light's own share is one row or column of the frame, a sliver at the very edge, which picks up the letterbox and the overscan junk before it picks up the picture. `edgeDepth` lets the outermost positions reach a percentage of the way in instead, without changing how many of them there are. It costs work in proportion: on a layout where every light is an edge light, 15% sends the pixel count up about sixfold. + +**Black bars move the zones, which `edgeDepth` cannot.** A letterboxed film puts bars exactly where the top and bottom lights look, so those lights go dark while the picture is bright. `edgeDepth` only widens a zone from its edge, so the bar stays inside it. `detectBlackBars` finds the bar and maps the lights across the picture within it. A reading is adopted only once several frames agree, because bars come and go at scene changes and a mapping that follows every dark frame twitches worse than one that ignores them. Reaching the scan ceiling reports no bar at all: darkness that deep is a dark scene rather than a letterbox. + +**No source paints black.** With nothing publishing, the effect fills its layer with black rather than returning early, or the previous effect's picture would stay frozen on the strip. A merely dropped frame never reaches that path, since the service keeps its buffer and only a removed service drops it. diff --git a/moondeck/docs/screenshot_modules.py b/moondeck/docs/screenshot_modules.py index 2af4563a4..99d4759cc 100644 --- a/moondeck/docs/screenshot_modules.py +++ b/moondeck/docs/screenshot_modules.py @@ -106,6 +106,9 @@ def asset_dir_for(type_name: str) -> Path: ("RainbowEffect", "Layer", {}, True), ("NoiseEffect", "Layer", {}, True), # The generative-fields showcases: each is Dim::D3, so the preview shows a volume. + # Paints the live video frame, so with no source it photographs black. The capture points it + # at the test pattern, whose four coloured bands and sweeping block are what the effect is for. + ("AmbilightEffect", "Layer", {}, True), ("AuroraEffect", "Layer", {}, True), ("ColorTrailsEffect", "Layer", {}, True), ("TrailsEffect", "Layer", {}, True), @@ -178,6 +181,7 @@ def asset_dir_for(type_name: str) -> Path: # (not in state); capture these against a board when needed. "ImprovProvisioningModule", "AudioService", + "VideoService", "AnalogService", "I2cBusModule", "InfraredService", @@ -209,6 +213,7 @@ def asset_dir_for(type_name: str) -> Path: # the desktop tree — so they're captured against an ESP32, where these entries route the # shot to the right nav root. "AudioService": "Services", + "VideoService": "Services", "AnalogService": "Services", "InfraredService": "Services", "ButtonService": "Services", diff --git a/src/core/services/VideoService.h b/src/core/services/VideoService.h new file mode 100644 index 000000000..e094ab88e --- /dev/null +++ b/src/core/services/VideoService.h @@ -0,0 +1,304 @@ +#pragma once + +#include "core/util/ActiveInstance.h" // the one-active-source seat (RAII vacate on destruct) +#include "core/util/color.h" // RGB: the pattern's band colors +#include "core/module/MoonModule.h" +#include "core/util/ScratchBuffer.h" +#include "core/util/VideoFrame.h" +#include "platform/platform.h" // fsSize / fsReadAt / millis + +#include +#include +#include +#include + +namespace mm { + +/// The device's video input: one decoded RGB frame per tick, published through the static `latestFrame()`. +/// +/// @moreinfo +/// +/// ## Two sources +/// +/// Decoded once here however many effects read it, and effects hold no pointer back to this module; the user adds it under `Services`, so it is not auto-wired. +/// `test pattern` is a DIAGNOSTIC rather than decoration: its colored border bands make a border-mapped effect's orientation self-evident. +/// `file` reads a binary PPM, chosen over JPEG because there is no software JPEG decoder here. +/// Both render into `buf_`, which this module owns, so a published frame lives exactly as long as the service does. +class VideoService : public MoonModule { +public: + /// A service: it produces for others and draws nothing itself. + ModuleRole role() const MM_NONBLOCKING override { return ModuleRole::Service; } + + // Appended, never reordered, so a persisted index keeps its meaning. + /// `source` value for the synthesized diagnostic pattern. + static constexpr uint8_t kSourcePattern = 0; + /// `source` value for a binary PPM on the filesystem. + static constexpr uint8_t kSourceFile = 1; + /// Dropdown labels for `source`, indexed by the constants above. + static constexpr const char* kSourceOptions[] = {"test pattern", "file"}; + /// How many of `kSourceOptions` this build offers. + static constexpr uint8_t kSourceCount = 2; + + /// Which of `kSourceOptions` fills the frame: @xref{two-sources|what each one is for}. + uint8_t source = kSourcePattern; + /// Path the `file` source reads. + char file[64] = "/frame.ppm"; + // Zero parks the block, which makes the pattern a still reference for checking a border light against a known color. Seventeen is the rate it used to be fixed at: a sweep every ~4 s. + /// Sweep rate of the test pattern's white block, in pixels per second. + uint8_t patternSpeed = 17; + + // Small on purpose: a border effect averages the frame down to a few dozen values, so pixels beyond that buy nothing but bandwidth and decode time. + /// Width of the synthesized pattern, 16:9 with kPatternH. + static constexpr uint16_t kPatternW = 64; + /// Height of the synthesized pattern. + static constexpr uint16_t kPatternH = 36; + /// Thickness of each colored edge band, in pixels. + static constexpr int kBand = kPatternH / 4; + // Comfortably past 4K, so a corrupt header is rejected at parse time rather than failing later as "too large for memory". What bounds the allocation is buf_.resize() failing. + /// Sanity ceiling on either dimension of a loaded file. + static constexpr uint32_t kMaxDim = 4096; + + /// The live frame. The POINTER is never null - with no source this returns kNoVideoFrame, which has a null `rgb`. So callers test the frame's contents, never the pointer + static const VideoFrame* latestFrame() MM_NONBLOCKING { + VideoService* v = ActiveInstance::active(); + return v ? &v->frame_ : &kNoVideoFrame; + } + + /// Test seam: the curve as built. + const uint16_t* toneForTest() const { return tone_; } + + /// Claims the one-active-source seat at construction, before any prepare() runs. + VideoService() { seat_.claim(); } + + /// The source picker, plus the settings that belong to whichever source is selected. + void defineControls() override { + controls_.addSelect("source", source, kSourceOptions, kSourceCount); + // Live (not in affectsPrepare): the rate changes what the NEXT frame draws, and nothing about the buffer, so it must not tear the pipeline down to take effect. + controls_.addControl("patternSpeed", patternSpeed, 0, 255); + controls_.setHidden(controls_.count() - 1, source != kSourcePattern); + controls_.addText("file", file, sizeof(file)); + controls_.setHidden(controls_.count() - 1, source != kSourceFile); + controls_.addButton("reload"); + controls_.setHidden(controls_.count() - 1, source != kSourceFile); + MoonModule::defineControls(); + } + + /// A source switch changes what the buffer must hold, so it re-runs the whole build. The reload button re-reads the same file in place: cheap, and it must NOT tear down the pipeline. + bool affectsPrepare(const char* name) const override { + return std::strcmp(name, "source") == 0 || std::strcmp(name, "file") == 0; + } + + /// Routes the one live edit, the reload button; every other control re-runs prepare(). + void onControlChanged(const char* name) override { + if (std::strcmp(name, "reload") == 0) loadFile(); + MoonModule::onControlChanged(name); + } + + /// Cold path: size the frame buffer for the selected source and fill it once, so a frame exists before the first tick rather than one tick later. + void prepare() override { + seat_.claim(); // re-take after a disable/enable cycle: release() vacated it + if (source >= kSourceCount) source = kSourcePattern; // a config naming a source this build lacks + rebuildTone(); // both sources are display-encoded, so the curve is built once and never moves + if (source == kSourceFile) { + loadFile(); + } else if (allocate(kPatternW, kPatternH)) { + renderPattern(); + } + } + + /// Only the synthesized pattern regenerates per frame, since it animates; a still file keeps the buffer it already holds. File I/O is blocking and belongs nowhere near this function. + void tick() MM_NONBLOCKING override { + // Take an EMPTY seat, so deleting the elected source while a second one runs hands over rather than going permanently dark. claim() only fills an empty seat, never yanks one. + seat_.claim(); + if (source == kSourcePattern && buf_.data()) + renderPattern(); + else if (source == kSourceFile && buf_.data()) + publish(); + MoonModule::tick(); + } + + + + /// Drops the published frame and the seat, so a disabled module holds neither. + void release() override { + frame_ = VideoFrame{}; + seat_.vacate(); + MoonModule::release(); + } + +private: + // Claimed at CONSTRUCTION, since an effect resolves latestFrame() during its own build, then re-claimed in prepare() after a disable/enable and in tick() so a survivor inherits it. + ActiveInstance seat_{*this}; + + + static constexpr int kMaxHeaderBytes = 256; // room for a comment, and its own error if not + ScratchBuffer buf_{*this}; // width*height*3, accounted in dynamicBytes() + VideoFrame frame_; + uint32_t seq_ = 0; + uint16_t tone_[256] = {}; // the published curve: source encoding -> linear light + // Sweep position in 1/1000 px and the millis() it was last advanced at. Milli-pixels because a per-second rate sampled per tick rounds to zero motion in whole pixels at 1 px/s. + uint32_t sweepMilliPx_ = 0; + uint32_t sweepAtMs_ = 0; + char status_[40] = {}; + + /// Drop the published frame and say why. Returns false so every failing path reads as one line, `return fail("...")`, and none can forget to un-publish the stale frame. + bool fail(const char* why) { + frame_ = VideoFrame{}; + setStatus(why, Severity::Error); + return false; + } + + /// Size the buffer and point the published frame at it. False on any failure, so a too-large image degrades to "no video" rather than to a crash. + bool allocate(uint16_t w, uint16_t h) { + if (w == 0 || h == 0 || w > kMaxDim || h > kMaxDim) return fail("frame size out of range"); + if (!buf_.resize(static_cast(w) * h * 3u)) return fail("frame too large for memory"); + frame_.rgb = buf_.data(); + frame_.width = w; + frame_.height = h; + // Published here, not from a tick: dimensions only change on a resize, so this keeps the snprintf off the render path. + std::snprintf(status_, sizeof(status_), "%ux%u", w, h); + setStatus(status_, Severity::Status); + return true; + } + + /// Publish the buffer as a NEW frame: the sequence bump is what tells a consumer the pixels changed, so every producer path ends here (see VideoFrame::seq). + void publish() { + frame_.tone = tone_; // per frame, so a curve change lands on the next one with nothing to remember + frame_.seq = ++seq_; + } + + /// Fill `tone_`: the source's transfer curve undone to linear light, where a consumer averages (the mean of encoded bytes is not the mean of the picture). Cold path: 256 float evaluations per edit or prepare, never per frame. + void rebuildTone() { + for (int i = 0; i < 256; i++) { + const float e = static_cast(i) / 255.0f; + // sRGB EOTF (IEC 61966-2-1), which is what both a PPM and the pattern carry. + float lin = e <= 0.04045f ? e / 12.92f : std::pow((e + 0.055f) / 1.055f, 2.4f); + if (lin < 0.0f) lin = 0.0f; + if (lin > 1.0f) lin = 1.0f; + tone_[i] = static_cast(lin * VideoFrame::kLinearMax + 0.5f); + } + } + + // Four colored border bands and a sweeping white block. Integer-only and allocation-free: it runs on the render tick. + void renderPattern() { + uint8_t* p = buf_.data(); + if (!p) return; + // An accumulator fed by elapsed time, not a position derived from millis(): a derived one jumps the block the instant the rate changes and cannot express "stopped" at all. + const uint32_t now = platform::millis(); + if (sweepAtMs_ == 0) sweepAtMs_ = now; // first frame: no elapsed time to charge for + const uint32_t elapsed = now - sweepAtMs_; + sweepAtMs_ = now; + if (patternSpeed) sweepMilliPx_ = (sweepMilliPx_ + elapsed * patternSpeed) % (kPatternW * 1000u); + const int sweepX = static_cast(sweepMilliPx_ / 1000u); + for (int y = 0; y < kPatternH; y++) { + for (int x = 0; x < kPatternW; x++) { + // A white block riding the top edge: shows liveness, and which way "forward" runs. + const bool onSweep = y < kBand && x >= sweepX && x < sweepX + 4; + const RGB c = onSweep ? RGB{255, 255, 255} : bandColor(x, y); + uint8_t* px = p + (static_cast(y) * kPatternW + x) * 3; + px[0] = c.r; + px[1] = c.g; + px[2] = c.b; + } + } + publish(); + } + + /// Color of the pattern at (x, y): one hue per edge, black interior. + static RGB bandColor(int x, int y) { + if (y < kBand) return {255, 0, 0}; // top → red + if (y >= kPatternH - kBand) return {0, 0, 255}; // bottom → blue + if (x < kBand) return {255, 255, 0}; // left → yellow + if (x >= kPatternW - kBand) return {0, 255, 0}; // right → green + return {0, 0, 0}; // interior stays dark + } + + // --- PPM (P6) file source ----------------------------------------------------------------- + /// Read the header, size the buffer, then read the pixel block straight into it. Cold path only (prepare / the reload button): this blocks on the filesystem. + bool loadFile() { + const long size = platform::fsSize(file); + if (size <= 0) return fail("file not found"); + + // Netpbm allows comments and any run of whitespace between tokens, so a header is not a fixed length, and the ceiling has to clear the comment GIMP writes. + char header[kMaxHeaderBytes] = {}; + const int headerLen = platform::fsReadAt(file, 0, header, sizeof(header) - 1); + uint16_t w = 0, h = 0; + const int pixOff = parsePpmHeader(header, headerLen, w, h); + if (pixOff < 0) + return fail(headerLen >= static_cast(sizeof(header)) - 1 + ? "PPM header too long" + : "not a binary PPM (P6, maxval 255)"); + if (!allocate(w, h)) return false; // allocate() already reported why + + const uint32_t need = static_cast(w) * h * 3u; + if (static_cast(size - pixOff) < need) return fail("PPM truncated"); + + const int read = platform::fsReadAt(file, pixOff, reinterpret_cast(buf_.data()), need); + if (read < 0 || static_cast(read) != need) return fail("PPM read failed"); + + setStatus(status_, Severity::Status); // allocate() formatted the size; restore it over an error + publish(); + return true; + } + +public: + /// Parse a binary-PPM header (Netpbm). Returns the byte offset where pixel data begins, or -1 if `buf` is not one. Pure: `len` bounds the read, so a truncated file is rejected rather than parsed into whatever follows it. + static int parsePpmHeader(const char* buf, int len, uint16_t& w, uint16_t& h) { + // P6 + HeaderCursor cur{buf, len}; + cur.skipBlanks(); + if (cur.pos + 1 >= len || buf[cur.pos] != 'P' || buf[cur.pos + 1] != '6') return -1; + cur.pos += 2; + + const long ww = cur.readInt(); + const long hh = cur.readInt(); + const long maxval = cur.readInt(); + if (ww <= 0 || ww > static_cast(kMaxDim)) return -1; + if (hh <= 0 || hh > static_cast(kMaxDim)) return -1; + if (maxval != 255) return -1; // 16-bit samples are two big-endian bytes: another format + // Netpbm requires ONE whitespace byte here. Accepting whatever is present would eat a pixel: "P6\n2 2\n255X" would read as valid with the X swallowed. + if (cur.pos >= len || !HeaderCursor::isBlank(buf[cur.pos])) return -1; + + w = static_cast(ww); + h = static_cast(hh); + return cur.pos + 1; // the pixels begin straight after that one byte + } + +private: + /// Position within an ASCII header. Netpbm separates tokens with any run of whitespace and `#` comments to end-of-line, so both readers skip those first. + struct HeaderCursor { + const char* buf; + int len; + int pos = 0; + + /// Spelled out rather than isspace(), which is locale-dependent and undefined for a signed char above 127. + static bool isBlank(char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r'; } + + void skipBlanks() { + while (pos < len) { + if (buf[pos] == '#') { + while (pos < len && buf[pos] != '\n') pos++; + } else if (isBlank(buf[pos])) { + pos++; + } else { + break; + } + } + } + + /// Next decimal token, or -1 when the next token is not one. Capped well above any real dimension purely so a long digit run cannot overflow; the true bounds are the caller's. + long readInt() { + skipBlanks(); + if (pos >= len || buf[pos] < '0' || buf[pos] > '9') return -1; + long v = 0; + while (pos < len && buf[pos] >= '0' && buf[pos] <= '9') { + v = v * 10 + (buf[pos] - '0'); + if (v > 100000) return -1; + pos++; + } + return v; + } + }; +}; + +} // namespace mm diff --git a/src/core/util/VideoFrame.h b/src/core/util/VideoFrame.h new file mode 100644 index 000000000..dfb462537 --- /dev/null +++ b/src/core/util/VideoFrame.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +namespace mm { + +/// One decoded video frame, produced by VideoService and read by video-reactive effects. +/// +/// @moreinfo +/// +/// ## The tone curve +/// +/// Borrows the producer's buffer rather than carrying the pixels, so `rgb` is valid for one effect tick and never across frames. Before any frame exists it is null, which every consumer must tolerate. +/// `tone` maps the source's encoding to linear light, and SDR is sRGB, so a published frame always carries one. +/// Read pixels through channel(): a consumer averaging the encoded bytes averages a quantity that is not proportional to light. +/// The table is 12-bit rather than 8 because linear has no headroom at the dark end, and small enough that a zone of ~1M pixels still sums inside a uint32. +struct VideoFrame { + /// The pixels: width*height*3, row-major, top-left origin, no padding. + const uint8_t* rgb = nullptr; + /// Frame width in pixels. + uint16_t width = 0; + /// Frame height in pixels. + uint16_t height = 0; + // Compare for INEQUALITY, never ordering: a still PPM bumps it every tick, the way a camera aimed at a still object sends one every period. + /// Bumped per published frame. + uint32_t seq = 0; + // Same one-tick lifetime as `rgb`. + /// 256-entry curve from the source's encoding to linear light, 0..kLinearMax: @xref{the-tone-curve|why a reader must use it}. + const uint16_t* tone = nullptr; + /// The full-scale value of a linear sample. + static constexpr uint16_t kLinearMax = 4095; + + // One lookup on a read the caller already makes. + /// One channel of the pixel at `px` as linear light, or the encoded byte when no curve is published. + uint16_t channel(const uint8_t* px, int c) const { return tone ? tone[px[c]] : px[c]; } +}; + +/// The "no source" frame consumers fall back to. +inline constexpr VideoFrame kNoVideoFrame{}; + +} // namespace mm diff --git a/src/light/effects/AmbilightEffect.h b/src/light/effects/AmbilightEffect.h new file mode 100644 index 000000000..3927d3ade --- /dev/null +++ b/src/light/effects/AmbilightEffect.h @@ -0,0 +1,374 @@ +#pragma once + +#include "core/services/VideoService.h" +#include "light/effects/EffectBase.h" + +#include // std::max / std::min +#include +#include + +namespace mm { + +/// Screen-follow ambient light: paints the layer with the live video frame, so lights around a display glow the color of the picture nearest them. +/// +/// @moreinfo +/// +/// ## The layout decides the shape +/// +/// Two spaces are in play. The SOURCE is the frame in pixels, the DESTINATION is the layer's box in light positions. The source is far the bigger, so each position owns a rectangle of pixels and shows their average. +/// The effect asks the mapping only ONE question, whether a position lights anything, and skips the averaging where the answer is no. On a border layout that is most of the box. +/// So a backlight strip shows the frame's border for free, and a full grid makes the same effect a video wall. +class AmbilightEffect : public EffectBase { +public: + /// Flat, because a frame is; the Layer extrudes z. + Dim dimensions() const override { return Dim::D2; } + + /// Dims THE VIDEO, where the driver's brightness dims everything. + uint8_t brightness = 255; + /// Percent of the distance from gray, so 100 leaves the mean untouched. + uint8_t saturation = 130; + /// How slowly a light moves toward the frame; 0 follows it exactly. + uint8_t smoothing = 0; + /// Jump rather than smooth when a channel moves further than this; 0 never jumps. + uint8_t snapAbove = 80; + /// Percent of the frame the OUTERMOST positions look in; 0 gives them their own share. + uint8_t edgeDepth = 0; + /// Find the letterbox and map the lights across the picture inside it. + bool detectBlackBars = false; + /// A channel at or below this counts as bar, ~5%, which clears compression noise. + uint8_t barLevel = 12; + + /// The video's own brightness and saturation, how fast a light follows it, and the two bar controls. + void defineControls() override { + controls_.addControl("brightness", brightness, 0, 255); + controls_.addControl("saturation", saturation, 0, 200); + controls_.addControl("smoothing", smoothing, 0, 255); + // A cut is a real jump, and smoothing through it reads as the lights lagging the picture. + controls_.addControl("snapAbove", snapAbove, 0, 255); + controls_.setHidden(controls_.count() - 1, smoothing == 0); + controls_.addControl("edgeDepth", edgeDepth, 0, 50); // Hyperion samples ~8% + // A letterboxed film puts bars where the top and bottom lights look, and edgeDepth cannot help since it widens a zone from the edge. This moves the zones instead. + controls_.addControl("detectBlackBars", detectBlackBars); + // Raise it if bars are missed, lower it if dark scenes get cropped; the doc page has why. + controls_.addControl("barLevel", barLevel, 0, 64); + controls_.setHidden(controls_.count() - 1, !detectBlackBars); + } + + /// Turning smoothing on or off allocates or frees the accumulators, so it has to re-run prepare(): without this the buffer stays empty and the setting does nothing. + bool affectsPrepare(const char* name) const override { return std::strcmp(name, "smoothing") == 0; } + + /// Cold path. applyState() prepares a parent before its children, so the Layer's mapping is already built when buildLitList() reads it. + void prepare() override { + // lengthType is signed: a stray negative would cast to a colossal size_t, not to nothing. + const lengthType w = width(), h = height(); + const size_t positions = (w > 0 && h > 0) ? static_cast(w) * static_cast(h) : 0; + + state_.resize(smoothing != 0 ? positions * 3u : 0); // 8.8 per channel, only while smoothing + encodeTable(); // built here, off the tick + primed_ = false; + buildLitList(positions); + } + + /// The positions that reach an LED, packed y<<16|x, so tick() walks a few hundred of tens of thousands on a border layout: @xref{the-layout-decides-the-shape|why most of the box is skipped}. + void buildLitList(size_t positions) { + litCount_ = 0; + const MappingLUT& lut = layer()->lut(); + // A table-free (identity) mapping lights every position, so the list would be 0,1,2,3, four bytes a position to say "all of them" where the plain loop needs none. + allLit_ = !lut.hasLUT(); + if (allLit_ || positions == 0) { + lit_.resize(0); + return; + } + // Count first, then size to the count. Sizing by the box reserves 156 KB on a 200x200 rectangle to hold the 3 KB its perimeter needs. + size_t lit = 0; + for (size_t i = 0; i < positions; i++) + if (columnLit(lut, i, positions)) lit++; + if (lit == 0 || !lit_.resize(lit)) return; // no list: tick() paints the whole box instead + const lengthType w = width(); + for (size_t i = 0; i < positions; i++) + if (columnLit(lut, i, positions)) + lit_[litCount_++] = static_cast((i / w) << 16 | (i % w)); + } + + // This effect is D2 and Layer::extrude() copies z=0 across the depth. On a sparse 3D layout a column whose only LED sits at z > 0 is still lit from here. + /// Whether front-face position `i` reaches an LED in ANY z plane, where `slice` is width*height. + bool columnLit(const MappingLUT& lut, size_t i, size_t slice) const MM_NONBLOCKING { + const lengthType d = depth(); + for (lengthType z = 0; z < d; z++) + if (lut.hasDestination(static_cast(i + static_cast(z) * slice))) + return true; + return false; + } + + /// Average each lit position's share of the frame and paint it, or paint black when no source is publishing. + void tick() MM_NONBLOCKING override { + const VideoFrame* frame = VideoService::latestFrame(); + const draw::Canvas out = canvas(); + + // No source: paint black rather than return, or the PREVIOUS effect's picture stays frozen on the strip. A merely dropped frame never lands here. + if (!frame->rgb || frame->width == 0 || frame->height == 0) { + draw::fill(out, {0, 0, 0}); + primed_ = false; // so the next frame lands whole instead of creeping up out of black + return; + } + + // The frame already on the strip, which `primed_` is what makes true: prepare() clears the layer and resets it, so a rebuild against a frozen frame would stay black. + if (primed_ && frame->seq == lastSeq_) return; + lastSeq_ = frame->seq; + + const lengthType lightsX = width(), lightsY = height(); + if (lightsX <= 0 || lightsY <= 0) return; + + const Region region = regionFor(*frame); + if (region.width <= 0 || region.height <= 0) return; + + const bool canSmooth = smootherReady(lightsX, lightsY); + + // Three ways to reach the same set of positions, cheapest first. + if (allLit_) { + // Nothing to skip: the plain box, no clear, no mapping queries. + for (lengthType y = 0; y < lightsY; y++) + for (lengthType x = 0; x < lightsX; x++) + paint(out, *frame, region, x, y, lightsX, lightsY, canSmooth); + } else if (lit_) { + // The list. Unlit positions are never written, so they keep the black Layer::prepare() left. BlendMap never reads them, but PreviewDriver shows the raw buffer and must not see a ghost. + for (size_t i = 0; i < litCount_; i++) + paint(out, *frame, region, static_cast(lit_[i] & 0xFFFF), + static_cast(lit_[i] >> 16), lightsX, lightsY, canSmooth); + } else { + // The list could not be allocated. Same output, asking the mapping per position - which is the cost the list exists to avoid. + const MappingLUT& lut = layer()->lut(); + const size_t slice = static_cast(lightsX) * lightsY; + draw::fill(out, {0, 0, 0}); + for (lengthType y = 0; y < lightsY; y++) + for (lengthType x = 0; x < lightsX; x++) + if (columnLit(lut, static_cast(y) * lightsX + x, slice)) + paint(out, *frame, region, x, y, lightsX, lightsY, canSmooth); + } + primed_ = true; + } + +private: + /// Half-open range of SOURCE pixels `[begin, end)` along one axis. + struct Span { + int begin, end; + Span shifted(int by) const { return {begin + by, end + by}; } + }; + + // The actual region of the source frame that the lights cover. Could be smaller than the full frame if black bars are detected. + struct Region { + int left = 0, top = 0; // where the picture starts inside the frame + int width = 0, height = 0; + int deepX = 0, deepY = 0; // edgeDepth in pixels, so the divide is not per position + + /// Which source pixels one light position covers: its share of the picture, shifted back into frame coordinates. Every input lives here, so the loop only asks. + Span cols(int x, int lightsX) const { return spanFor(x, lightsX, width, deepX).shifted(left); } + Span rows(int y, int lightsY) const { return spanFor(y, lightsY, height, deepY).shifted(top); } + }; + + /// One light position: average its pixels, correct, smooth, write. + void paint(const draw::Canvas& out, const VideoFrame& frame, const Region& region, lengthType x, + lengthType y, lengthType lightsX, lengthType lightsY, bool canSmooth) MM_NONBLOCKING { + RGB color = adjust(meanOf(frame, region.cols(x, lightsX), region.rows(y, lightsY))); + if (canSmooth) color = smooth(static_cast(y) * lightsX + x, color); + draw::pixel(out, {x, y, 0}, color); + } + + Region regionFor(const VideoFrame& frame) MM_NONBLOCKING { + const Bars bars = trackBars(frame); + Region r; + r.left = bars.left; + r.top = bars.top; + r.width = frame.width - bars.left - bars.right; + r.height = frame.height - bars.top - bars.bottom; + // Rounded UP, so any non-zero percentage is at least one pixel. Flooring would let a small setting on a small frame land on 0, which is the off value: the control would go quiet. + r.deepX = (r.width * edgeDepth + 99) / 100; + r.deepY = (r.height * edgeDepth + 99) / 100; + return r; + } + + /// Whether this frame can be smoothed: turned on, and the accumulators are there and big enough. + bool smootherReady(lengthType lightsX, lengthType lightsY) const MM_NONBLOCKING { + return smoothing != 0 && state_ && + state_.count() >= static_cast(lightsX) * static_cast(lightsY) * 3u; + } + + /// How thick the bar at each edge is, in pixels + struct Bars { + int top = 0, bottom = 0, left = 0, right = 0; + bool operator==(const Bars& o) const { + return top == o.top && bottom == o.bottom && left == o.left && right == o.right; + } + }; + + static constexpr int kProbes = 8; // sample points per scanned line + static constexpr int kMaxBarPercent = 40; // a "bar" deeper than this is a dark scene + static constexpr uint8_t kStableFrames = 30; + + /// Which edge a bar is being measured from. Top and Bottom scan rows, Left and Right columns. + enum class Edge : uint8_t { Top, Bottom, Left, Right }; + + static bool scansRows(Edge e) MM_NONBLOCKING { return e == Edge::Top || e == Edge::Bottom; } + static bool scansFromEnd(Edge e) MM_NONBLOCKING { return e == Edge::Bottom || e == Edge::Right; } + + /// Is this line dark all the way across? Sampled at a few evenly spaced points rather than every pixel: a bar is uniform, so a handful of probes settles it for a fraction of the cost. + bool lineIsDark(const VideoFrame& frame, int line, Edge edge) const MM_NONBLOCKING { + const bool horizontal = scansRows(edge); + const int along = horizontal ? frame.width : frame.height; + for (int i = 0; i < kProbes; i++) { + const int v = along * (2 * i + 1) / (2 * kProbes); // midpoints, so the corners are skipped + const int x = horizontal ? v : line; + const int y = horizontal ? line : v; + const uint8_t* px = frame.rgb + (static_cast(y) * frame.width + x) * 3; + if (px[0] > barLevel || px[1] > barLevel || px[2] > barLevel) return false; + } + return true; + } + + // Returning the ceiling cropped a dark frame to its middle, and kStableFrames then held that into the next scene. + /// How many dark lines run inward from one edge, where reaching the ceiling reports NO bar: darkness that deep is a dark SCENE rather than a letterbox. + int barFrom(const VideoFrame& frame, Edge edge) const MM_NONBLOCKING { + const int extent = scansRows(edge) ? frame.height : frame.width; + const int limit = extent * kMaxBarPercent / 100; + for (int i = 0; i < limit; i++) { + const int line = scansFromEnd(edge) ? extent - 1 - i : i; + if (!lineIsDark(frame, line, edge)) return i; + } + return 0; + } + + // Bars come and go at scene changes, and a mapping that follows every dark frame twitches worse than one that ignores them. Hence the state. + /// Scan this frame and return the bars IN EFFECT, which is what the caller maps across: a reading is adopted only once kStableFrames of them agree. + Bars trackBars(const VideoFrame& frame) MM_NONBLOCKING { + if (!detectBlackBars) { + // All of it, not just the adopted value. A surviving candidate_ with a saturated stable_ would make the next enable agree with itself at once and never re-adopt. + bars_ = candidate_ = Bars{}; + stable_ = 0; + return bars_; + } + Bars found; + found.top = barFrom(frame, Edge::Top); + found.bottom = barFrom(frame, Edge::Bottom); + found.left = barFrom(frame, Edge::Left); + found.right = barFrom(frame, Edge::Right); + if (!(found == candidate_)) { + candidate_ = found; + stable_ = 0; + } else if (stable_ < kStableFrames && ++stable_ == kStableFrames) { + bars_ = found; + } + return bars_; + } + + /// Which source pixels light position `lightId` covers along one axis. + /// - `pixels` shared evenly among `lightsSize` positions, cut at the edges so ranges meet exactly + /// - a position ON an edge takes exactly `deep` instead of its share, deeper OR shallower, so the control sets the depth rather than raising a floor under it + /// - `deep` of 0 leaves the plain division, and interior positions are on no edge either way + /// - an empty range widens to one pixel, so a strip finer than the picture still lights up + static Span spanFor(int lightId, int lightsSize, int pixels, int deep) { + int begin = static_cast((static_cast(lightId) * pixels) / lightsSize); + int end = static_cast((static_cast(lightId + 1) * pixels) / lightsSize); + if (deep > 0) { + if (lightId == 0) + end = deep; // down/right, inward + else if (lightId == lightsSize - 1) + begin = pixels - deep; // up/left, inward + } + if (begin < 0) begin = 0; + if (begin >= pixels) begin = pixels - 1; + if (end <= begin) end = begin + 1; + if (end > pixels) end = pixels; + return {begin, end}; + } + + /// Linear light back to a display byte (sRGB OETF). Built on first use, which prepare() makes a cold path: 4096 pow() calls have no place in a tick. + static const uint8_t* encodeTable() { + static const auto table = [] { + std::array t{}; + for (size_t i = 0; i < t.size(); i++) { + const float lin = static_cast(i) / VideoFrame::kLinearMax; + const float v = lin <= 0.0031308f ? 12.92f * lin : 1.055f * std::pow(lin, 1.0f / 2.4f) - 0.055f; + t[i] = static_cast(v * 255.0f + 0.5f); + } + return t; + }(); + return table.data(); + } + + // uint32 accumulators, because 640x480 onto 32x18 is ~520 pixels each and 520 x 4095 overflows 16 bits many times over. + /// Mean of one light position's pixels: the box filter Hyperion uses, taken in linear light and encoded once per LIGHT. + static RGB meanOf(const VideoFrame& frame, Span cols, Span rows) { + uint32_t sr = 0, sg = 0, sb = 0; + for (int py = rows.begin; py < rows.end; py++) { + const uint8_t* px = frame.rgb + (static_cast(py) * frame.width + cols.begin) * 3; + for (int pxX = cols.begin; pxX < cols.end; pxX++, px += 3) { + sr += frame.channel(px, 0); + sg += frame.channel(px, 1); + sb += frame.channel(px, 2); + } + } + const uint32_t pixels = + static_cast(rows.end - rows.begin) * static_cast(cols.end - cols.begin); + const uint32_t mr = sr / pixels, mg = sg / pixels, mb = sb / pixels; + if (!frame.tone) return {static_cast(mr), static_cast(mg), static_cast(mb)}; + const uint8_t* enc = encodeTable(); + return {enc[mr], enc[mg], enc[mb]}; + } + + /// Move one channel `saturation` percent of the way out from `luma`, clamped to a byte. + uint8_t stretch(uint8_t v, int luma) const MM_NONBLOCKING { + const int out = luma + ((static_cast(v) - luma) * static_cast(saturation)) / 100; + return static_cast(out < 0 ? 0 : (out > 255 ? 255 : out)); + } + + /// Saturation runs on the RAW mean, before brightness: stretching around an already-dimmed luma would shrink the boost as the lights were turned down. + RGB adjust(RGB c) const { + if (saturation != 100) { + // Rec.601 weights (77/150/29 of 256). A flat (r+g+b)/3 would brighten greens and dim blues as saturation rose, because it is not what the eye does. + const int luma = static_cast((77 * c.r + 150 * c.g + 29 * c.b) >> 8); + c = {stretch(c.r, luma), stretch(c.g, luma), stretch(c.b, luma)}; + } + if (brightness != 255) { + c = {static_cast((c.r * brightness) / 255), + static_cast((c.g * brightness) / 255), + static_cast((c.b * brightness) / 255)}; + } + return c; + } + + /// Walk each channel a fraction of the way toward `color`. The state is 8.8 so the fraction of a step survives between frames: in whole bytes a slow setting rounds every step to zero. + RGB smooth(size_t lightId, RGB color) MM_NONBLOCKING { + const uint8_t target[3] = {color.r, color.g, color.b}; + const int32_t step = 256 - smoothing; // gap closed per frame, of 256 + const int32_t snap = static_cast(snapAbove) << 8; // 8.8, to compare against delta + uint8_t out[3]; + for (uint8_t ch = 0; ch < 3; ch++) { + const size_t slot = lightId * 3 + ch; // three accumulators per position, row-major + const int32_t held = state_[slot]; + const int32_t want = static_cast(target[ch]) << 8; + const int32_t delta = want - held; + // The first frame after a gap, and any move big enough to be a cut, land whole. + const bool jump = !primed_ || (snapAbove && (delta > snap || delta < -snap)); + // >> floors, so without the nudge a rising channel stalls one count short for ever, rendering white as 254, while a falling one arrives. + int32_t move = (delta * step) >> 8; + if (move == 0 && delta != 0) move = delta > 0 ? 1 : -1; + state_[slot] = static_cast(jump ? want : held + move); + out[ch] = static_cast(state_[slot] >> 8); + } + return {out[0], out[1], out[2]}; + } + + Bars bars_; // in effect + Bars candidate_; // seen most recently + uint8_t stable_ = 0; + + ScratchBuffer lit_{*this}; // packed y<<16|x, the positions that reach an LED + size_t litCount_ = 0; + bool allLit_ = true; // no list: the mapping lights every position + + ScratchBuffer state_{*this}; // 8.8 per channel per light position, while smoothing is on + bool primed_ = false; // false until one frame has been written + uint32_t lastSeq_ = 0; // the frame already on the strip +}; + +} // namespace mm diff --git a/src/light/layers/MappingLUT.h b/src/light/layers/MappingLUT.h index 416f283a7..e57bbb3fa 100644 --- a/src/light/layers/MappingLUT.h +++ b/src/light/layers/MappingLUT.h @@ -149,6 +149,13 @@ class MappingLUT { + static_cast(maxDest) * sizeof(nrOfLightsType); } + /// Hot path: does this logical index reach any physical light? Empty run = no destination. + bool hasDestination(nrOfLightsType logicalIdx) const MM_NONBLOCKING { + if (identity_) return true; + if (!offsets_ || logicalIdx >= logicalCount_) return false; + return offsets_[logicalIdx + 1] > offsets_[logicalIdx]; + } + /// Walk the physical destinations of one logical light, on the hot path. template void forEachDestination(nrOfLightsType logicalIdx, F&& callback) const { diff --git a/src/module_types.cpp b/src/module_types.cpp index edc9d0726..02ca9e010 100644 --- a/src/module_types.cpp +++ b/src/module_types.cpp @@ -84,6 +84,7 @@ #include "light/effects/RadialSpectrumEffect.h" #include "light/effects/VuMetersEffect.h" #include "light/effects/BeatRipplesEffect.h" +#include "light/effects/AmbilightEffect.h" #include "light/effects/AudioSpectrumEffect.h" #include "light/effects/SineEffect.h" #include "light/effects/DistortionWavesEffect.h" @@ -177,6 +178,7 @@ #include "core/system/ControlModule.h" #include "core/services/Services.h" #include "core/services/AudioService.h" +#include "core/services/VideoService.h" #include "core/services/OscModule.h" #include "core/system/I2cBusModule.h" #include "core/system/TasksModule.h" @@ -237,6 +239,7 @@ void mm::registerModuleTypes() { mm::ModuleFactory::registerType("TubesLayout", "light/layouts.md#tubes"); mm::ModuleFactory::registerType("WheelLayout", "light/layouts.md#wheel"); // Effects, registered alphabetically by display name: @xref{what-registertype-captures}. + mm::ModuleFactory::registerType("AmbilightEffect", "light/effects.md#ambilight"); mm::ModuleFactory::registerType("AudioSpectrumEffect", "light/effects.md#audiospectrum"); mm::ModuleFactory::registerType("RadialSpectrumEffect", "light/effects.md#radialspectrum"); mm::ModuleFactory::registerType("VuMetersEffect", "light/effects.md#vumeters"); @@ -355,6 +358,7 @@ void mm::registerModuleTypes() { mm::ModuleFactory::registerType("ControlModule", "core/system.md#control"); mm::ModuleFactory::registerType("Services", "core/services.md#services"); mm::ModuleFactory::registerType("AudioService", "core/services.md#audio"); + mm::ModuleFactory::registerType("VideoService", "core/services.md#video"); mm::ModuleFactory::registerType("OscModule", "core/services.md#osc"); mm::ModuleFactory::registerType("I2cBusModule", "core/system.md#i2c-bus"); mm::ModuleFactory::registerType("TasksModule", "core/system.md#tasks"); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 94626e2e5..0b5b422a3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable(mm_tests unit/core/unit_SpscRing.cpp unit/core/unit_AnalogService.cpp unit/core/unit_AudioCapture.cpp + unit/core/unit_VideoService.cpp unit/core/unit_platform_audiofft.cpp unit/core/unit_Buffer.cpp unit/core/unit_ScratchBuffer.cpp @@ -165,6 +166,7 @@ add_executable(mm_tests unit/light/unit_Shader.cpp unit/light/unit_PolarLut.cpp unit/light/unit_PolarLut_equivalence.cpp + unit/light/unit_AmbilightEffect.cpp unit/light/unit_AuroraEffect.cpp unit/light/unit_NoiseEffect.cpp unit/light/unit_Effects_framerate.cpp diff --git a/test/scenarios/light/scenario_Video_source.json b/test/scenarios/light/scenario_Video_source.json new file mode 100644 index 000000000..aeedbaa14 --- /dev/null +++ b/test/scenarios/light/scenario_Video_source.json @@ -0,0 +1,317 @@ +{ + "name": "scenario_Video_source", + "module": "VideoService", + "mode": "mutate", + "also": [ + "SystemModule", + "Services", + "Layouts", + "GridLayout", + "Effects", + "Layer", + "RainbowEffect", + "Drivers", + "PreviewDriver", + "AmbilightEffect" + ], + "description": "Add / configure / remove the VideoService while the render pipeline runs, the video half of what scenario_Audio_mutation pins for audio. A Service is user-added at runtime, so every step asserts the pipeline keeps RENDERING through it: adding the service, writing its controls one at a time (source is an affectsPrepare control, so that write drives a full prepareTree mid-render), and removing it again. This also pins the type REGISTRY, since the runner builds every module through the firmware's own src/module_types.cpp: a service left out of it cannot be named here, where the unit tests construct the class directly and pass either way. It then adds the AmbilightEffect consumer, configures it, and REMOVES the service while the consumer is still live. That last step is what the one-active-source seat exists for: latestFrame() falls back to the static kNoVideoFrame and the effect paints black instead of dereferencing a frame whose buffer went with the service. Pixel correctness is pinned by unit_AmbilightEffect and unit_VideoService; this is the live wired-pipeline gate.", + "fixture": [ + { + "name": "fix-system", + "description": "SystemModule: the device's fixed identity/vitals root, mirroring main.cpp.", + "op": "add_module", + "id": "System", + "type": "SystemModule" + }, + { + "name": "fix-services", + "description": "Services: the top-level container user-added capability modules hang under, mirroring main.cpp where VideoService is a Service, not a System child.", + "op": "add_module", + "id": "Services", + "type": "Services" + }, + { + "name": "fix-layouts", + "op": "add_module", + "id": "Layouts", + "type": "Layouts" + }, + { + "name": "fix-grid", + "description": "The grid the pipeline renders on: 16:9 at 96x54. No effect reads the video frame in this scenario, so the layout is here to give the pipeline something real to tick, not to be sampled.", + "op": "add_module", + "id": "Grid", + "type": "GridLayout", + "parent_id": "Layouts", + "props": { + "width": 96, + "height": 54 + } + }, + { + "name": "fix-layers", + "op": "add_module", + "id": "Effects", + "type": "Effects", + "props": { + "layouts": "Layouts" + } + }, + { + "name": "fix-layer", + "op": "add_module", + "id": "Layer", + "type": "Layer", + "parent_id": "Effects", + "props": { + "channelsPerLight": 3 + } + }, + { + "name": "fix-rainbow", + "description": "A non-video effect so the pipeline has something to render before, and after, the video pair exists.", + "op": "add_module", + "id": "Rainbow", + "type": "RainbowEffect", + "parent_id": "Layer" + }, + { + "name": "fix-drivers", + "op": "add_module", + "id": "Drivers", + "type": "Drivers", + "props": { + "effects": "Effects" + } + }, + { + "name": "fix-preview", + "op": "add_module", + "id": "Preview", + "type": "PreviewDriver", + "parent_id": "Drivers" + } + ], + "steps": [ + { + "name": "measure-pipeline-only", + "description": "Baseline: the render pipeline runs with no video module present.", + "op": "measure", + "measure": true, + "bounds": { + "fps": { + "min": 1 + } + }, + "observed": { + "desktop-macos": { + "tick_us": { + "p50": 16, + "p95": 16, + "min": 16, + "max": 16, + "n": 1, + "samples": [16] + }, + "last_updated": "2026-10-10" + } + } + }, + { + "name": "add-video-module", + "description": "Add the VideoService under the Services container. It claims the one-active-source seat on construction and renders its test pattern; the pipeline must keep rendering.", + "op": "add_module", + "id": "Video", + "type": "VideoService", + "parent_id": "Services" + }, + { + "name": "measure-video-added", + "description": "Pipeline still renders with the video service added and no consumer reading it.", + "op": "measure", + "measure": true, + "bounds": { + "fps": { + "min": 1 + } + }, + "observed": { + "desktop-macos": { + "tick_us": { + "p50": 16, + "p95": 16, + "min": 16, + "max": 16, + "n": 1, + "samples": [16] + }, + "last_updated": "2026-10-10" + } + } + }, + { + "name": "configure-source", + "description": "Select the test-pattern source. This is an affectsPrepare control, so the write drives a full prepareTree mid-render: the buffer is resized and refilled while the pipeline ticks.", + "op": "set_control", + "id": "Video", + "key": "source", + "value": 0 + }, + { + "name": "measure-video-configured", + "description": "Pipeline still renders after the config writes, one of which rebuilt the tree.", + "op": "measure", + "measure": true, + "bounds": { + "fps": { + "min": 1 + } + }, + "observed": { + "desktop-macos": { + "tick_us": { + "p50": 16, + "p95": 16, + "min": 16, + "max": 16, + "n": 1, + "samples": [16] + }, + "last_updated": "2026-10-10" + } + } + }, + { + "name": "add-video-consumer", + "description": "Add an AmbilightEffect under the Layer. It reads the service through the static accessor, so it picks up the live frame with nothing having wired the two together.", + "op": "add_module", + "id": "Ambi", + "type": "AmbilightEffect", + "parent_id": "Layer" + }, + { + "name": "measure-consumer-live", + "description": "Producer and consumer both live: the border is being painted from the published frame.", + "op": "measure", + "measure": true, + "bounds": { + "fps": { + "min": 1 + } + }, + "observed": { + "desktop-macos": { + "tick_us": { + "p50": 70, + "p95": 70, + "min": 70, + "max": 70, + "n": 1, + "samples": [70] + }, + "last_updated": "2026-10-10" + } + } + }, + { + "name": "configure-consumer-brightness", + "description": "Configure the consumer while it renders: a plain scalar write that touches no buffer, so the resize in the next step is the only allocation under test.", + "op": "set_control", + "id": "Ambi", + "key": "brightness", + "value": 200 + }, + { + "name": "configure-consumer-smoothing", + "description": "Smoothing allocates the 8.8 per-channel state in prepare(), so this write resizes a live effect's buffer mid-render.", + "op": "set_control", + "id": "Ambi", + "key": "smoothing", + "value": 64 + }, + { + "name": "measure-consumer-configured", + "description": "Pipeline still renders after both consumer writes, one of which resized a buffer.", + "op": "measure", + "measure": true, + "bounds": { + "fps": { + "min": 1 + } + }, + "observed": { + "desktop-macos": { + "tick_us": { + "p50": 114, + "p95": 114, + "min": 114, + "max": 114, + "n": 1, + "samples": [114] + }, + "last_updated": "2026-10-10" + } + } + }, + { + "name": "remove-video-module", + "description": "Remove the service while the consumer is STILL live. latestFrame() must fall back to the static kNoVideoFrame, and the effect must paint black rather than dereference a frame whose buffer went with the service. This is the robustness rule's hardest case for this pair, and the one the seat and the borrowed-buffer teardown order exist for.", + "op": "remove_module", + "id": "Video" + }, + { + "name": "measure-after-video-removed", + "description": "Pipeline still renders with an orphaned consumer and no producer.", + "op": "measure", + "measure": true, + "bounds": { + "fps": { + "min": 1 + } + }, + "observed": { + "desktop-macos": { + "tick_us": { + "p50": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1, + "samples": [20] + }, + "last_updated": "2026-10-10" + } + } + }, + { + "name": "remove-video-consumer", + "description": "Remove the orphaned consumer too: clean teardown, pipeline still live.", + "op": "remove_module", + "id": "Ambi" + }, + { + "name": "measure-back-to-baseline", + "description": "Back to the baseline tree, still rendering.", + "op": "measure", + "measure": true, + "bounds": { + "fps": { + "min": 1 + } + }, + "observed": { + "desktop-macos": { + "tick_us": { + "p50": 16, + "p95": 16, + "min": 16, + "max": 16, + "n": 1, + "samples": [16] + }, + "last_updated": "2026-10-10" + } + } + } + ] +} diff --git a/test/unit/core/unit_VideoService.cpp b/test/unit/core/unit_VideoService.cpp new file mode 100644 index 000000000..ceb7dc915 --- /dev/null +++ b/test/unit/core/unit_VideoService.cpp @@ -0,0 +1,177 @@ +/// @module VideoService +/// +/// Pins the PPM header grammar VideoService's file source accepts, the seat election that decides which service publishes, and the test pattern's sweep rate. +/// +/// @moreinfo +/// +/// The parser is the part with real edge cases: comments, whitespace runs, a 16-bit maxval, a truncated header. +/// It also decides where pixel data starts, so a wrong offset shows as a picture shifted by a few bytes rather than as a clean failure. +/// Driven directly, since it is a pure static, so these run without a filesystem and a malformed file is testable without writing one. + +#include "doctest.h" +#include "core/services/VideoService.h" + +#include +#include + +using mm::VideoService; + +namespace { +// Parse helper: returns the pixel offset, or -1, and reports the dimensions it read. +int parse(const char* text, uint16_t& w, uint16_t& h) { + return VideoService::parsePpmHeader(text, static_cast(std::strlen(text)), w, h); +} +} // namespace + +// The canonical form ffmpeg and ImageMagick emit: magic, dimensions, maxval, one newline, pixels. +TEST_CASE("VideoService PPM: a canonical P6 header yields the dimensions and the pixel offset") { + uint16_t w = 0, h = 0; + const char* hdr = "P6\n64 36\n255\n"; + CHECK(parse(hdr, w, h) == 13); // pixels begin straight after the final newline + CHECK(w == 64); + CHECK(h == 36); +} + +// Netpbm allows any run of whitespace between tokens and `#` comments to end of line. Both appear in real files, so both must be skipped without shifting the offset. +TEST_CASE("VideoService PPM: comments and whitespace runs are skipped, not counted as pixels") { + uint16_t w = 0, h = 0; + const char* hdr = "P6\n# CREATOR: GIMP\n 16 9 \n255\n"; + const int off = parse(hdr, w, h); + CHECK(off == static_cast(std::strlen(hdr))); + CHECK(w == 16); + CHECK(h == 9); +} + +// Exactly ONE whitespace byte separates the header from the binary block; any further byte is already a pixel. Consuming two would tint the whole image by shifting every channel one place. +TEST_CASE("VideoService PPM: only one separator byte is consumed before the pixels") { + uint16_t w = 0, h = 0; + // A leading pixel byte that happens to be whitespace-valued (0x20) must survive as data. + const char hdr[] = {'P', '6', '\n', '2', ' ', '2', '\n', '2', '5', '5', '\n', ' ', 'X'}; + const int off = VideoService::parsePpmHeader(hdr, static_cast(sizeof(hdr)), w, h); + CHECK(off == 11); // after the newline: NOT after the following 0x20 + CHECK(w == 2); + CHECK(h == 2); +} + +// P3 is the ASCII variant: same dimensions, completely different body (decimal text, not bytes). Accepting it would read numerals as pixel values and render noise. +TEST_CASE("VideoService PPM: the ASCII variant P3 is rejected, not read as binary") { + uint16_t w = 0, h = 0; + CHECK(parse("P3\n8 8\n255\n", w, h) == -1); +} + +// A 16-bit maxval means two big-endian bytes per sample: a different pixel format. Reading it as 8-bit would show the high bytes as a dim, doubled image, so it is refused rather than guessed at. +TEST_CASE("VideoService PPM: a 16-bit maxval is rejected rather than misread as 8-bit") { + uint16_t w = 0, h = 0; + CHECK(parse("P6\n8 8\n65535\n", w, h) == -1); +} + +// Garbage, an empty buffer, and a header cut off mid-token must all fail cleanly. The file source is fed by whatever the user uploads, so this is the ordinary case. +TEST_CASE("VideoService PPM: malformed and truncated headers fail without reading past the buffer") { + uint16_t w = 0, h = 0; + CHECK(parse("", w, h) == -1); + CHECK(parse("not an image at all", w, h) == -1); + CHECK(parse("P6", w, h) == -1); // magic only + CHECK(parse("P6\n64", w, h) == -1); // no height + CHECK(parse("P6\n64 36\n", w, h) == -1); // no maxval + CHECK(parse("P6\n64 36\n255", w, h) == -1); // no separator, so no pixel data can follow +} + +// A zero side has no pixels, and an absurd dimension would overflow the width*height*3 allocation size. Both are refused at the header rather than at the allocation. +TEST_CASE("VideoService PPM: zero and out-of-range dimensions are refused at the header") { + uint16_t w = 0, h = 0; + CHECK(parse("P6\n0 36\n255\n", w, h) == -1); + CHECK(parse("P6\n64 0\n255\n", w, h) == -1); + CHECK(parse("P6\n99999 36\n255\n", w, h) == -1); // past kMaxDim +} + +// With no service instantiated, latestFrame() still returns a readable struct, so an effect null-checks the frame's contents rather than the POINTER. Every device is in that state at boot. +TEST_CASE("VideoService: latestFrame is readable with no service present and reports no frame") { + const mm::VideoFrame* f = VideoService::latestFrame(); + REQUIRE(f != nullptr); + CHECK(f->rgb == nullptr); + CHECK(f->seq == 0); + CHECK(f->width == 0); + CHECK(f->height == 0); +} + +// Deleting the elected source while a second one runs must hand the seat over rather than go dark. The destructor vacates it and a running module re-claims an empty one on its next tick. +TEST_CASE("VideoService: a survivor takes over the seat when the elected source is destroyed") { + auto* elected = new VideoService(); // constructed first, so it claims the seat + elected->source = VideoService::kSourcePattern; // needs no file + elected->applyState(); + REQUIRE(VideoService::latestFrame()->rgb != nullptr); + + VideoService survivor; // seat already held, so its claim is a no-op + survivor.source = VideoService::kSourcePattern; + survivor.applyState(); + + delete elected; // ~ActiveInstance vacates: the seat is now empty + CHECK(VideoService::latestFrame()->rgb == nullptr); + + survivor.tick(); // the survivor inherits it + CHECK(VideoService::latestFrame()->rgb != nullptr); +} + +// Accepting a non-whitespace separator eats a pixel and shifts every channel one place, which tints the whole image rather than failing. +TEST_CASE("VideoService PPM: the separator must be whitespace, not merely present") { + uint16_t w = 0, h = 0; + CHECK(parse("P6\n2 2\n255X", w, h) == -1); + CHECK(parse("P6\n2 2\n255\n", w, h) == 11); // the same header with a real separator +} + +// The sweep is a RATE rather than a phase of the clock, so a rate change moves smoothly rather than jumping, and 0 parks the block as a still reference. +TEST_CASE("VideoService: the test pattern sweeps at patternSpeed pixels per second, and 0 parks it") { + struct ClockGuard { ~ClockGuard() { mm::platform::setTestNowMs(0); } } guard; + // Column of the white block on the top row, which is otherwise the red band. + auto sweepX = [] { + const mm::VideoFrame* f = VideoService::latestFrame(); + for (int x = 0; x < f->width; x++) + if (f->rgb[static_cast(x) * 3 + 1] == 255) return x; + return -1; + }; + + mm::platform::setTestNowMs(1000); + VideoService v; + v.source = VideoService::kSourcePattern; + v.patternSpeed = 10; + v.applyState(); // the first frame takes the clock and charges nothing + const int start = sweepX(); + REQUIRE(start >= 0); + + mm::platform::setTestNowMs(1500); // 0.5 s at 10 px/s + v.tick(); + CHECK(sweepX() == (start + 5) % VideoService::kPatternW); + + v.patternSpeed = 0; + mm::platform::setTestNowMs(4000); + v.tick(); + CHECK(sweepX() == (start + 5) % VideoService::kPatternW); // parked, however long passes +} + +// Every source publishes one, SDR included: sRGB is a curve like any other, and a consumer averaging raw bytes averages a quantity that is not proportional to light. +TEST_CASE("VideoService: an SDR source publishes the sRGB curve, not nothing") { + VideoService v; + v.source = VideoService::kSourcePattern; + v.applyState(); + const uint16_t* t = VideoService::latestFrame()->tone; + REQUIRE(t != nullptr); + CHECK(t[0] == 0); + CHECK(t[255] == mm::VideoFrame::kLinearMax); + // sRGB's midpoint is about 21% of full light: the whole reason averaging bytes is wrong. + CHECK(t[128] < mm::VideoFrame::kLinearMax / 3); + CHECK(t[128] > mm::VideoFrame::kLinearMax / 8); +} + +// The frame carries its curve and consumers read through channel(), so every reader corrects the same way and none has to know which curve it is. Null means the bytes are taken as they are. +TEST_CASE("VideoFrame: channel() reads through the tone curve when one is published") { + uint8_t px[3] = {10, 20, 30}; + uint16_t tone[256]; + for (int i = 0; i < 256; i++) tone[i] = static_cast(255 - i); + mm::VideoFrame f; + f.rgb = px; + CHECK(f.channel(px, 0) == 10); + CHECK(f.channel(px, 2) == 30); + f.tone = tone; + CHECK(f.channel(px, 0) == 245); + CHECK(f.channel(px, 1) == 235); +} diff --git a/test/unit/light/unit_AmbilightEffect.cpp b/test/unit/light/unit_AmbilightEffect.cpp new file mode 100644 index 000000000..08ad9070d --- /dev/null +++ b/test/unit/light/unit_AmbilightEffect.cpp @@ -0,0 +1,567 @@ +/// @module AmbilightEffect +/// +/// Pins the frame to light mapping end to end through the real static seam: a live VideoService publishes a frame, the effect renders it, the buffer is read back. +/// +/// @moreinfo +/// +/// The checks are about orientation and coverage, because a picture averaged over the wrong rectangle, or flipped top for bottom, still looks like *a* picture. + +#include "doctest.h" +#include "core/services/VideoService.h" +#include "light/effects/AmbilightEffect.h" +#include "light/layouts/GridLayout.h" +#include "light/layouts/LayoutBase.h" +#include "light/layouts/SphereLayout.h" +#include "platform/platform.h" // fsRootPath: ctest roots the filesystem in the build tree +#include "light/layouts/Layouts.h" + +#include +#include +#include + +using mm::AmbilightEffect; +using mm::VideoService; +namespace platform = mm::platform; + +namespace { + +// A live VideoService in test-pattern mode: red top band, blue bottom, yellow left, green right. Its seat is claimed on construction and vacated on destruction, so each case starts clean. +struct PatternSource { + VideoService svc; + PatternSource() { + svc.source = 0; // test pattern + svc.applyState(); // builds the buffer and renders the first frame + } +}; + +// Render one frame of the effect over a `w`x`h` grid and hand back the layer for inspection. +struct Rig { + mm::Layouts layouts; + mm::GridLayout grid; + mm::Layer layer; + AmbilightEffect fx; + + Rig(uint16_t w, uint16_t h) { + grid.width = w; + grid.height = h; + grid.depth = 1; + layouts.addChild(&grid); + layer.setLayouts(&layouts); + layer.setChannelsPerLight(3); + layer.addChild(&fx); + } + void render() { + layer.applyState(); + layer.tick(); + } + // applyState() re-runs prepare(), which un-primes the smoother and makes every frame jump. Anything testing the SMOOTHING has to tick without it. + void tickOnly() { layer.tick(); } + /// A tick with a NEW frame behind it: the effect skips a repeated one, so anything measuring per-frame behavior has to advance the source too, as the scheduler does. + void tickOnly(VideoService& source) { + source.tick(); + layer.tick(); + } + const uint8_t* px(int x, int y) const { + return layer.buffer().data() + (static_cast(y) * grid.width + x) * 3; + } +}; + +} // namespace + +// Orientation must survive to the buffer: red top band → red first row. Swapped, the whole picture is upside down: on a TV border, the difference between matching the screen and mirroring it. +TEST_CASE("AmbilightEffect: the frame's orientation reaches the buffer, top band to top row") { + PatternSource src; + Rig rig(8, 8); + rig.fx.saturation = 100; // identity, so the raw zone means are what we read + rig.render(); + + const uint8_t* top = rig.px(4, 0); + const uint8_t* bottom = rig.px(4, 7); + CHECK(top[0] > top[2]); // top row reads red-dominant + CHECK(bottom[2] > bottom[0]); // bottom row reads blue-dominant +} + +// The horizontal counterpart of the test above; together they pin all four edges. Red separates the bands: it is in yellow and absent from green. +TEST_CASE("AmbilightEffect: the frame's left and right bands reach the matching columns") { + PatternSource src; + Rig rig(8, 8); + rig.fx.saturation = 100; + rig.render(); + + const uint8_t* left = rig.px(0, 4); // mid-height, so neither the top nor bottom band + const uint8_t* right = rig.px(7, 4); + CHECK(left[0] > right[0]); // yellow carries red; green does not + CHECK(right[1] > 0); // and the right column is lit at all +} + +// Every light must be written. An empty zone leaves its light holding the previous frame, so a mapping bug shows as dead lights scattered through the strip rather than an obvious failure. +TEST_CASE("AmbilightEffect: every light is written, none left dark by an empty zone") { + PatternSource src; + Rig rig(16, 9); + rig.fx.saturation = 100; + rig.render(); + + // WRITTEN, not lit: the pattern's center is black, so counting lit cells cannot tell "every position was painted" from "one was". Fill with a value the effect cannot produce instead. + constexpr uint8_t kSentinel = 0x5A; + std::memset(rig.layer.buffer().data(), kSentinel, static_cast(16) * 9 * 3); + rig.render(); + + for (int y = 0; y < 9; y++) + for (int x = 0; x < 16; x++) { + const uint8_t* p = rig.px(x, y); + const bool untouched = p[0] == kSentinel && p[1] == kSentinel && p[2] == kSentinel; + CHECK_FALSE(untouched); + } + // The corners sit inside the colored bands and must never be dark. + for (const auto& [x, y] : {std::pair{0, 0}, std::pair{15, 0}, std::pair{0, 8}, std::pair{15, 8}}) { + const uint8_t* p = rig.px(x, y); + CHECK((p[0] || p[1] || p[2])); + } +} + +// More lights than source pixels: neighboring positions must SHARE one rather than resolve to an empty zone. The pattern is 64 wide, so a 128-wide layer forces the guard. +TEST_CASE("AmbilightEffect: a layer finer than the frame still writes every light") { + PatternSource src; + Rig rig(128, 4); + rig.fx.saturation = 100; + rig.render(); + + // Top row of the pattern is the red band. At 4 rows tall every row samples some band, so the whole first row must be lit across its full width. + for (int x = 0; x < 128; x++) { + const uint8_t* p = rig.px(x, 0); + CHECK((p[0] || p[1] || p[2])); + } +} + +// brightness scales the result down uniformly. Distinct from the driver's brightness: this one dims the video relative to whatever else is composited beside it. +TEST_CASE("AmbilightEffect: brightness scales the sampled color down") { + PatternSource src; + Rig full(8, 8); + full.fx.saturation = 100; + full.fx.brightness = 255; + full.render(); + const int fullRed = full.px(4, 0)[0]; + + Rig dim(8, 8); + dim.fx.saturation = 100; + dim.fx.brightness = 64; + dim.render(); + const int dimRed = dim.px(4, 0)[0]; + + CHECK(fullRed > 0); + CHECK(dimRed < fullRed); + CHECK(dimRed == (fullRed * 64) / 255); +} + +// Saturation stretches each channel away from the zone's luma: above 100 a colored zone gets more saturated, which is what pulls averaged means back off gray. +TEST_CASE("AmbilightEffect: saturation above 100 pushes a colored zone further from gray") { + PatternSource src; + Rig flat(8, 8); + flat.fx.saturation = 100; + flat.render(); + const uint8_t* a = flat.px(4, 0); + const int flatSpread = static_cast(a[0]) - static_cast(a[2]); + + Rig boosted(8, 8); + boosted.fx.saturation = 180; + boosted.render(); + const uint8_t* b = boosted.px(4, 0); + const int boostedSpread = static_cast(b[0]) - static_cast(b[2]); + + CHECK(flatSpread > 0); + CHECK(boostedSpread >= flatSpread); // red pulled further from blue, or already clipped at 255 +} + +// No source paints black rather than returning early, which would leave the PREVIOUS effect's picture frozen on the strip. Every effect owns its background (unit_Effects_gridsweep). +TEST_CASE("AmbilightEffect: no video source paints black, never the previous effect's frame") { + // No PatternSource here, so no service holds the seat and latestFrame() reports nothing. + REQUIRE(VideoService::latestFrame()->rgb == nullptr); + + Rig rig(4, 4); + rig.layer.applyState(); + // Paint a recognizable frame, standing in for whatever effect ran before this one. + uint8_t* buf = rig.layer.buffer().data(); + REQUIRE(buf != nullptr); + for (size_t i = 0; i < rig.layer.buffer().count(); i++) { + buf[i * 3 + 0] = 11; + buf[i * 3 + 1] = 22; + buf[i * 3 + 2] = 33; + } + rig.layer.tick(); + CHECK(rig.px(2, 2)[0] == 0); + CHECK(rig.px(2, 2)[1] == 0); + CHECK(rig.px(2, 2)[2] == 0); +} + +// --- Smoothing --------------------------------------------------------------------------------- +// The accumulators are 8.8 precisely so a slow setting still ARRIVES: in whole bytes every step rounds to zero and the light stalls short of its target forever. These check that it converges, and that a big move still lands at once. + +// Off must be bit-identical to no smoothing at all, since it is the default. +TEST_CASE("AmbilightEffect: smoothing off follows the frame exactly") { + PatternSource src; + Rig plain(8, 8), off(8, 8); + plain.fx.saturation = 100; + off.fx.saturation = 100; + off.fx.smoothing = 0; + plain.render(); + off.render(); + CHECK(std::memcmp(plain.px(4, 0), off.px(4, 0), 3) == 0); +} + +// The first frame after a gap must land immediately: creeping up from black would show as a fade-in every time the source reconnects. +TEST_CASE("AmbilightEffect: the first frame lands whole, not smoothed up out of black") { + PatternSource src; + Rig fast(8, 8), slow(8, 8); + fast.fx.saturation = 100; + slow.fx.saturation = 100; + slow.fx.smoothing = 240; // very slow, so a smoothed first frame would be nearly black + fast.render(); + slow.render(); + CHECK(std::memcmp(fast.px(4, 0), slow.px(4, 0), 3) == 0); +} + +// The one that 8-bit state would fail: with heavy smoothing each step is a fraction of a byte. Both directions, because >> floors and the two arrive by different routes. +TEST_CASE("AmbilightEffect: a heavily smoothed light converges exactly, rising and falling") { + PatternSource src; + Rig rig(8, 8); + rig.fx.saturation = 100; + rig.fx.smoothing = 250; // a step of ~6/256 of the remaining distance + rig.fx.snapAbove = 0; // never jump, so only the smoothing can get it there + rig.render(); // primes on the first frame, so this one lands whole + + const uint8_t bright = rig.px(4, 0)[0]; + REQUIRE(bright > 8); // the band has somewhere to fall from + + // Falling: drive the target down and let it smooth in. + rig.fx.brightness = 8; + for (int i = 0; i < 2000; i++) rig.tickOnly(src.svc); + const uint8_t dim = rig.px(4, 0)[0]; + CHECK(dim < bright / 2); + + // Rising back to where it started must land on the SAME value, not one short. + rig.fx.brightness = 255; + for (int i = 0; i < 2000; i++) rig.tickOnly(src.svc); + CHECK(rig.px(4, 0)[0] == bright); +} + +// --- edgeDepth --------------------------------------------------------------------------------- +// A border light's own share is 1/height of the frame, a sliver at the very edge. edgeDepth lets the outermost positions reach further in without changing how many there are. + +// Off is the default, so it must be the plain division exactly. +TEST_CASE("AmbilightEffect: edgeDepth 0 leaves the zones as the plain division") { + PatternSource src; + Rig plain(8, 8), zero(8, 8); + plain.fx.saturation = 100; + zero.fx.saturation = 100; + zero.fx.edgeDepth = 0; + plain.render(); + zero.render(); + CHECK(std::memcmp(plain.px(4, 0), zero.px(4, 0), 3) == 0); +} + +// The point of the control: the top row must see further down the picture than its own 1/8 share. +TEST_CASE("AmbilightEffect: edgeDepth makes the outer row sample deeper") { + PatternSource src; + Rig shallow(8, 8), deep(8, 8); + shallow.fx.saturation = 100; + deep.fx.saturation = 100; + deep.fx.edgeDepth = 50; // half the frame, so it reaches well past the top band + shallow.render(); + deep.render(); + CHECK(std::memcmp(shallow.px(4, 0), deep.px(4, 0), 3) != 0); +} + +// The control SETS the depth, it does not raise a floor: a value below a position's own share must make its zone thinner +TEST_CASE("AmbilightEffect: edgeDepth below the natural share makes the outer row thinner") { + PatternSource src; + // Three rows over a 36-tall pattern is a 12-row share, which reaches past the 9-row red band into the black center. A shallower zone stays inside the band, so it reads BRIGHTER. + Rig plain(8, 3), thin(8, 3); + plain.fx.saturation = 100; + thin.fx.saturation = 100; + thin.fx.edgeDepth = 10; // ~4 rows, against a natural share of 12 + plain.render(); + thin.render(); + CHECK(thin.px(4, 0)[0] > plain.px(4, 0)[0]); +} + +// Only the outermost ring moves. An interior position has no edge to reach in from, so a video wall is unaffected even with the control turned up. +TEST_CASE("AmbilightEffect: edgeDepth leaves interior positions alone") { + PatternSource src; + Rig plain(8, 8), deep(8, 8); + plain.fx.saturation = 100; + deep.fx.saturation = 100; + deep.fx.edgeDepth = 50; + plain.render(); + deep.render(); + for (int y = 1; y < 7; y++) + for (int x = 1; x < 7; x++) CHECK(std::memcmp(plain.px(x, y), deep.px(x, y), 3) == 0); +} + +// --- Black bars -------------------------------------------------------------------------------- +// A letterboxed film puts bars exactly where the top and bottom lights look, so those lights go dark while the picture is bright. Detection moves the zones past the bar, which edgeDepth cannot do. + +namespace { + +// A VideoService reading a P6 PPM written here: `bar` black rows top and bottom, green between. Written to a file because that is the seam the file source actually uses. +struct Letterbox { + VideoService svc; + char path[64] = {}; + Letterbox(int w, int h, int bar) { + // The service resolves a bare name under the desktop filesystem root, which ctest points into the build tree. Ask for the resolved root rather than assuming one. + std::snprintf(path, sizeof(path), "mm_letterbox_%dx%d_%d.ppm", w, h, bar); + char real[256]; + std::snprintf(real, sizeof(real), "%s/%s", mm::platform::fsRootPath(), path); + mm::platform::fsMkdir("/"); // ctest's root is a path, not necessarily a directory yet + std::FILE* f = std::fopen(real, "wb"); + REQUIRE(f != nullptr); + std::fprintf(f, "P6\n%d %d\n255\n", w, h); + for (int y = 0; y < h; y++) + for (int x = 0; x < w; x++) { + const bool picture = y >= bar && y < h - bar; + const uint8_t px[3] = {0, picture ? uint8_t(200) : uint8_t(0), 0}; + std::fwrite(px, 1, 3, f); + } + std::fclose(f); + svc.source = 1; + std::strncpy(svc.file, path, sizeof(svc.file) - 1); + svc.applyState(); + } + ~Letterbox() { + char real[256]; + std::snprintf(real, sizeof(real), "%s/%s", mm::platform::fsRootPath(), path); + std::remove(real); + } +}; + + +// A frame every line of which reads DARK to the bar probe, with brighter outer rows than middle ones, so a wrongly adopted bar changes what the edge lights see. Same shape as Letterbox. +struct DimFrame { + VideoService svc; + char path[64] = {}; + DimFrame(int w, int h, uint8_t outer, uint8_t inner, int band) { + std::snprintf(path, sizeof(path), "mm_dim_%dx%d_%d.ppm", w, h, band); + char real[256]; + std::snprintf(real, sizeof(real), "%s/%s", mm::platform::fsRootPath(), path); + mm::platform::fsMkdir("/"); + std::FILE* f = std::fopen(real, "wb"); + REQUIRE(f != nullptr); + std::fprintf(f, "P6\n%d %d\n255\n", w, h); + for (int y = 0; y < h; y++) + for (int x = 0; x < w; x++) { + const uint8_t v = (y < band || y >= h - band) ? outer : inner; + const uint8_t px[3] = {v, v, v}; + std::fwrite(px, 1, 3, f); + } + std::fclose(f); + svc.source = 1; + std::strncpy(svc.file, path, sizeof(svc.file) - 1); + svc.applyState(); + } + ~DimFrame() { + char real[256]; + std::snprintf(real, sizeof(real), "%s/%s", mm::platform::fsRootPath(), path); + std::remove(real); + } +}; + +} // namespace + +// Off by default: no scan, no shift, identical to before the feature existed. +TEST_CASE("AmbilightEffect: blackBars off maps across the whole frame") { + PatternSource src; + Rig plain(8, 8), off(8, 8); + plain.fx.saturation = 100; + off.fx.saturation = 100; + off.fx.detectBlackBars = false; + plain.render(); + off.render(); + CHECK(std::memcmp(plain.px(4, 0), off.px(4, 0), 3) == 0); +} + +// The top light sits in the bar and reads black; with detection it reads the picture instead. +TEST_CASE("AmbilightEffect: the top light escapes the letterbox once bars are detected") { + Letterbox src(64, 64, 16); // a quarter of the height black at each end + Rig rig(8, 8); + rig.fx.saturation = 100; + rig.fx.detectBlackBars = true; + rig.render(); + + CHECK(rig.px(4, 0)[1] == 0); // first frame: still inside the bar + for (int i = 0; i < 60; i++) rig.tickOnly(src.svc); // past the hysteresis window + CHECK(rig.px(4, 0)[1] > 100); // now reading the green picture +} + +// Dark EVERYWHERE by the probe, but not uniform. Scanning to the ceiling used to report the deepest bar on all four edges, cropping a dark scene to its middle for kStableFrames after it ended. +TEST_CASE("AmbilightEffect: an all-dark frame reports no bars, not the deepest ones") { + // 40% of 64 is a 25-line ceiling. Rows 0..24 sit at 60, under barLevel 64, so the scan runs the whole way; rows 25..38 are black, which the top light would read if a bar were adopted. + DimFrame src(64, 64, 60, 0, 25); + Rig rig(8, 8); + rig.fx.saturation = 100; + rig.fx.detectBlackBars = true; + rig.fx.barLevel = 64; + rig.render(); + + const uint8_t first = rig.px(4, 0)[0]; + REQUIRE(first > 0); // reading the bright outer rows, not the middle + for (int i = 0; i < 60; i++) rig.tickOnly(src.svc); // past the hysteresis window + CHECK(rig.px(4, 0)[0] == first); // nothing adopted, so nothing moved +} + +// The pattern's center is black and its edges are colored: the OPPOSITE of a letterbox. Nothing must be detected in it, or a picture that fills the frame would get cropped. +TEST_CASE("AmbilightEffect: a frame that fills the picture reports no bars") { + PatternSource src; + Rig plain(8, 8), armed(8, 8); + plain.fx.saturation = 100; + armed.fx.saturation = 100; + armed.fx.detectBlackBars = true; + plain.render(); + armed.render(); + for (int i = 0; i < 60; i++) armed.tickOnly(src.svc); + CHECK(std::memcmp(plain.px(4, 0), armed.px(4, 0), 3) == 0); +} + +// --- Skipping positions that reach no LED ------------------------------------------------------- +// A border layout maps its interior to nothing, so the effect asks the LUT and skips those positions. GridLayout is identity, so the video-wall case is unaffected. + +namespace { + +// A hollow rectangle, local to this file: perimeter lit, interior reaching no LED. Local rather than a shipped layout, since what is under test is the EFFECT asking the mapping. +struct HollowRect : mm::LayoutBase { + uint16_t width = 8; + uint16_t height = 8; + + mm::nrOfLightsType lightCount() const override { + return static_cast(2 * width + 2 * height - 4); // corners counted once + } + + void placeLights(const mm::CoordSink& sink) const override { + mm::nrOfLightsType i = 0; + const int w = width, h = height; + for (int x = 0; x < w; x++) sink.pixel(i++, static_cast(x), 0, 0); + for (int y = 1; y < h; y++) sink.pixel(i++, static_cast(w - 1), static_cast(y), 0); + for (int x = w - 2; x >= 0; x--) sink.pixel(i++, static_cast(x), static_cast(h - 1), 0); + for (int y = h - 2; y >= 1; y--) sink.pixel(i++, 0, static_cast(y), 0); + } +}; + +// The Rig above, with that hollow rectangle in place of the grid. +struct RectRig { + mm::Layouts layouts; + HollowRect rect; + mm::Layer layer; + AmbilightEffect fx; + + RectRig(uint16_t w, uint16_t h) { + rect.width = w; + rect.height = h; + layouts.addChild(&rect); + layer.setLayouts(&layouts); + layer.setChannelsPerLight(3); + layer.addChild(&fx); + } + void render() { + layer.applyState(); + layer.tick(); + } + const uint8_t* px(int x, int y) const { + return layer.buffer().data() + (static_cast(y) * rect.width + x) * 3; + } +}; + +} // namespace + +TEST_CASE("AmbilightEffect: a border layout paints its perimeter and skips the interior") { + PatternSource src; + RectRig rig(8, 8); + rig.fx.saturation = 100; + rig.render(); + + // The perimeter reaches LEDs, so it carries the picture. + const uint8_t* top = rig.px(4, 0); + CHECK((top[0] | top[1] | top[2]) != 0); + + // The interior reaches none. Never averaged, never written. it holds the black that Layer::prepare() left in the buffer on the rebuild the effect's own prepare() rode in on. + for (int y = 1; y < 7; y++) + for (int x = 1; x < 7; x++) { + const uint8_t* p = rig.px(x, y); + CHECK((p[0] | p[1] | p[2]) == 0); + } + + // And it stays black across further frames, rather than only on the first. + for (int i = 0; i < 5; i++) rig.layer.tick(); + for (int y = 1; y < 7; y++) + for (int x = 1; x < 7; x++) { + const uint8_t* p = rig.px(x, y); + CHECK((p[0] | p[1] | p[2]) == 0); + } +} + +// The effect is D2 and Layer::extrude() copies its front slice across the depth. On a sparse 3D layout a column whose only LEDs sit at z > 0 must be painted at z = 0 too. +TEST_CASE("AmbilightEffect: a sparse 3D layout lights an LED behind an empty front-face position") { + PatternSource src; + mm::Layouts layouts; + mm::SphereLayout sphere; + mm::Layer layer; + AmbilightEffect fx; + sphere.radius = 2; // a 5x5x5 box; the shell point (4,2,2) has no LED anywhere at z = 0 in its column + layouts.addChild(&sphere); + layer.setLayouts(&layouts); + layer.setChannelsPerLight(3); + layer.addChild(&fx); + fx.saturation = 100; + layer.applyState(); + layer.tick(); + + const mm::MappingLUT& lut = layer.lut(); + REQUIRE(layer.depth() == 5); + REQUIRE_FALSE(lut.hasDestination(2 * 5 + 4)); // (4,2) at z = 0: nothing + REQUIRE(lut.hasDestination((2 * 5 + 2) * 5 + 4)); // (4,2) at z = 2: on the shell + const uint8_t* p = layer.buffer().data() + ((2 * 5 + 2) * 5 + 4) * 3; + CHECK((p[0] | p[1] | p[2]) != 0); +} + + +// --- Skipping a repeated frame ----------------------------------------------------------------- +// The render loop outruns the source (60 Hz against 30 fps video, or a still picture) and re-averaging a frame already on the strip buys nothing. What the effect advances then runs at the source's rate, which is the rate it should run at. + +// A skipped tick must leave the strip exactly as it was, not half-painted or cleared. +TEST_CASE("AmbilightEffect: a repeated frame leaves the strip untouched") { + PatternSource src; + Rig rig(8, 8); + rig.fx.saturation = 100; + rig.render(); + + uint8_t before[3]; + std::memcpy(before, rig.px(4, 0), 3); + for (int i = 0; i < 5; i++) rig.tickOnly(); // no new frame published + CHECK(std::memcmp(before, rig.px(4, 0), 3) == 0); +} + +// Turning detection off has to clear the hysteresis, not only the adopted bars. A surviving candidate with a saturated counter agrees with itself the moment detection returns, so the adoption branch never fires again and the control looks dead. +TEST_CASE("AmbilightEffect: detection can be turned off and on again") { + Letterbox src(64, 64, 16); + Rig rig(8, 8); + rig.fx.saturation = 100; + rig.fx.detectBlackBars = true; + rig.render(); + for (int i = 0; i < 60; i++) rig.tickOnly(src.svc); + REQUIRE(rig.px(4, 0)[1] > 100); // bars adopted, reading the picture + + rig.fx.detectBlackBars = false; + rig.tickOnly(src.svc); + CHECK(rig.px(4, 0)[1] == 0); // back to the frame, so back inside the bar + + rig.fx.detectBlackBars = true; + for (int i = 0; i < 60; i++) rig.tickOnly(src.svc); + CHECK(rig.px(4, 0)[1] > 100); // and adopted again rather than stuck +} + +// Averaging happens in LINEAR light rather than in the encoding: half black and half white is half the light, which sRGB writes as 188 where the byte mean is 128. +TEST_CASE("AmbilightEffect: a part-lit zone averages as light, not as bytes") { + PatternSource src; + Rig rig(1, 1); + rig.fx.saturation = 100; // identity, so the zone mean is what we read + rig.render(); + CHECK(rig.px(0, 0)[0] > 120); + CHECK(rig.px(0, 0)[0] < 180); +}