diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-07-08 10:00:28 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-07-08 10:00:28 -0400 |
| commit | 2bf896106c8923e7fae38641a8ad80ddee2f5fe5 (patch) | |
| tree | e6a396061546b61039c06af8555218b192b7681e /src | |
| parent | 34863f5b702c0dbb00d8db5c00efd43d895fcd4c (diff) | |
pke: audio-pw: link consistently + cleanup
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio-impl-pw.cpp | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/src/audio-impl-pw.cpp b/src/audio-impl-pw.cpp index 628976e..53953ba 100644 --- a/src/audio-impl-pw.cpp +++ b/src/audio-impl-pw.cpp @@ -177,6 +177,10 @@ void pke_audio_pw_teardown() { pw_deinit(); pk_delete<char>(pke_audio_pw.default_sink_name, PKE_AUDIO_PW_NAME_RESERVE_LEN, pke_audio_pw.bkt); pk_delete<uint8_t>(pke_audio_pw.pod_buffer, pke_audio_mstr.channel_count * PKE_AUDIO_POD_BUFFER_LEN, pke_audio_pw.bkt); + pk_arr_reset(&pke_audio_pw.created_objects); + pke_audio_pw.created_objects.bkt = nullptr; + pk_arr_reset(&pke_audio_pw.pw_objects); + pke_audio_pw.pw_objects.bkt = nullptr; pk_mem_bucket_destroy(pke_audio_pw.bkt); pke_audio_pw.bkt = CAFE_BABE(pk_membucket); pke_audio_mstr.mtx_buffer.unlock(); @@ -188,6 +192,7 @@ void pke_audio_pw_remap_outputs() { uint32_t port_count = {0}; void *created_obj = {0}; if (pke_audio_pw.pw_objects.data == nullptr) return; + if (pke_audio_pw.default_sink_name == nullptr || pke_audio_pw.default_sink_name[0] == '\0') return; pw_properties *props = pw_properties_new(NULL, NULL); pke_audio_pw_object *objs = (pke_audio_pw_object *)pke_audio_pw.pw_objects.data; const char *str; @@ -244,6 +249,10 @@ void pke_audio_pw_remap_outputs() { // do links { for (i = 0; i < pke_audio_mstr.channel_count; ++i) { + if (out_ports[i] == 0) { + goto remap_done; + } + fprintf(stdout, "[pke_audio_pw_remap_outputs] Mapping (out:in): %d:%d\n", out_ports[i], in_ports[i]); pw_properties_clear(props); pw_properties_setf(props, PW_KEY_LINK_OUTPUT_PORT, "%d", out_ports[i]); pw_properties_setf(props, PW_KEY_LINK_INPUT_PORT, "%d", in_ports[i % port_count]); @@ -469,7 +478,7 @@ void on_pipewire_stream_param_changed(void *, uint32_t id, const struct spa_pod /* call a helper function to parse the format for us. */ spa_format_audio_raw_parse(param, &pke_audio_pw.format.info.raw); - fprintf(stdout, "\r\ncapturing rate changed:%d channels:%d\n", pke_audio_pw.format.info.raw.rate, pke_audio_pw.format.info.raw.channels); + fprintf(stdout, "capturing rate changed:%d channels:%d\n", pke_audio_pw.format.info.raw.rate, pke_audio_pw.format.info.raw.channels); return; } @@ -486,7 +495,7 @@ int metadata_event_property(void *data, uint32_t subject, const char *key, const } } } - fprintf(stdout, "\r\nPW_METADATA_CB: data: %p, subject: %d, key: '%s', type: '%s', value: '%s'\n", data, subject, key, type, value); + fprintf(stdout, "PW_METADATA_CB: data: %p, subject: %d, key: '%s', type: '%s', value: '%s'\n", data, subject, key, type, value); return 0; } @@ -499,12 +508,12 @@ void on_registry_event_global(void *data, uint32_t id, uint32_t permissions, con // if (props == NULL) return; // why if (props == NULL) { - printf("\r\nPW CALLBACK: NULL PROPS: object: id:%u type:%s/%d\n", id, type, version); + printf("PW CALLBACK: NULL PROPS: object: id:%u type:%s/%d\n", id, type, version); return; // why - in what scenario does this happen? } if (spa_streq(type, PW_TYPE_INTERFACE_Node)) { - printf("\r\nPW CALLBACK NODE: object: id:%u type:%s/%d\n", id, type, version); + printf("PW CALLBACK NODE: object: id:%u type:%s/%d\n", id, type, version); obj.type = PKE_AUDIO_PW_OBJECT_TYPE_NODE; } else if (spa_streq(type, PW_TYPE_INTERFACE_Port)) { obj.type = PKE_AUDIO_PW_OBJECT_TYPE_PORT; @@ -522,14 +531,14 @@ void on_registry_event_global(void *data, uint32_t id, uint32_t permissions, con return; } if (res = pk_stn(&obj.data.port.node, str, 0), res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "\r\nPW_CALLBACK: failed to parse port node from str: '%s', PK_STN_RES: %i\n", str, res); + fprintf(stderr, "PW_CALLBACK: failed to parse port node from str: '%s', PK_STN_RES: %i\n", str, res); return; } if ((str = spa_dict_lookup(props, PW_KEY_PORT_ID)) == NULL) { return; } if (res = pk_stn(&obj.data.port.id, str, 0), res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "\r\nPW_CALLBACK: failed to parse port id from str: '%s', PK_STN_RES: %i\n", str, res); + fprintf(stderr, "PW_CALLBACK: failed to parse port id from str: '%s', PK_STN_RES: %i\n", str, res); return; } } else if (spa_streq(type, PW_TYPE_INTERFACE_Link)) { @@ -538,14 +547,14 @@ void on_registry_event_global(void *data, uint32_t id, uint32_t permissions, con return; } if (res = pk_stn(&obj.data.link.output_port, str, 0), res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "\r\nPW_CALLBACK: failed to parse link output port from str: '%s', PK_STN_RES: %i\n", str, res); + fprintf(stderr, "PW_CALLBACK: failed to parse link output port from str: '%s', PK_STN_RES: %i\n", str, res); return; } if ((str = spa_dict_lookup(props, PW_KEY_LINK_INPUT_PORT)) == NULL) { return; } if (res = pk_stn(&obj.data.link.input_port, str, 0), res != PK_STN_RES_SUCCESS) { - fprintf(stderr, "\r\nPW_CALLBACK: failed to parse link input port from str: '%s', PK_STN_RES: %i\n", str, res); + fprintf(stderr, "PW_CALLBACK: failed to parse link input port from str: '%s', PK_STN_RES: %i\n", str, res); return; } } else if (spa_streq(type, PW_TYPE_INTERFACE_Metadata)) { @@ -568,33 +577,45 @@ void on_registry_event_global(void *data, uint32_t id, uint32_t permissions, con #if 0 int i; for (i = 0; i < props->n_items; ++i) { - printf("\r\n\t'%s': '%s'", props->items[i].key, props->items[i].value); + printf("\t'%s': '%s'", props->items[i].key, props->items[i].value); } - printf("\r\n"); + printf(""); #endif obj.id = id; obj.props = pw_properties_new_dict(props); - printf("\r\nPW CALLBACK: object: id:%u type:%s/%d\n", id, type, version); + printf("PW CALLBACK: object: id:%u type:%s/v%d\n", id, type, version); pk_arr_append_t(&pke_audio_pw.pw_objects, obj); + // TODO 2025-07-07 JCB + // I don't know if this logic is ever true. + // Specifically, on startup we don't have default_sink_id yet. + // So the only time this catches is if ports on our default node change during runtime? + // I feel like this was the right idea, but maybe the wrong place for it? + // The bug I was trying to fix at the time was a race condition where we were + // trying to link output ports that didn't exist yet. + // The correct answer was to validate the data before making the links. + /* + if (obj.type == PKE_AUDIO_PW_OBJECT_TYPE_PORT + && obj.data.port.node == pke_audio_pw.default_sink_id) { + pke_audio_pw.is_needing_output_remapped = true; + } + */ return; } void on_registry_event_global_removal(void *data, uint32_t id) { (void)data; uint32_t i; - // printf("\r\nPW CALLBACK: object remove: id:%u ...", id); + // printf("PW CALLBACK: object remove: id:%u ...", id); if (i = pk_arr_find_first_index(&pke_audio_pw.pw_objects, &id, pw_objects_find_pw_object_by_id), i != 0xFFFFFFFF) { - if (pke_audio_pw.pw_objects[i].type != PKE_AUDIO_PW_OBJECT_TYPE_LINK) { - pke_audio_pw.is_needing_output_remapped = true; - } if (pke_audio_pw.pw_objects[i].id == pke_audio_pw.default_sink_id) { // we just lost our target audio device pke_audio_pw.default_sink_id = 0; pke_audio_pw.default_sink_name[0] = '\0'; + pke_audio_pw.is_needing_output_remapped = true; } pk_arr_remove_at(&pke_audio_pw.pw_objects, i); // printf(" removed.\n"); |
