Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions docs/integration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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

Expand Down
3 changes: 1 addition & 2 deletions docs/internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,7 @@ Used for:
- **`std::atomic<bool>`** on `SendspinConnection::message_dispatch_enabled_`: allows the main loop to instantly suppress message delivery from the network thread.
- **`std::atomic<bool/uint8_t>`** on `VisualizerRole::Impl`: network thread writes stream config atomically; drain thread reads it.
- **`std::atomic<bool>`** on `ArtworkRole::Impl::stream_active`: guards `handle_binary()` from writing when no stream is active.
- **`std::atomic<uint8_t>`** on `ArtworkRole::Impl::SlotBuffer::write_idx`: tracks which of two double-buffers the network thread writes to next.
- **`std::atomic<bool>`** 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<uint8_t>`** on `SendspinClient::high_performance_ref_count_`: ref-counted high-performance networking requests from time sync and playback.

## Message Flow
Expand Down
Loading