diff --git a/docs/integration-guide.md b/docs/integration-guide.md index 7595702..7fcc615 100644 --- a/docs/integration-guide.md +++ b/docs/integration-guide.md @@ -121,7 +121,7 @@ The slot/channel number for each entry is its position (index) in `preferred_for ### Visualizer Role (Audio Visualization) -Receives real-time beat, loudness, peak frequency, onset, and spectrum data synchronized to playback. +Receives real-time beat, loudness, dominant-frequency, onset, and spectrum data synchronized to playback. ```cpp VisualizerSupportObject vis_support; @@ -144,6 +144,23 @@ vis_support.spectrum = VisualizerSpectrumConfig{ auto& visualizer = client.add_visualizer({.support = vis_support}); ``` +The advertised support object is the starting format. To change it at runtime, call +`request_format()` with only the fields you want to change; omitted fields keep their +current value on the server: + +```cpp +visualizer.request_format({.rate_max = 15}); // Halve the frame rate + +visualizer.request_format({ + .types = {{VisualizerDataType::BEAT, VisualizerDataType::LOUDNESS}}, +}); +``` + +While a stream is active the server replies with a fresh `stream/start`, so +`on_visualizer_stream_start()` fires again with the updated +`ServerVisualizerStreamObject`. If no stream is active, the server remembers the request +and applies it to the next stream. + ### Color Role (Audio-Derived Color Palette) Receives an RGB color palette derived by the server from the currently playing audio (e.g., extracted from album artwork). Useful for LED matrices, status lights, or themed displays. Server-to-client only; no configuration. @@ -944,10 +961,11 @@ These represent commands the server can send to the player. The player advertise | Value | Description | |---|---| -| `BEAT` | Beat detection events | -| `LOUDNESS` | Loudness level | -| `F_PEAK` | Peak frequency | -| `SPECTRUM` | Frequency spectrum bins | +| `BEAT` | Musical beat events from tempo/beat tracking | +| `LOUDNESS` | Overall loudness level | +| `F_PEAK` | Dominant frequency and its amplitude | +| `SPECTRUM` | Full frequency spectrum bins | +| `PEAK` | Energy onset (transient) events | ### VisualizerSpectrumScale diff --git a/docs/internals.md b/docs/internals.md index 1e089a4..2dc016c 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -146,8 +146,7 @@ Used for: - **`std::atomic`** on `SendspinConnection::message_dispatch_enabled_`: allows the main loop to instantly suppress message delivery from the network thread. - **`std::atomic`** on `VisualizerRole::Impl`: network thread writes stream config atomically; drain thread reads it. - **`std::atomic`** on `ArtworkRole::Impl::stream_active`: guards `handle_binary()` from writing when no stream is active. -- **`std::atomic`** on `ArtworkRole::Impl::SlotBuffer::write_idx`: tracks which of two double-buffers the network thread writes to next. -- **`std::atomic`** on `ArtworkRole::Impl::SlotBuffer::drain_active`: set by the decode thread while decoding, checked by the network thread to avoid overwriting an in-use buffer. +- **`std::mutex`** on `ArtworkRole::Impl::DrainTask::slot_mutex`: guards every field of `SlotBuffer` (shared across all slots; artwork is not a hot path, so contention is negligible). Under that lock `write_idx` tracks which of the two per-slot buffers the network thread writes to next, `drain_active`/`drain_buf_idx` record which buffer the decode thread is decoding, `write_generation[]` lets the decode thread detect a buffer overwritten before it could be claimed, and `ack_state`/`has_parked`/`parked` hold the per-slot frame-done gate. - **`std::atomic`** on `SendspinClient::high_performance_ref_count_`: ref-counted high-performance networking requests from time sync and playback. ## Message Flow