Last active
October 13, 2023 03:14
-
-
Save CarterLi/b316aaa818de3862eba037c2120051eb to your computer and use it in GitHub Desktop.
Pipewire: enum audio devices
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -lpipewire-0.3 | |
#include <common/library.h> | |
#include <pipewire/pipewire.h> | |
#include <util/stringUtils.h> | |
struct roundtrip_data { | |
int pending; | |
struct pw_main_loop *loop; | |
}; | |
static void on_core_done(void *data, uint32_t id, int seq) | |
{ | |
struct roundtrip_data *d = data; | |
if (id == PW_ID_CORE && seq == d->pending) | |
pw_main_loop_quit(d->loop); | |
} | |
static void roundtrip(struct pw_core *core, struct pw_main_loop *loop) | |
{ | |
static const struct pw_core_events core_events = { | |
PW_VERSION_CORE_EVENTS, | |
.done = on_core_done, | |
}; | |
struct roundtrip_data d = { .loop = loop }; | |
struct spa_hook core_listener; | |
pw_core_add_listener(core, &core_listener, &core_events, &d); | |
d.pending = pw_core_sync(core, PW_ID_CORE, 0); | |
pw_main_loop_run(loop); | |
spa_hook_remove(&core_listener); | |
} | |
static void registry_event_global(void *data, uint32_t id, | |
uint32_t permissions, const char *type, uint32_t version, | |
const struct spa_dict *props) | |
{ | |
if (!ffStrEquals(type, PW_TYPE_INTERFACE_Device)) return; | |
bool found = false; | |
for (uint32_t i = 0; i < props->n_items; ++i) | |
{ | |
const struct spa_dict_item* item = &props->items[i]; | |
if (ffStrEquals(item->key, PW_KEY_MEDIA_CLASS)) | |
{ | |
if (!ffStrEquals(item->value, "Audio/Device")) return; | |
found = true; | |
break; | |
} | |
} | |
if (!found) | |
return; | |
const char* deviceName = NULL; | |
for (uint32_t i = 0; i < props->n_items; ++i) | |
{ | |
const struct spa_dict_item* item = &props->items[i]; | |
if (ffStrEquals(item->key, PW_KEY_DEVICE_DESCRIPTION)) | |
{ | |
deviceName = item->value; | |
break; | |
} | |
} | |
printf("object: id:%u type:%s/%d name=%s\n", id, type, version, deviceName ? deviceName : "unknown"); | |
} | |
static const char* detectSoundWithPipeWire(FFlist* devices) | |
{ | |
pw_init(NULL, NULL); | |
struct pw_main_loop* mainloop = pw_main_loop_new(NULL); | |
if (!mainloop) return "Failed to create pipewire mainloop"; | |
struct pw_context* context = pw_context_new(pw_main_loop_get_loop(mainloop), NULL, 0); | |
struct pw_core* core = pw_context_connect(context, NULL, 0); | |
struct pw_registry* registry = pw_core_get_registry(core, PW_VERSION_REGISTRY, 0); | |
struct spa_hook registry_listener; | |
spa_zero(registry_listener); | |
pw_registry_add_listener(registry, ®istry_listener, &(struct pw_registry_events) { | |
.version = PW_VERSION_REGISTRY_EVENTS, | |
.global = registry_event_global, | |
}, NULL); | |
// pw_core_sync(core, PW_ID_CORE, 0); | |
roundtrip(core, mainloop); | |
pw_proxy_destroy((struct pw_proxy*) registry); | |
pw_core_disconnect(core); | |
pw_context_destroy(context); | |
pw_main_loop_quit(mainloop); | |
pw_deinit(); | |
return NULL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment