mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-10-14 20:02:38 +00:00
alsa-pcm-device: notify observers when profile changes
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
This commit is contained in:
parent
7206980023
commit
d6184bd9bb
|
@ -48,6 +48,13 @@ struct impl {
|
||||||
|
|
||||||
struct spa_log *log;
|
struct spa_log *log;
|
||||||
|
|
||||||
|
uint32_t info_all;
|
||||||
|
struct spa_device_info device_info;
|
||||||
|
|
||||||
|
#define IDX_EnumProfile 0
|
||||||
|
#define IDX_Profile 1
|
||||||
|
struct spa_param_info params[2];
|
||||||
|
|
||||||
struct spa_hook_list hooks;
|
struct spa_hook_list hooks;
|
||||||
|
|
||||||
struct props props;
|
struct props props;
|
||||||
|
@ -229,6 +236,9 @@ static int set_profile(struct impl *this, uint32_t id)
|
||||||
spa_log_debug(this->log, "done enumerating PCM nodes for card %s", this->props.device);
|
spa_log_debug(this->log, "done enumerating PCM nodes for card %s", this->props.device);
|
||||||
snd_ctl_close(ctl_hndl);
|
snd_ctl_close(ctl_hndl);
|
||||||
|
|
||||||
|
this->device_info.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS;
|
||||||
|
this->params[IDX_Profile].user++;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,51 +249,54 @@ static int emit_info(struct impl *this, bool full)
|
||||||
uint32_t n_items = 0;
|
uint32_t n_items = 0;
|
||||||
snd_ctl_t *ctl_hndl;
|
snd_ctl_t *ctl_hndl;
|
||||||
snd_ctl_card_info_t *info;
|
snd_ctl_card_info_t *info;
|
||||||
struct spa_device_info dinfo;
|
|
||||||
struct spa_param_info params[2];
|
|
||||||
char path[128];
|
char path[128];
|
||||||
|
|
||||||
spa_log_debug(this->log, "open card %s", this->props.device);
|
if (full)
|
||||||
if ((err = snd_ctl_open(&ctl_hndl, this->props.device, 0)) < 0) {
|
this->device_info.change_mask = this->info_all;
|
||||||
spa_log_error(this->log, "can't open control for card %s: %s",
|
|
||||||
this->props.device, snd_strerror(err));
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
snd_ctl_card_info_alloca(&info);
|
if (this->device_info.change_mask) {
|
||||||
if ((err = snd_ctl_card_info(ctl_hndl, info)) < 0) {
|
spa_log_debug(this->log, "open card %s", this->props.device);
|
||||||
spa_log_error(this->log, "error hardware info: %s", snd_strerror(err));
|
if ((err = snd_ctl_open(&ctl_hndl, this->props.device, 0)) < 0) {
|
||||||
goto exit;
|
spa_log_error(this->log, "can't open control for card %s: %s",
|
||||||
}
|
this->props.device, snd_strerror(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
dinfo = SPA_DEVICE_INFO_INIT();
|
snd_ctl_card_info_alloca(&info);
|
||||||
|
if ((err = snd_ctl_card_info(ctl_hndl, info)) < 0) {
|
||||||
dinfo.change_mask = SPA_DEVICE_CHANGE_MASK_PROPS;
|
spa_log_error(this->log, "error hardware info: %s", snd_strerror(err));
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
#define ADD_ITEM(key, value) items[n_items++] = SPA_DICT_ITEM_INIT(key, value)
|
#define ADD_ITEM(key, value) items[n_items++] = SPA_DICT_ITEM_INIT(key, value)
|
||||||
snprintf(path, sizeof(path), "alsa:pcm:%s", snd_ctl_card_info_get_id(info));
|
snprintf(path, sizeof(path), "alsa:pcm:%s", snd_ctl_card_info_get_id(info));
|
||||||
ADD_ITEM(SPA_KEY_OBJECT_PATH, path);
|
ADD_ITEM(SPA_KEY_OBJECT_PATH, path);
|
||||||
ADD_ITEM(SPA_KEY_DEVICE_API, "alsa:pcm");
|
ADD_ITEM(SPA_KEY_DEVICE_API, "alsa:pcm");
|
||||||
ADD_ITEM(SPA_KEY_MEDIA_CLASS, "Audio/Device");
|
ADD_ITEM(SPA_KEY_MEDIA_CLASS, "Audio/Device");
|
||||||
ADD_ITEM(SPA_KEY_API_ALSA_PATH, (char *)this->props.device);
|
ADD_ITEM(SPA_KEY_API_ALSA_PATH, (char *)this->props.device);
|
||||||
ADD_ITEM(SPA_KEY_API_ALSA_CARD_ID, snd_ctl_card_info_get_id(info));
|
ADD_ITEM(SPA_KEY_API_ALSA_CARD_ID, snd_ctl_card_info_get_id(info));
|
||||||
ADD_ITEM(SPA_KEY_API_ALSA_CARD_COMPONENTS, snd_ctl_card_info_get_components(info));
|
ADD_ITEM(SPA_KEY_API_ALSA_CARD_COMPONENTS, snd_ctl_card_info_get_components(info));
|
||||||
ADD_ITEM(SPA_KEY_API_ALSA_CARD_DRIVER, snd_ctl_card_info_get_driver(info));
|
ADD_ITEM(SPA_KEY_API_ALSA_CARD_DRIVER, snd_ctl_card_info_get_driver(info));
|
||||||
ADD_ITEM(SPA_KEY_API_ALSA_CARD_NAME, snd_ctl_card_info_get_name(info));
|
ADD_ITEM(SPA_KEY_API_ALSA_CARD_NAME, snd_ctl_card_info_get_name(info));
|
||||||
ADD_ITEM(SPA_KEY_API_ALSA_CARD_LONGNAME, snd_ctl_card_info_get_longname(info));
|
ADD_ITEM(SPA_KEY_API_ALSA_CARD_LONGNAME, snd_ctl_card_info_get_longname(info));
|
||||||
ADD_ITEM(SPA_KEY_API_ALSA_CARD_MIXERNAME, snd_ctl_card_info_get_mixername(info));
|
ADD_ITEM(SPA_KEY_API_ALSA_CARD_MIXERNAME, snd_ctl_card_info_get_mixername(info));
|
||||||
dinfo.props = &SPA_DICT_INIT(items, n_items);
|
this->device_info.props = &SPA_DICT_INIT(items, n_items);
|
||||||
#undef ADD_ITEM
|
#undef ADD_ITEM
|
||||||
|
|
||||||
dinfo.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS;
|
if (this->device_info.change_mask & SPA_DEVICE_CHANGE_MASK_PARAMS) {
|
||||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumProfile, SPA_PARAM_INFO_READ);
|
SPA_FOR_EACH_ELEMENT_VAR(this->params, p) {
|
||||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Profile, SPA_PARAM_INFO_READWRITE);
|
if (p->user > 0) {
|
||||||
dinfo.n_params = SPA_N_ELEMENTS(params);
|
p->flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
dinfo.params = params;
|
p->user = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
spa_device_emit_info(&this->hooks, &dinfo);
|
spa_device_emit_info(&this->hooks, &this->device_info);
|
||||||
|
this->device_info.change_mask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
spa_log_debug(this->log, "close card %s", this->props.device);
|
spa_log_debug(this->log, "close card %s", this->props.device);
|
||||||
snd_ctl_close(ctl_hndl);
|
snd_ctl_close(ctl_hndl);
|
||||||
return err;
|
return err;
|
||||||
|
@ -471,7 +484,9 @@ static int impl_set_param(void *object,
|
||||||
spa_log_warn(this->log, "unknown profile %s", name);
|
spa_log_warn(this->log, "unknown profile %s", name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_profile(this, idx);
|
set_profile(this, idx);
|
||||||
|
emit_info(this, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -551,6 +566,15 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
if (info && (str = spa_dict_lookup(info, SPA_KEY_API_ALSA_PATH)))
|
if (info && (str = spa_dict_lookup(info, SPA_KEY_API_ALSA_PATH)))
|
||||||
snprintf(this->props.device, 64, "%s", str);
|
snprintf(this->props.device, 64, "%s", str);
|
||||||
|
|
||||||
|
this->device_info = SPA_DEVICE_INFO_INIT();
|
||||||
|
this->info_all = SPA_DEVICE_CHANGE_MASK_PROPS |
|
||||||
|
SPA_DEVICE_CHANGE_MASK_PARAMS;
|
||||||
|
|
||||||
|
this->params[IDX_EnumProfile] = SPA_PARAM_INFO(SPA_PARAM_EnumProfile, SPA_PARAM_INFO_READ);
|
||||||
|
this->params[IDX_Profile] = SPA_PARAM_INFO(SPA_PARAM_Profile, SPA_PARAM_INFO_READWRITE);
|
||||||
|
this->device_info.params = this->params;
|
||||||
|
this->device_info.n_params = SPA_N_ELEMENTS(this->params);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue