diff --git a/frontend/src/components/GraphCanvas.svelte b/frontend/src/components/GraphCanvas.svelte index 11feb1f..c5b089f 100644 --- a/frontend/src/components/GraphCanvas.svelte +++ b/frontend/src/components/GraphCanvas.svelte @@ -690,10 +690,12 @@ Class{nd.mode} / {nd.node_type} Volume{Math.round(nd.volume * 100)}% {nd.mute ? '(muted)' : ''} Ports{nd.port_ids.length} - {#if nd.sample_rate > 0}Sample Rate{nd.sample_rate} Hz{/if} - {#if nd.channels > 0}Channels{nd.channels}{/if} + {#if nd.node_type === 'audio' || nd.channels > 0} + Channels{nd.channels > 0 ? nd.channels : '-'} + Sample Rate{nd.sample_rate > 0 ? nd.sample_rate + ' Hz' : 'default'} + {#if nd.quantum > 0}Latency{nd.quantum} samples{#if nd.sample_rate > 0} ({(nd.quantum / nd.sample_rate * 1000).toFixed(1)} ms){/if}{/if} + {/if} {#if nd.format}Format{nd.format}{/if} - {#if nd.quantum > 0}Latency{nd.quantum} samples @ {nd.sample_rate} Hz{/if} {#if nd.rate > 0}Period Size{nd.rate}{/if} {#if nd.device_name}Device{nd.device_name}{/if} {#if nd.device_bus}Bus{nd.device_bus}{/if} diff --git a/src/graph_engine.cpp b/src/graph_engine.cpp index 03e6b94..b890dc9 100644 --- a/src/graph_engine.cpp +++ b/src/graph_engine.cpp @@ -102,10 +102,22 @@ static void on_node_info(void *data, const struct pw_node_info *info) { const char *str; str = spa_dict_lookup(info->props, "default.clock.rate"); - if (str) nobj->node.sample_rate = (uint32_t)atoi(str); + if (str && strlen(str) > 0) nobj->node.sample_rate = (uint32_t)atoi(str); str = spa_dict_lookup(info->props, "default.clock.quantum"); - if (str) nobj->node.quantum = (uint32_t)atoi(str); + if (str && strlen(str) > 0) nobj->node.quantum = (uint32_t)atoi(str); + + // Also try clock.rate (set on some devices) + if (nobj->node.sample_rate == 0) { + str = spa_dict_lookup(info->props, "clock.rate"); + if (str && strlen(str) > 0) nobj->node.sample_rate = (uint32_t)atoi(str); + } + + // Also try api.alsa.rate + if (nobj->node.sample_rate == 0) { + str = spa_dict_lookup(info->props, "api.alsa.rate"); + if (str && strlen(str) > 0) nobj->node.sample_rate = (uint32_t)atoi(str); + } str = spa_dict_lookup(info->props, "audio.channels"); if (str) nobj->node.channels = (uint32_t)atoi(str); @@ -125,26 +137,31 @@ static void on_node_info(void *data, const struct pw_node_info *info) { str = spa_dict_lookup(info->props, "priority.driver"); if (str) nobj->node.priority = atoi(str); - // Latency info + // Latency: "256/48000" format str = spa_dict_lookup(info->props, "node.latency"); if (str) { - // Format: "256/48000" -> quantum=256 rate=48000 uint32_t q = 0, r = 0; if (sscanf(str, "%u/%u", &q, &r) == 2) { - nobj->node.quantum = q; - nobj->node.sample_rate = r; + if (nobj->node.quantum == 0) nobj->node.quantum = q; + if (nobj->node.sample_rate == 0 && r > 0) nobj->node.sample_rate = r; } } - // Fallback: read clock rate from device props + // ALSA period size + str = spa_dict_lookup(info->props, "api.alsa.period-size"); + if (str) nobj->node.rate = (uint32_t)atoi(str); + + // Fallback: clock.rate if (nobj->node.sample_rate == 0) { str = spa_dict_lookup(info->props, "clock.rate"); if (str) nobj->node.sample_rate = (uint32_t)atoi(str); } - // ALSA latency - str = spa_dict_lookup(info->props, "api.alsa.period-size"); - if (str) nobj->node.rate = (uint32_t)atoi(str); // reuse rate field for period-size + // Fallback: api.alsa.rate + if (nobj->node.sample_rate == 0) { + str = spa_dict_lookup(info->props, "api.alsa.rate"); + if (str) nobj->node.sample_rate = (uint32_t)atoi(str); + } } }