warp-pipe/include/warppipe/warppipe.hpp
2026-01-30 10:40:52 -07:00

227 lines
5.1 KiB
C++

#pragma once
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
namespace warppipe {
enum class StatusCode : uint8_t {
kOk = 0,
kInvalidArgument,
kNotFound,
kUnavailable,
kPermissionDenied,
kTimeout,
kInternal,
kNotImplemented,
};
struct Status {
StatusCode code = StatusCode::kOk;
std::string message;
static Status Ok();
static Status Error(StatusCode code, std::string message);
bool ok() const;
};
template <typename T>
struct Result {
Status status;
T value{};
bool ok() const { return status.ok(); }
};
enum class ThreadingMode : uint8_t {
kCallerThread = 0,
kThreadLoop,
};
struct ConnectionOptions {
ThreadingMode threading = ThreadingMode::kThreadLoop;
bool autoconnect = true;
bool policy_only = false;
std::string application_name = "warppipe";
std::optional<std::string> remote_name;
std::optional<std::string> config_path;
};
struct AudioFormat {
uint32_t rate = 48000;
uint32_t channels = 2;
};
enum class VirtualBehavior : uint8_t {
kNull = 0,
kLoopback,
};
struct VirtualNodeOptions {
AudioFormat format{};
VirtualBehavior behavior = VirtualBehavior::kNull;
std::optional<std::string> target_node;
std::optional<std::string> media_class_override;
std::string display_name;
std::string group;
};
struct NodeId {
uint32_t value = 0;
};
struct PortId {
uint32_t value = 0;
};
struct LinkId {
uint32_t value = 0;
};
struct RuleId {
uint32_t value = 0;
};
struct NodeInfo {
NodeId id;
std::string name;
std::string description;
std::string media_class;
std::string application_name;
std::string process_binary;
std::string media_role;
bool is_virtual = false;
};
struct PortInfo {
PortId id;
NodeId node;
std::string name;
bool is_input = false;
};
struct VirtualSink {
NodeId node;
std::string name;
};
struct VirtualSource {
NodeId node;
std::string name;
};
struct Link {
LinkId id;
PortId output_port;
PortId input_port;
};
struct LinkOptions {
bool passive = false;
bool linger = false;
};
struct RuleMatch {
std::string application_name;
std::string process_binary;
std::string media_role;
};
struct RouteRule {
RuleId id;
RuleMatch match;
std::string target_node;
};
struct VolumeState {
float volume = 1.0f;
bool mute = false;
};
struct MeterState {
float peak_left = 0.0f;
float peak_right = 0.0f;
};
struct MetadataInfo {
std::string default_sink_name;
std::string default_source_name;
std::string configured_sink_name;
std::string configured_source_name;
};
class Client {
public:
Client(const Client&) = delete;
Client& operator=(const Client&) = delete;
Client(Client&&) noexcept;
Client& operator=(Client&&) noexcept;
~Client();
static Result<std::unique_ptr<Client>> Create(const ConnectionOptions& options);
Status Shutdown();
Result<std::vector<NodeInfo>> ListNodes();
Result<std::vector<PortInfo>> ListPorts(NodeId node);
Result<std::vector<Link>> ListLinks();
Result<VirtualSink> CreateVirtualSink(std::string_view name,
const VirtualNodeOptions& options = VirtualNodeOptions{});
Result<VirtualSource> CreateVirtualSource(std::string_view name,
const VirtualNodeOptions& options = VirtualNodeOptions{});
Status RemoveNode(NodeId node);
Status SetNodeVolume(NodeId node, float volume, bool mute);
Result<VolumeState> GetNodeVolume(NodeId node) const;
Status EnsureNodeMeter(NodeId node);
Status DisableNodeMeter(NodeId node);
Result<MeterState> NodeMeterPeak(NodeId node) const;
Result<MeterState> MeterPeak() const;
Result<Link> CreateLink(PortId output, PortId input, const LinkOptions& options);
Result<Link> CreateLinkByName(std::string_view output_node,
std::string_view output_port,
std::string_view input_node,
std::string_view input_port,
const LinkOptions& options);
Status RemoveLink(LinkId link);
Result<RuleId> AddRouteRule(const RouteRule& rule);
Status RemoveRouteRule(RuleId id);
Result<std::vector<RouteRule>> ListRouteRules();
Result<MetadataInfo> GetDefaults();
Status SetDefaultSink(std::string_view node_name);
Status SetDefaultSource(std::string_view node_name);
Status SaveConfig(std::string_view path);
Status LoadConfig(std::string_view path);
#ifdef WARPPIPE_TESTING
Status Test_InsertNode(const NodeInfo& node);
Status Test_InsertPort(const PortInfo& port);
Status Test_InsertLink(const Link& link);
Status Test_RemoveGlobal(uint32_t id);
Status Test_ForceDisconnect();
Status Test_TriggerPolicyCheck();
size_t Test_GetPendingAutoLinkCount() const;
Status Test_SetNodeVolume(NodeId node, float volume, bool mute);
Result<VolumeState> Test_GetNodeVolume(NodeId node) const;
Status Test_SetNodeMeterPeak(NodeId node, float left, float right);
Status Test_SetMasterMeterPeak(float left, float right);
#endif
private:
struct Impl;
explicit Client(std::unique_ptr<Impl> impl);
std::unique_ptr<Impl> impl_;
};
} // namespace warppipe