Docs
This commit is contained in:
parent
69debb202c
commit
9d57ba5d25
9 changed files with 235 additions and 19 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
# Warppipe GUI Plan (Qt6 Node-Based Audio Router)
|
# Warp Pipe GUI Plan (Qt6 Node-Based Audio Router)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
A Qt6-based node editor GUI for warppipe using the QtNodes (nodeeditor) library. Visualizes PipeWire audio nodes, ports, and links as draggable nodes with connection lines. Supports creating virtual sinks/sources via context menu and displays ephemeral sources with visual fade when inactive.
|
A Qt6-based node editor GUI for warppipe using the QtNodes (nodeeditor) library. Visualizes PipeWire audio nodes, ports, and links as draggable nodes with connection lines. Supports creating virtual sinks/sources via context menu and displays ephemeral sources with visual fade when inactive.
|
||||||
|
|
@ -395,7 +395,7 @@ Active vs Ghost:
|
||||||
|
|
||||||
option(BUILD_GUI "Build Qt6 GUI application" ON)
|
option(BUILD_GUI "Build Qt6 GUI application" ON)
|
||||||
|
|
||||||
if(BUILD_GUI)
|
if(WARPPIPE_BUILD_GUI)
|
||||||
find_package(Qt6 6.2 REQUIRED COMPONENTS Core Widgets)
|
find_package(Qt6 6.2 REQUIRED COMPONENTS Core Widgets)
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
@ -441,6 +441,7 @@ if(BUILD_GUI)
|
||||||
|
|
||||||
target_link_libraries(warppipe-gui-tests PRIVATE
|
target_link_libraries(warppipe-gui-tests PRIVATE
|
||||||
warppipe
|
warppipe
|
||||||
|
Qt6::Core
|
||||||
Qt6::Widgets
|
Qt6::Widgets
|
||||||
QtNodes
|
QtNodes
|
||||||
Catch2::Catch2WithMain
|
Catch2::Catch2WithMain
|
||||||
|
|
@ -464,9 +465,8 @@ endif()
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
- Qt6 >= 6.2 (Core, Widgets)
|
- Qt6 >= 6.2 (Core, Widgets)
|
||||||
- Qt6::Test (for GUI test target)
|
|
||||||
- QtNodes (nodeeditor) — fetched via CMake FetchContent
|
- QtNodes (nodeeditor) — fetched via CMake FetchContent
|
||||||
- Catch2 v3 — fetched via CMake FetchContent (shared with existing tests)
|
- Catch2 v3 — required for GUI tests (via `find_package`)
|
||||||
- warppipe library (existing)
|
- warppipe library (existing)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
2
PLAN.md
2
PLAN.md
|
|
@ -1,4 +1,4 @@
|
||||||
# Warppipe Plan (C++ libpipewire library)
|
# Warp Pipe Plan (C++ libpipewire library)
|
||||||
|
|
||||||
- [x] Milestone 0 - Groundwork and constraints
|
- [x] Milestone 0 - Groundwork and constraints
|
||||||
- [x] Choose build system: CMake (confirmed). Define minimal library target and example app target.
|
- [x] Choose build system: CMake (confirmed). Define minimal library target and example app target.
|
||||||
|
|
|
||||||
33
README.md
33
README.md
|
|
@ -1,6 +1,6 @@
|
||||||
# warppipe
|
# warppipe
|
||||||
|
|
||||||
A C++17 static library wrapping libpipewire for virtual audio node management, link routing, and per-app routing policy.
|
Warp Pipe is a C++20 static library wrapping libpipewire for virtual audio node management, link routing, and per-app routing policy.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|
@ -8,6 +8,8 @@ A C++17 static library wrapping libpipewire for virtual audio node management, l
|
||||||
- **Link management** — connect and disconnect ports by node+port name or ID, with passive and linger options
|
- **Link management** — connect and disconnect ports by node+port name or ID, with passive and linger options
|
||||||
- **Per-app routing rules** — match applications by name, process binary, or media role and auto-route to target sinks
|
- **Per-app routing rules** — match applications by name, process binary, or media role and auto-route to target sinks
|
||||||
- **Persistence** — JSON config with atomic writes, auto-save on change, auto-load on startup
|
- **Persistence** — JSON config with atomic writes, auto-save on change, auto-load on startup
|
||||||
|
- **Volume control** — set per-node volume and mute state
|
||||||
|
- **Audio metering** — per-node and master peak meters
|
||||||
- **Metadata integration** — read and set default audio sink/source via PipeWire metadata
|
- **Metadata integration** — read and set default audio sink/source via PipeWire metadata
|
||||||
- **Policy-only mode** — observe and set metadata without creating links (avoids fighting WirePlumber)
|
- **Policy-only mode** — observe and set metadata without creating links (avoids fighting WirePlumber)
|
||||||
- **Thread-safe** — dedicated PipeWire thread loop; all public methods callable from any thread
|
- **Thread-safe** — dedicated PipeWire thread loop; all public methods callable from any thread
|
||||||
|
|
@ -18,20 +20,24 @@ Requirements:
|
||||||
- CMake 3.20+
|
- CMake 3.20+
|
||||||
- pkg-config
|
- pkg-config
|
||||||
- libpipewire-0.3 development files
|
- libpipewire-0.3 development files
|
||||||
- C++17 compiler
|
- C++20 compiler
|
||||||
|
- Qt6 6.2+ (for the GUI target; disable with `-DWARPPIPE_BUILD_GUI=OFF`)
|
||||||
|
- Catch2 v3 (for tests; required when `-DWARPPIPE_BUILD_TESTS=ON`)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cmake -S . -B build
|
cmake -S . -B build
|
||||||
cmake --build build
|
cmake --build build
|
||||||
```
|
```
|
||||||
|
|
||||||
Targets: `warppipe` (library), `warppipe_example`, `warppipe_cli`, `warppipe_tests`, `warppipe_perf`
|
Targets: `warppipe` (library), `warppipe_example`, `warppipe_cli`, `warppipe_tests`, `warppipe_perf`, `warppipe-gui`, `warppipe-gui-tests`
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
- [libpipewire-0.3](https://pipewire.org/) — system package
|
- [libpipewire-0.3](https://pipewire.org/) — system package
|
||||||
- [nlohmann/json](https://github.com/nlohmann/json) — fetched automatically via CMake FetchContent
|
- [nlohmann/json](https://github.com/nlohmann/json) — fetched automatically if not installed
|
||||||
- [Catch2 v3](https://github.com/catchorg/Catch2) — fetched automatically via CMake FetchContent
|
- [Catch2 v3](https://github.com/catchorg/Catch2) — required for tests (via `find_package`)
|
||||||
|
- [Qt6](https://www.qt.io/) — required for `warppipe-gui` (default on)
|
||||||
|
- [QtNodes](https://github.com/paceholder/nodeeditor) — fetched automatically when GUI is enabled
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
|
|
@ -77,11 +83,13 @@ warppipe_cli load-config <path>
|
||||||
warppipe_cli defaults
|
warppipe_cli defaults
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`link` uses node and port names (not IDs). `--passive` sets `PW_KEY_LINK_PASSIVE`, and `--linger` sets `PW_KEY_OBJECT_LINGER` so links persist after the client exits. `defaults` prints the current and configured default sink/source names.
|
||||||
|
|
||||||
`create-sink` and `create-source` block until interrupted with Ctrl-C.
|
`create-sink` and `create-source` block until interrupted with Ctrl-C.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Config is JSON. Set `ConnectionOptions::config_path` to enable auto-save/load, or use `SaveConfig`/`LoadConfig` manually.
|
Config is JSON. Set `ConnectionOptions::config_path` to enable auto-save/load, or use `SaveConfig`/`LoadConfig` manually. The config persists virtual nodes, routing rules, saved links, and per-node volume/mute state.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -93,7 +101,9 @@ Config is JSON. Set `ConnectionOptions::config_path` to enable auto-save/load, o
|
||||||
"rate": 48000,
|
"rate": 48000,
|
||||||
"channels": 2,
|
"channels": 2,
|
||||||
"loopback": false,
|
"loopback": false,
|
||||||
"target_node": ""
|
"target_node": "",
|
||||||
|
"volume": 1.0,
|
||||||
|
"mute": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"route_rules": [
|
"route_rules": [
|
||||||
|
|
@ -105,6 +115,14 @@ Config is JSON. Set `ConnectionOptions::config_path` to enable auto-save/load, o
|
||||||
},
|
},
|
||||||
"target_node": "warppipe-gaming-sink"
|
"target_node": "warppipe-gaming-sink"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"out_node": "Firefox",
|
||||||
|
"out_port": "output_FL",
|
||||||
|
"in_node": "warppipe-gaming-sink",
|
||||||
|
"in_port": "input_FL"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -126,6 +144,7 @@ In this mode the policy engine still evaluates rules but does not create links.
|
||||||
|
|
||||||
- [API Reference](docs/api.md) — full API, threading model, error model, performance notes
|
- [API Reference](docs/api.md) — full API, threading model, error model, performance notes
|
||||||
- [Config Schema](docs/config-schema.md) — JSON configuration format and persistence behavior
|
- [Config Schema](docs/config-schema.md) — JSON configuration format and persistence behavior
|
||||||
|
- [GUI Usage](docs/gui-usage.md) — how to run the Qt GUI and capture screenshots
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
|
|
|
||||||
96
docs/api.md
96
docs/api.md
|
|
@ -1,8 +1,8 @@
|
||||||
# Warppipe API
|
# Warp Pipe API
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Warppipe is a C++17 library wrapping libpipewire for virtual audio node management, link routing, and per-app routing policy. The entire public API is in `<warppipe/warppipe.hpp>`.
|
Warp Pipe is a C++20 library wrapping libpipewire for virtual audio node management, link routing, and per-app routing policy. The entire public API is in `<warppipe/warppipe.hpp>`.
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
|
|
@ -84,6 +84,19 @@ struct ConnectionOptions {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- `ThreadingMode::kCallerThread` returns `StatusCode::kNotImplemented`.
|
||||||
|
- When `autoconnect` is false, operations return `kUnavailable` after a disconnect instead of reconnecting.
|
||||||
|
- `remote_name` connects to a non-default PipeWire instance.
|
||||||
|
|
||||||
|
## Lifecycle
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
Status Shutdown();
|
||||||
|
```
|
||||||
|
|
||||||
|
`Shutdown()` stops the PipeWire thread loop and releases resources. It is called automatically by the destructor, but you can invoke it explicitly to tear down early.
|
||||||
|
|
||||||
### Policy-Only Mode
|
### Policy-Only Mode
|
||||||
|
|
||||||
When `policy_only = true`, the policy engine observes the registry and matches rules, but does not create links. This avoids conflicts with WirePlumber or other session managers.
|
When `policy_only = true`, the policy engine observes the registry and matches rules, but does not create links. This avoids conflicts with WirePlumber or other session managers.
|
||||||
|
|
@ -117,8 +130,73 @@ Result<VirtualSource> CreateVirtualSource(std::string_view name, const VirtualNo
|
||||||
Status RemoveNode(NodeId node);
|
Status RemoveNode(NodeId node);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct VirtualNodeOptions {
|
||||||
|
AudioFormat format; // rate/channels
|
||||||
|
VirtualBehavior behavior; // kNull (default) or kLoopback
|
||||||
|
std::optional<std::string> target_node; // Required for kLoopback
|
||||||
|
std::optional<std::string> media_class_override; // Override PW_KEY_MEDIA_CLASS
|
||||||
|
std::string display_name; // PW_KEY_MEDIA_NAME / PW_KEY_NODE_DESCRIPTION
|
||||||
|
std::string group; // PW_KEY_NODE_GROUP
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Virtual nodes are PipeWire streams with `PW_KEY_NODE_VIRTUAL = true`. They live as long as the `Client` (or until explicitly removed). Null behavior discards audio; loopback behavior forwards to a target node.
|
Virtual nodes are PipeWire streams with `PW_KEY_NODE_VIRTUAL = true`. They live as long as the `Client` (or until explicitly removed). Null behavior discards audio; loopback behavior forwards to a target node.
|
||||||
|
|
||||||
|
Behavior and validation:
|
||||||
|
- `format.rate` and `format.channels` must be non-zero (`kInvalidArgument` otherwise).
|
||||||
|
- `behavior = kLoopback` requires `target_node` and the target must exist (`kInvalidArgument`/`kNotFound`).
|
||||||
|
- `media_class_override` overrides the PipeWire media class (cannot be an empty string).
|
||||||
|
- `display_name` and `group` map to `PW_KEY_MEDIA_NAME` / `PW_KEY_NODE_DESCRIPTION` and `PW_KEY_NODE_GROUP`.
|
||||||
|
|
||||||
|
Example loopback node:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
warppipe::VirtualNodeOptions opts;
|
||||||
|
opts.behavior = warppipe::VirtualBehavior::kLoopback;
|
||||||
|
opts.target_node = "alsa_output.pci-0000_00_1f.3.analog-stereo";
|
||||||
|
auto sink = client->CreateVirtualSink("warppipe-loopback", opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Volume Control
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
Status SetNodeVolume(NodeId node, float volume, bool mute);
|
||||||
|
Result<VolumeState> GetNodeVolume(NodeId node) const;
|
||||||
|
|
||||||
|
struct VolumeState {
|
||||||
|
float volume; // 0.0 - 1.5
|
||||||
|
bool mute;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
`SetNodeVolume` clamps `volume` to `[0.0, 1.5]` and stores the last known volume/mute state. `GetNodeVolume` returns the cached state (defaults to 1.0/false when unknown). Volume and mute are persisted in config files when saved.
|
||||||
|
|
||||||
|
## Audio Metering
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
Status EnsureNodeMeter(NodeId node);
|
||||||
|
Status DisableNodeMeter(NodeId node);
|
||||||
|
Result<MeterState> NodeMeterPeak(NodeId node) const;
|
||||||
|
Result<MeterState> MeterPeak() const;
|
||||||
|
|
||||||
|
struct MeterState {
|
||||||
|
float peak_left;
|
||||||
|
float peak_right;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Call `EnsureNodeMeter` before querying `NodeMeterPeak`; otherwise you may receive `kNotFound` for unmetered nodes. `MeterPeak` returns master peak levels gathered by a monitor stream.
|
||||||
|
|
||||||
|
## Change Notifications
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
using ChangeCallback = std::function<void()>;
|
||||||
|
void SetChangeCallback(ChangeCallback callback);
|
||||||
|
```
|
||||||
|
|
||||||
|
The callback fires when the registry cache changes (nodes/ports/links) and when volume/mute updates are observed. It is invoked on the PipeWire thread loop; do not call `Client` methods inside the callback to avoid deadlocks.
|
||||||
|
|
||||||
## Link Management
|
## Link Management
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
|
@ -131,6 +209,8 @@ Status RemoveLink(LinkId link);
|
||||||
|
|
||||||
Links are created via `link-factory` (`pw_core_create_object`). Use `linger = true` so links persist after the creating client disconnects. Use `passive = true` for monitoring/side-chain links that don't affect the session manager's routing decisions.
|
Links are created via `link-factory` (`pw_core_create_object`). Use `linger = true` so links persist after the creating client disconnects. Use `passive = true` for monitoring/side-chain links that don't affect the session manager's routing decisions.
|
||||||
|
|
||||||
|
`CreateLinkByName` matches by node and port name and returns `kNotFound` if no matching ports are found.
|
||||||
|
|
||||||
## Route Rules (Policy Engine)
|
## Route Rules (Policy Engine)
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
|
@ -148,6 +228,8 @@ Match criteria (all non-empty fields must match):
|
||||||
|
|
||||||
When a matching node appears, the engine waits for ports to register (via PipeWire sync), then creates links pairwise by port name order.
|
When a matching node appears, the engine waits for ports to register (via PipeWire sync), then creates links pairwise by port name order.
|
||||||
|
|
||||||
|
`AddRouteRule` returns `kInvalidArgument` if no match criteria are provided or if the target node name is empty.
|
||||||
|
|
||||||
Adding a rule also scans existing nodes for matches.
|
Adding a rule also scans existing nodes for matches.
|
||||||
|
|
||||||
## Metadata
|
## Metadata
|
||||||
|
|
@ -173,7 +255,13 @@ JSON format. See `docs/config-schema.md` for the schema.
|
||||||
|
|
||||||
When `config_path` is set in `ConnectionOptions`:
|
When `config_path` is set in `ConnectionOptions`:
|
||||||
- Config is loaded automatically after connection.
|
- Config is loaded automatically after connection.
|
||||||
- Config is saved automatically after mutations (add/remove rules, create/remove virtual nodes).
|
- Config is saved automatically after mutations (add/remove rules, create/remove virtual nodes, `CreateLink`/`RemoveLink`, `SetNodeVolume`).
|
||||||
|
|
||||||
|
Saved configs include virtual nodes, routing rules, saved links, and per-node volume/mute state.
|
||||||
|
|
||||||
|
## Testing Hooks
|
||||||
|
|
||||||
|
When compiled with `-DWARPPIPE_TESTING`, additional helpers are available for tests (node/port/link injection, forcing disconnects, manual policy triggers, and meter/volume overrides). These APIs are not intended for production use.
|
||||||
|
|
||||||
## Performance
|
## Performance
|
||||||
|
|
||||||
|
|
@ -206,3 +294,5 @@ warppipe_cli save-config <path>
|
||||||
warppipe_cli load-config <path>
|
warppipe_cli load-config <path>
|
||||||
warppipe_cli defaults
|
warppipe_cli defaults
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`link` uses node/port names (not IDs). `defaults` prints current and configured default sink/source names.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Warppipe Configuration Schema
|
# Warp Pipe Configuration Schema
|
||||||
|
|
||||||
Warppipe uses JSON for configuration persistence. The config file stores virtual nodes and routing rules using stable identifiers (names, not serial IDs).
|
Warp Pipe uses JSON for configuration persistence. The config file stores virtual nodes, routing rules, saved links, and per-node volume/mute using stable identifiers (names, not serial IDs).
|
||||||
|
|
||||||
## Schema Version 1
|
## Schema Version 1
|
||||||
|
|
||||||
|
|
@ -14,7 +14,9 @@ Warppipe uses JSON for configuration persistence. The config file stores virtual
|
||||||
"rate": 48000,
|
"rate": 48000,
|
||||||
"channels": 2,
|
"channels": 2,
|
||||||
"loopback": false,
|
"loopback": false,
|
||||||
"target_node": ""
|
"target_node": "",
|
||||||
|
"volume": 1.0,
|
||||||
|
"mute": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "warppipe-mic-source",
|
"name": "warppipe-mic-source",
|
||||||
|
|
@ -50,6 +52,14 @@ Warppipe uses JSON for configuration persistence. The config file stores virtual
|
||||||
},
|
},
|
||||||
"target_node": "alsa_output.usb-headset"
|
"target_node": "alsa_output.usb-headset"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"out_node": "Firefox",
|
||||||
|
"out_port": "output_FL",
|
||||||
|
"in_node": "warppipe-gaming-sink",
|
||||||
|
"in_port": "input_FL"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -64,6 +74,8 @@ Warppipe uses JSON for configuration persistence. The config file stores virtual
|
||||||
- `channels` (integer, default 2): Channel count
|
- `channels` (integer, default 2): Channel count
|
||||||
- `loopback` (boolean, default false): Whether node forwards to a target
|
- `loopback` (boolean, default false): Whether node forwards to a target
|
||||||
- `target_node` (string, optional): Required when loopback is true
|
- `target_node` (string, optional): Required when loopback is true
|
||||||
|
- `volume` (number, default 1.0): Stored node volume (0.0 - 1.5)
|
||||||
|
- `mute` (boolean, default false): Stored node mute state
|
||||||
|
|
||||||
### route_rules
|
### route_rules
|
||||||
|
|
||||||
|
|
@ -72,15 +84,27 @@ Rules match ephemeral audio sources to target sinks by stable application metada
|
||||||
- `match.application_name` (string): Match PW_KEY_APP_NAME
|
- `match.application_name` (string): Match PW_KEY_APP_NAME
|
||||||
- `match.process_binary` (string): Match PW_KEY_APP_PROCESS_BINARY
|
- `match.process_binary` (string): Match PW_KEY_APP_PROCESS_BINARY
|
||||||
- `match.media_role` (string): Match PW_KEY_MEDIA_ROLE
|
- `match.media_role` (string): Match PW_KEY_MEDIA_ROLE
|
||||||
|
- `id` (integer, optional): Auto-saved rule id (ignored on load)
|
||||||
- `target_node` (string, required): Destination node name
|
- `target_node` (string, required): Destination node name
|
||||||
|
|
||||||
All non-empty match fields must match (AND logic). At least one match field must be non-empty.
|
All non-empty match fields must match (AND logic). At least one match field must be non-empty.
|
||||||
|
|
||||||
|
### links
|
||||||
|
|
||||||
|
Saved links are recreated by matching node and port names when both endpoints appear.
|
||||||
|
|
||||||
|
- `out_node` (string, required): Output node name
|
||||||
|
- `out_port` (string, required): Output port name
|
||||||
|
- `in_node` (string, required): Input node name
|
||||||
|
- `in_port` (string, required): Input port name
|
||||||
|
|
||||||
## Persistence Behavior
|
## Persistence Behavior
|
||||||
|
|
||||||
- **Auto-save**: When `ConnectionOptions::config_path` is set, config is saved after:
|
- **Auto-save**: When `ConnectionOptions::config_path` is set, config is saved after:
|
||||||
- Virtual node created/removed
|
- Virtual node created/removed
|
||||||
- Routing rule added/removed
|
- Routing rule added/removed
|
||||||
|
- `SetNodeVolume` updates
|
||||||
|
- `CreateLink`/`RemoveLink` updates
|
||||||
|
|
||||||
- **Load on startup**: When `config_path` is set and the file exists, it is loaded during `Client::Create()` after connection is established.
|
- **Load on startup**: When `config_path` is set and the file exists, it is loaded during `Client::Create()` after connection is established.
|
||||||
|
|
||||||
|
|
|
||||||
33
docs/gui-usage.md
Normal file
33
docs/gui-usage.md
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Warp Pipe GUI Usage
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -S . -B build
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
Disable the GUI target with `-DWARPPIPE_BUILD_GUI=OFF`.
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
```
|
||||||
|
./build/warppipe-gui
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The GUI uses `ConnectionOptions::config_path` pointed at Qt's `AppConfigLocation` with `/config.json` appended. On Linux this is typically under `~/.config/Warppipe/config.json`.
|
||||||
|
|
||||||
|
## Command-line options
|
||||||
|
|
||||||
|
- `--screenshot <path>`: capture a PNG screenshot and exit
|
||||||
|
- `--screenshot-delay <ms>`: delay before capture (default 800)
|
||||||
|
- `--debug-screenshot-dir <dir>`: save a timestamped screenshot on every graph update
|
||||||
|
- `--offscreen`: run with `QT_QPA_PLATFORM=offscreen`
|
||||||
|
- `--help`, `--version`
|
||||||
|
|
||||||
|
## Shortcuts
|
||||||
|
|
||||||
|
- `F12`: capture a screenshot to `~/Pictures/warppipe` with a timestamp
|
||||||
|
- `Ctrl+Q`: quit
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
## Build system
|
## Build system
|
||||||
|
|
||||||
- CMake 3.20+
|
- CMake 3.20+
|
||||||
- C++17
|
- C++20
|
||||||
- pkg-config
|
- pkg-config
|
||||||
- libpipewire-0.3 development files
|
- libpipewire-0.3 development files
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,21 @@ cmake --build build
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
```
|
||||||
|
./build/warppipe_perf --mode create-destroy|registry|links|policy|e2e [options]
|
||||||
|
```
|
||||||
|
|
||||||
|
Options:
|
||||||
|
- `--type` sink|source|both (default `sink`)
|
||||||
|
- `--count` N (default 200; per-type when `--type both`)
|
||||||
|
- `--events` N (registry mode, default 100)
|
||||||
|
- `--links` N (links mode, default 200)
|
||||||
|
- `--batch` N (links mode batch size)
|
||||||
|
- `--rate` N (default 48000)
|
||||||
|
- `--channels` N (default 2)
|
||||||
|
- `--target` <node-name> (loopback target)
|
||||||
|
|
||||||
Create/destroy microbenchmark (milestone 0/2):
|
Create/destroy microbenchmark (milestone 0/2):
|
||||||
```
|
```
|
||||||
./build/warppipe_perf --mode create-destroy --count 200 --type sink
|
./build/warppipe_perf --mode create-destroy --count 200 --type sink
|
||||||
|
|
@ -28,6 +43,16 @@ Link creation + removal (milestone 3):
|
||||||
./build/warppipe_perf --mode links --links 200 --batch 50
|
./build/warppipe_perf --mode links --links 200 --batch 50
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Policy auto-routing (milestone 4):
|
||||||
|
```
|
||||||
|
./build/warppipe_perf --mode policy --count 200
|
||||||
|
```
|
||||||
|
|
||||||
|
End-to-end (milestone 5):
|
||||||
|
```
|
||||||
|
./build/warppipe_perf --mode e2e --count 200
|
||||||
|
```
|
||||||
|
|
||||||
Optional format and loopback:
|
Optional format and loopback:
|
||||||
```
|
```
|
||||||
./build/warppipe_perf --mode create-destroy --count 200 --type sink --rate 48000 --channels 2
|
./build/warppipe_perf --mode create-destroy --count 200 --type sink --rate 48000 --channels 2
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,31 @@
|
||||||
|
|
||||||
Milestone 0 test instructions are tracked in docs/milestone-0.md.
|
Milestone 0 test instructions are tracked in docs/milestone-0.md.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -S . -B build -DWARPPIPE_BUILD_TESTS=ON
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
Catch2 v3 is required when tests are enabled.
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
```
|
||||||
|
./build/warppipe_tests
|
||||||
|
```
|
||||||
|
|
||||||
|
GUI tests (requires Qt6, `-DWARPPIPE_BUILD_GUI=ON`):
|
||||||
|
|
||||||
|
```
|
||||||
|
./build/warppipe-gui-tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
When tests are enabled, the library is compiled with `WARPPIPE_TESTING`, which exposes test-only helpers in the public header.
|
||||||
|
|
||||||
Planned coverage:
|
Planned coverage:
|
||||||
- Missing PipeWire daemon
|
- Missing PipeWire daemon
|
||||||
- Missing link-factory module
|
- Missing link-factory module
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue