alsa: report extra latency for FireWire drivers

Based on testing, ALSA FireWire drivers introduce additional latency
determined by the buffer size.

Report that latency.

Pass device.bus to the node, so it can recognize firewire.
This commit is contained in:
Pauli Virtanen 2025-09-06 19:14:22 +03:00 committed by Wim Taymans
parent 916896c1cc
commit bf783ab08f
3 changed files with 14 additions and 2 deletions

View file

@ -160,7 +160,7 @@ static int emit_node(struct impl *this, struct acp_device *dev)
char codecs[512];
struct spa_device_object_info info;
struct acp_card *card = this->card;
const char *stream, *card_id;
const char *stream, *card_id, *bus;
info = SPA_DEVICE_OBJECT_INFO_INIT();
info.type = SPA_TYPE_INTERFACE_Node;
@ -175,7 +175,7 @@ static int emit_node(struct impl *this, struct acp_device *dev)
info.change_mask = SPA_DEVICE_OBJECT_CHANGE_MASK_PROPS;
items = alloca((dev->props.n_items + 11) * sizeof(*items));
items = alloca((dev->props.n_items + 12) * sizeof(*items));
n_items = 0;
snprintf(card_index, sizeof(card_index), "%d", card->index);
@ -193,6 +193,8 @@ static int emit_node(struct impl *this, struct acp_device *dev)
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_PCM_STREAM, stream);
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, stream);
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ICON_NAME, "audio-card-analog");
bus = acp_dict_lookup(&card->props, SPA_KEY_DEVICE_BUS);
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_BUS, bus);
snprintf(channels, sizeof(channels), "%d", dev->format.channels);
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_AUDIO_CHANNELS, channels);

View file

@ -1012,6 +1012,8 @@ int spa_alsa_init(struct state *state, const struct spa_dict *info)
state->num_bind_ctls = i;
/* We'll do the actual binding after checking the card exists */
} else if (spa_streq(k, SPA_KEY_DEVICE_BUS)) {
state->is_firewire = spa_streq(s, "firewire");
} else {
alsa_set_param(state, k, s);
}
@ -2054,6 +2056,13 @@ static void recalc_headroom(struct state *state)
if (rate != 0 && state->rate != 0)
latency = SPA_SCALE32_UP(latency, rate, state->rate);
if (state->is_firewire) {
/* XXX: For ALSA FireWire drivers, unlike for other ALSA drivers, buffer size
* XXX: contributes extra latency (as of kernel 6.16).
*/
latency += state->buffer_frames;
}
state->latency[state->port_direction].min_rate =
state->latency[state->port_direction].max_rate = latency;
}

View file

@ -154,6 +154,7 @@ struct state {
unsigned int disable_batch:1;
unsigned int disable_tsched:1;
unsigned int is_split_parent:1;
unsigned int is_firewire:1;
char clock_name[64];
uint32_t quantum_limit;