diff --git a/README.md b/README.md index 958c993..bb94fe0 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,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 - [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 +- [Examples](docs/examples.md) — common patterns and usage recipes ## Tests diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..34802bb --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,115 @@ +# Warp Pipe Examples + +This page collects common usage patterns for the library and CLI. Snippets assume `#include ` and a successful `Client::Create` call. + +## Connect with auto-save + +```cpp +warppipe::ConnectionOptions opts; +opts.application_name = "my-app"; +opts.config_path = "/home/user/.config/warppipe/config.json"; + +auto result = warppipe::Client::Create(opts); +if (!result.ok()) { + // handle result.status +} +auto& client = result.value; +``` + +## Connect to a non-default PipeWire instance + +```cpp +warppipe::ConnectionOptions opts; +opts.application_name = "my-app"; +opts.remote_name = "pipewire-0"; // or a custom PipeWire instance name + +auto result = warppipe::Client::Create(opts); +``` + +## Per-app routing rule + +```cpp +warppipe::RouteRule rule; +rule.match.application_name = "Firefox"; +rule.target_node = "warppipe-gaming-sink"; + +auto add = client->AddRouteRule(rule); +if (!add.ok()) { + // kInvalidArgument if no match criteria or target is empty +} +``` + +## Loopback sink to a target 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); +``` + +## Policy-only mode (no auto-links) + +```cpp +warppipe::ConnectionOptions opts; +opts.policy_only = true; + +auto result = warppipe::Client::Create(opts); +auto& client = result.value; + +client->SetDefaultSink("warppipe-gaming-sink"); +client->SetDefaultSource("warppipe-mic-source"); +``` + +## Volume and mute + +```cpp +auto nodes = client->ListNodes(); +if (nodes.ok() && !nodes.value.empty()) { + warppipe::NodeId node = nodes.value.front().id; + client->SetNodeVolume(node, 0.85f, false); + auto state = client->GetNodeVolume(node); +} +``` + +## Audio metering + +```cpp +auto nodes = client->ListNodes(); +if (nodes.ok() && !nodes.value.empty()) { + warppipe::NodeId node = nodes.value.front().id; + client->EnsureNodeMeter(node); + auto peak = client->NodeMeterPeak(node); // kNotFound if not metered +} + +auto master = client->MeterPeak(); +``` + +## Change callback + +```cpp +client->SetChangeCallback([] { + // Fires on registry changes and volume/mute updates. + // Runs on the PipeWire thread loop; do not call Client methods here. +}); +``` + +## CLI workflow: link by name + +``` +warppipe_cli list-nodes +warppipe_cli list-ports + +warppipe_cli link --linger +warppipe_cli unlink +``` + +## Persisted links and volume state + +``` +client->SaveConfig("/tmp/warppipe.json"); +client->LoadConfig("/tmp/warppipe.json"); +``` + +Saved configs include virtual nodes, routing rules, links (by node/port name), and per-node volume/mute state. Links are recreated when both endpoints appear in the registry.