mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
acp: add option to switch profile and ports
Enable an option to switch to the next best profile and port when the current one becomes unavailable.
This commit is contained in:
parent
368366b88d
commit
5e368b1ad6
3 changed files with 561 additions and 522 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -42,6 +42,8 @@ extern "C" {
|
|||
#define ACP_PRINTF_FUNC(fmt, arg1)
|
||||
#endif
|
||||
|
||||
#define ACP_INVALID_INDEX ((uint32_t)-1)
|
||||
|
||||
struct acp_dict_item {
|
||||
const char *key;
|
||||
const char *value;
|
||||
|
|
@ -201,8 +203,9 @@ struct acp_device {
|
|||
float base_volume;
|
||||
float volume_step;
|
||||
|
||||
struct acp_port **ports;
|
||||
uint32_t n_ports;
|
||||
uint32_t active_port_index;
|
||||
struct acp_port **ports;
|
||||
};
|
||||
|
||||
struct acp_card_profile {
|
||||
|
|
@ -227,8 +230,8 @@ struct acp_card {
|
|||
struct acp_dict props;
|
||||
|
||||
uint32_t n_profiles;
|
||||
struct acp_card_profile **profiles;
|
||||
uint32_t active_profile_index;
|
||||
struct acp_card_profile **profiles;
|
||||
|
||||
uint32_t n_devices;
|
||||
struct acp_device **devices;
|
||||
|
|
@ -252,8 +255,10 @@ int acp_card_poll_descriptors_revents(struct acp_card *card, struct pollfd *pfds
|
|||
unsigned int nfds, unsigned short *revents);
|
||||
int acp_card_handle_events(struct acp_card *card);
|
||||
|
||||
uint32_t acp_card_find_best_profile_index(struct acp_card *card, const char *name);
|
||||
int acp_card_set_profile(struct acp_card *card, uint32_t profile_index);
|
||||
|
||||
uint32_t acp_device_find_best_port_index(struct acp_device *dev, const char *name);
|
||||
int acp_device_set_port(struct acp_device *dev, uint32_t port_index);
|
||||
|
||||
int acp_device_set_volume(struct acp_device *dev, const float *volume, uint32_t n_volume);
|
||||
|
|
|
|||
|
|
@ -52,15 +52,21 @@
|
|||
|
||||
#define MAX_POLL 16
|
||||
|
||||
static const char default_device[] = "hw:0";
|
||||
#define DEFAULT_DEVICE "hw:0"
|
||||
#define DEFAULT_AUTO_PROFILE true
|
||||
#define DEFAULT_AUTO_PORT true
|
||||
|
||||
struct props {
|
||||
char device[64];
|
||||
bool auto_profile;
|
||||
bool auto_port;
|
||||
};
|
||||
|
||||
static void reset_props(struct props *props)
|
||||
{
|
||||
strncpy(props->device, default_device, 64);
|
||||
strncpy(props->device, DEFAULT_DEVICE, 64);
|
||||
props->auto_profile = DEFAULT_AUTO_PROFILE;
|
||||
props->auto_port = DEFAULT_AUTO_PORT;
|
||||
}
|
||||
|
||||
struct impl {
|
||||
|
|
@ -651,7 +657,7 @@ static void card_profile_changed(void *data, uint32_t old_index, uint32_t new_in
|
|||
}
|
||||
|
||||
static void card_profile_available(void *data, uint32_t index,
|
||||
enum acp_available old, enum acp_available available)
|
||||
enum acp_available old, enum acp_available available)
|
||||
{
|
||||
struct impl *this = data;
|
||||
struct acp_card *card = this->card;
|
||||
|
|
@ -661,6 +667,11 @@ static void card_profile_available(void *data, uint32_t index,
|
|||
this->info.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS;
|
||||
this->params[IDX_EnumProfile].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||
emit_info(this, false);
|
||||
|
||||
if (this->props.auto_profile && available == ACP_AVAILABLE_NO) {
|
||||
index = acp_card_find_best_profile_index(card, NULL);
|
||||
acp_card_set_profile(card, index);
|
||||
}
|
||||
}
|
||||
|
||||
static void card_port_changed(void *data, uint32_t old_index, uint32_t new_index)
|
||||
|
|
@ -679,7 +690,7 @@ static void card_port_changed(void *data, uint32_t old_index, uint32_t new_index
|
|||
}
|
||||
|
||||
static void card_port_available(void *data, uint32_t index,
|
||||
enum acp_available old, enum acp_available available)
|
||||
enum acp_available old, enum acp_available available)
|
||||
{
|
||||
struct impl *this = data;
|
||||
struct acp_card *card = this->card;
|
||||
|
|
@ -689,6 +700,19 @@ static void card_port_available(void *data, uint32_t index,
|
|||
this->info.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS;
|
||||
this->params[IDX_EnumRoute].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||
emit_info(this, false);
|
||||
|
||||
if (this->props.auto_port && available == ACP_AVAILABLE_NO) {
|
||||
uint32_t i, index;
|
||||
|
||||
for (i = 0; i < p->n_devices; i++) {
|
||||
struct acp_device *d = p->devices[i];
|
||||
if (!(d->flags & ACP_DEVICE_ACTIVE))
|
||||
continue;
|
||||
|
||||
index = acp_device_find_best_port_index(d, NULL);
|
||||
acp_device_set_port(d, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void on_volume_changed(void *data, struct acp_device *dev)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue