summaryrefslogtreecommitdiff
path: root/src/audio-impl-pw.hpp
blob: 7d195d5decf545852f24c80fcaf4b96fe966c710 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#ifndef PKE_AUDIO_IMPL_PW_HPP
#define PKE_AUDIO_IMPL_PW_HPP

#include <atomic>

#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 <pipewire/pipewire.h>
#include <pipewire/extensions/metadata.h>
#include <spa/param/audio/format-utils.h>
#include <spa/param/audio/raw.h>
#include <spa/param/param.h>
#include <spa/utils/string.h>
#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<pke_audio_pw_object> pw_objects;
	pk_arr_t<void*> 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 */