diff --git a/spa/plugins/alsa/alsa-acp-device.c b/spa/plugins/alsa/alsa-acp-device.c index 4d8a6d92d..b2e06f67f 100644 --- a/spa/plugins/alsa/alsa-acp-device.c +++ b/spa/plugins/alsa/alsa-acp-device.c @@ -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); diff --git a/spa/plugins/alsa/alsa-pcm.c b/spa/plugins/alsa/alsa-pcm.c index 299f752b6..4daaa44c2 100644 --- a/spa/plugins/alsa/alsa-pcm.c +++ b/spa/plugins/alsa/alsa-pcm.c @@ -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; } diff --git a/spa/plugins/alsa/alsa-pcm.h b/spa/plugins/alsa/alsa-pcm.h index 0d23fa2f6..b440c2796 100644 --- a/spa/plugins/alsa/alsa-pcm.h +++ b/spa/plugins/alsa/alsa-pcm.h @@ -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;