#ifndef PKE_AUDIO_IMPL_PW_HPP #define PKE_AUDIO_IMPL_PW_HPP #include #include "pk.h" // 2025-06-24 spa does not have c++ headers so we have to use c headers. // They throw a ton of pedantic warnings that spam the build output. // Might be too large of a swath, but none of this is my code anyway. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #include #include #include #include #include #include #pragma GCC diagnostic pop #define PKE_AUDIO_POD_BUFFER_LEN 1024 enum pke_audio_pw_object_type : uint8_t { PKE_AUDIO_PW_OBJECT_TYPE_ANY, PKE_AUDIO_PW_OBJECT_TYPE_NODE, PKE_AUDIO_PW_OBJECT_TYPE_PORT, PKE_AUDIO_PW_OBJECT_TYPE_LINK, PKE_AUDIO_PW_OBJECT_TYPE_METADATA, }; struct pke_audio_pw_object { union { struct { enum pw_direction direction; uint32_t node; uint32_t id; } port; struct { uint32_t output_port; uint32_t input_port; uint32_t dummy; } link; } data; uint32_t id; enum pke_audio_pw_object_type type; struct pw_properties *props; }; struct pke_audio_implementation_pipewire { pk_membucket *bkt; pw_thread_loop *loop; uint8_t *pod_buffer; pw_stream *stream; pw_core *core; pw_registry *registry; spa_hook registry_listener; pw_metadata *metadata; spa_hook metadata_listener; pk_arr_t pw_objects; pk_arr_t created_objects; char *default_sink_name; spa_audio_info format; uint32_t default_sink_id; std::atomic_bool is_needing_output_remapped; }; extern struct pke_audio_implementation_pipewire pke_audio_pw; void pke_audio_pw_init(); void pke_audio_pw_teardown(); void pke_audio_pw_remap_outputs(); void on_pipewire_process(void *user_data); void on_pipewire_stream_param_changed(void *, uint32_t id, const struct spa_pod *param); void on_registry_event_global(void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props); void on_registry_event_global_removal(void *data, uint32_t id); #endif /* PKE_AUDIO_IMPL_PW_HPP */