diff --git a/src/modules/mixer/app_mixer.c b/src/modules/mixer/app_mixer.c index 537468070..3ef1e2d8c 100644 --- a/src/modules/mixer/app_mixer.c +++ b/src/modules/mixer/app_mixer.c @@ -247,7 +247,7 @@ _populate_channels(E_Mixer_App_Dialog_Data *app) if (app->channel_infos) { E_Mixer_Channel_Info *info = app->channel_infos->data; - if (info->has_capture) + if (e_mod_mixer_channel_has_capture(info)) { e_widget_ilist_header_append(ilist, NULL, _("Input")); header_input = 1; @@ -265,7 +265,7 @@ _populate_channels(E_Mixer_App_Dialog_Data *app) { E_Mixer_Channel_Info *info = l->data; - if ((!header_input) && info->has_capture) + if ((!header_input) && e_mod_mixer_channel_has_capture(info)) { e_widget_ilist_header_append(ilist, NULL, _("Input")); header_input = 1; @@ -533,13 +533,13 @@ _find_channel_by_name(E_Mixer_App_Dialog_Data *app, const char *channel_name) { info = app->channel_infos->data; - header_input = !!info->has_capture; + header_input = !!e_mod_mixer_channel_has_capture(info); i = 1; } EINA_LIST_FOREACH(app->channel_infos, l, info) { - if ((!header_input) && info->has_capture) + if ((!header_input) && e_mod_mixer_channel_has_capture(info)) { header_input = 1; i++; diff --git a/src/modules/mixer/e_mod_mixer.c b/src/modules/mixer/e_mod_mixer.c index cb98bba72..b76d7165f 100644 --- a/src/modules/mixer/e_mod_mixer.c +++ b/src/modules/mixer/e_mod_mixer.c @@ -70,9 +70,9 @@ _channel_info_cmp(const void *data_a, const void *data_b) { const E_Mixer_Channel_Info *a = data_a, *b = data_b; - if (a->has_capture < b->has_capture) + if (e_mod_mixer_channel_has_capture(a) < e_mod_mixer_channel_has_capture(b)) return -1; - else if (a->has_capture > b->has_capture) + else if (e_mod_mixer_channel_has_capture(a) > e_mod_mixer_channel_has_capture(b)) return 1; return strcmp(a->name, b->name); diff --git a/src/modules/mixer/e_mod_mixer.h b/src/modules/mixer/e_mod_mixer.h index c0871059c..bf0ffdbaa 100644 --- a/src/modules/mixer/e_mod_mixer.h +++ b/src/modules/mixer/e_mod_mixer.h @@ -14,9 +14,35 @@ typedef struct _E_Mixer_Channel_State int right; } E_Mixer_Channel_State; +#define E_MIXER_CHANNEL_CAN_MUTE 0x01 +#define E_MIXER_CHANNEL_IS_MONO 0x02 +#define E_MIXER_CHANNEL_HAS_CAPTURE 0x04 +#define E_MIXER_CHANNEL_HAS_PLAYBACK 0x08 +#define E_MIXER_CHANNEL_GROUP_MASK 0xFC +#define E_MIXER_CHANNEL_USABLE_MASK 0xFD + +#define e_mod_mixer_channel_is_mutable(_ch) \ + ( ((_ch)->capabilities & E_MIXER_CHANNEL_CAN_MUTE )!=0 ) +#define e_mod_mixer_channel_is_mono(_ch) \ + ( ((_ch)->capabilities & E_MIXER_CHANNEL_IS_MONO )!=0 ) +#define e_mod_mixer_channel_has_capture(_ch) \ + ( ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_CAPTURE )!=0 ) +#define e_mod_mixer_channel_has_playback(_ch) \ + ( ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_PLAYBACK )!=0 ) +#define e_mod_mixer_channel_is_boost(_ch) \ + ( ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_PLAYBACK )!=0 && \ + ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_CAPTURE )!=0 ) +#define e_mod_mixer_channel_has_no_volume(_ch) \ + ( ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_PLAYBACK )==0 && \ + ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_CAPTURE )==0 ) +#define e_mod_mixer_channel_group_get(_ch) \ + ( (_ch)->capabilities & E_MIXER_CHANNEL_GROUP_MASK ) +#define e_mod_mixer_capabilities_usable(_capa) \ + ( ((_capa) & E_MIXER_CHANNEL_USABLE_MASK)!=0 ) + typedef struct _E_Mixer_Channel_Info { - int has_capture; + int capabilities; const char *name; E_Mixer_Channel *id; E_Mixer_App *app; diff --git a/src/modules/mixer/sys_alsa.c b/src/modules/mixer/sys_alsa.c index ca8c841c3..2e14d3611 100644 --- a/src/modules/mixer/sys_alsa.c +++ b/src/modules/mixer/sys_alsa.c @@ -294,11 +294,55 @@ e_mixer_system_get_card_name(const char *card) return eina_stringshare_add(name); } +static int +_mixer_channel_has_capabilities(snd_mixer_elem_t *elem) +{ + if (!snd_mixer_selem_is_active(elem)) return 0; + if (snd_mixer_selem_has_playback_volume(elem)) return 1; + if (snd_mixer_selem_has_capture_volume(elem)) return 1; + if (snd_mixer_selem_has_playback_switch(elem)) return 1; + if (snd_mixer_selem_has_capture_switch(elem)) return 1; + + return 0; +} + +static int +_mixer_channel_capabilities(snd_mixer_elem_t *elem) +{ + int capabilities = 0; + + /* + * never vol_joined if not mono + * -> mono is enough + * never switch_joined if not switch + * -> switch is enough + * never common_vol if not (playback_vol && capture vol) + * -> palyback_vol & capture_vol is enough + */ + if (!snd_mixer_selem_is_active(elem)) + return 0; + + if (snd_mixer_selem_has_capture_volume(elem)) + capabilities |= E_MIXER_CHANNEL_HAS_CAPTURE; + if (snd_mixer_selem_has_playback_volume(elem)) + capabilities |= E_MIXER_CHANNEL_HAS_PLAYBACK; + if (snd_mixer_selem_has_playback_switch(elem) || + snd_mixer_selem_has_capture_switch(elem)) + capabilities |= E_MIXER_CHANNEL_CAN_MUTE; + if (snd_mixer_selem_is_playback_mono(elem)==1 || + snd_mixer_selem_is_capture_mono(elem)==1) + capabilities |= E_MIXER_CHANNEL_IS_MONO; + + return capabilities; +} + Eina_List * e_mixer_system_get_channels(const E_Mixer_System *self) { + int capabilities; Eina_List *channels; snd_mixer_elem_t *elem; + E_Mixer_Channel_Info *ch_info; if (!self) return NULL; @@ -308,16 +352,14 @@ e_mixer_system_get_channels(const E_Mixer_System *self) elem = snd_mixer_first_elem((snd_mixer_t *)self); for (; elem; elem = snd_mixer_elem_next(elem)) { - if ((!snd_mixer_selem_is_active(elem)) || - (!snd_mixer_selem_has_playback_volume(elem))) + capabilities = _mixer_channel_capabilities(elem); + if (!e_mod_mixer_capabilities_usable(capabilities)) continue; - E_Mixer_Channel_Info *ch_info; - ch_info = malloc(sizeof(*ch_info)); ch_info->id = elem; ch_info->name = eina_stringshare_add(snd_mixer_selem_get_name(elem)); - ch_info->has_capture = snd_mixer_selem_has_capture_switch(elem) || snd_mixer_selem_has_capture_volume(elem); + ch_info->capabilities = capabilities; channels = eina_list_append(channels, ch_info); } @@ -342,8 +384,7 @@ e_mixer_system_get_channel_names(const E_Mixer_System *self) for (; elem; elem = snd_mixer_elem_next(elem)) { const char *name; - if ((!snd_mixer_selem_is_active(elem)) || - (!snd_mixer_selem_has_playback_volume(elem))) + if (!_mixer_channel_has_capabilities(elem)) continue; snd_mixer_selem_get_id(elem, sid); @@ -370,8 +411,7 @@ e_mixer_system_get_default_channel_name(const E_Mixer_System *self) for (; elem; elem = snd_mixer_elem_next(elem)) { const char *name; - if ((!snd_mixer_selem_is_active(elem)) || - (!snd_mixer_selem_has_playback_volume(elem))) + if (!_mixer_channel_has_capabilities(elem)) continue; snd_mixer_selem_get_id(elem, sid); @@ -387,6 +427,7 @@ E_Mixer_Channel_Info * e_mixer_system_get_channel_by_name(const E_Mixer_System *self, const char *name) { + int capabilities; snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; E_Mixer_Channel_Info *ch_info; @@ -400,8 +441,8 @@ e_mixer_system_get_channel_by_name(const E_Mixer_System *self, for (; elem; elem = snd_mixer_elem_next(elem)) { const char *n; - if ((!snd_mixer_selem_is_active(elem)) || - (!snd_mixer_selem_has_playback_volume(elem))) + capabilities = _mixer_channel_capabilities(elem); + if (!e_mod_mixer_capabilities_usable(capabilities)) continue; snd_mixer_selem_get_id(elem, sid); @@ -411,7 +452,7 @@ e_mixer_system_get_channel_by_name(const E_Mixer_System *self, ch_info = malloc(sizeof(*ch_info)); ch_info->id = elem; ch_info->name = eina_stringshare_add(n); - ch_info->has_capture = snd_mixer_selem_has_capture_switch(elem) || snd_mixer_selem_has_capture_volume(elem); + ch_info->capabilities = capabilities; return ch_info; } diff --git a/src/modules/mixer/sys_dummy.c b/src/modules/mixer/sys_dummy.c index 33069a621..9fbd46bdd 100644 --- a/src/modules/mixer/sys_dummy.c +++ b/src/modules/mixer/sys_dummy.c @@ -62,14 +62,14 @@ e_mixer_system_get_card_name(const char *card) Eina_List * e_mixer_system_get_channels(const E_Mixer_System *self __UNUSED__) { - _e_mixer_dummy_set(); - E_Mixer_Channel_Info *ch_info; + _e_mixer_dummy_set(); + ch_info = malloc(sizeof(*ch_info)); ch_info->id = (void*)-2; ch_info->name = eina_stringshare_ref(_name); - ch_info->has_capture = 0; + ch_info->capabilities = E_MIXER_CHANNEL_CAN_MUTE|E_MIXER_CHANNEL_HAS_PLAYBACK; return eina_list_append(NULL, ch_info); } @@ -102,7 +102,7 @@ e_mixer_system_get_channel_by_name(const E_Mixer_System *self __UNUSED__, const ch_info = malloc(sizeof(*ch_info)); ch_info->id = (void*)-2; ch_info->name = eina_stringshare_ref(_name); - ch_info->has_capture = 0; + ch_info->capabilities = E_MIXER_CHANNEL_CAN_MUTE|E_MIXER_CHANNEL_HAS_PLAYBACK; return ch_info; } diff --git a/src/modules/mixer/sys_pulse.c b/src/modules/mixer/sys_pulse.c index acdc2e8cc..a1ac56ebb 100644 --- a/src/modules/mixer/sys_pulse.c +++ b/src/modules/mixer/sys_pulse.c @@ -480,7 +480,7 @@ e_mixer_pulse_get_channels(const E_Mixer_System *self EINA_UNUSED) ch_info = malloc(sizeof(*ch_info)); ch_info->id = (void*)1; ch_info->name = eina_stringshare_ref(_name); - ch_info->has_capture = 0; + ch_info->capabilities= E_MIXER_CHANNEL_CAN_MUTE|E_MIXER_CHANNEL_HAS_PLAYBACK; return eina_list_append(NULL, ch_info); } @@ -506,7 +506,7 @@ e_mixer_pulse_get_channel_by_name(const E_Mixer_System *self EINA_UNUSED, ch_info = malloc(sizeof(*ch_info)); ch_info->id = (void*)1; ch_info->name = eina_stringshare_ref(_name); - ch_info->has_capture = 0; + ch_info->capabilities= E_MIXER_CHANNEL_CAN_MUTE|E_MIXER_CHANNEL_HAS_PLAYBACK; return ch_info; }