emixer: Add volume channels control on emixer

Summary:
This commit allow the user to control each volumes channels in emixer.
A lock flag is introduced to manage volume as before.

@feature

Reviewers: zmike!, devilhorns, raster

Subscribers: cedric

Tags: #enlightenment-git

Differential Revision: https://phab.enlightenment.org/D7639
This commit is contained in:
Michael Bouchaud (yoz) 2019-05-21 14:40:43 +01:00 committed by Carsten Haitzler (Rasterman)
parent 5cded14b76
commit 5aedf54042
7 changed files with 702 additions and 145 deletions

View File

@ -347,7 +347,7 @@ emix_config_save_state_restore(void)
v.channel_count = emsink->volume.channel_count;
for (i = 0; i < v.channel_count; i++)
v.volumes[i] = sink->volume;
emix_sink_volume_set(emsink, v);
emix_sink_volume_set(emsink, &v);
free(v.volumes);
}
emix_sink_mute_set(emsink, sink->mute);
@ -373,7 +373,7 @@ emix_config_save_state_restore(void)
v.channel_count = emsource->volume.channel_count;
for (i = 0; i < v.channel_count; i++)
v.volumes[i] = source->volume;
emix_source_volume_set(emsource, v);
emix_source_volume_set(emsource, &v);
free(v.volumes);
}
emix_source_mute_set(emsource, source->mute);

View File

@ -9,6 +9,8 @@ Eina_List *source_list = NULL, *sink_input_list = NULL, *sink_list = NULL, *card
//////////////////////////////////////////////////////////////////////////////
static void _emix_sink_volume_fill(Emix_Sink *sink, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked);
static Eina_Bool
_backend_init(const char *back)
{
@ -48,6 +50,20 @@ _cb_sink_volume_change(void *data,
elm_slider_value_set(obj, vol);
}
static void
_cb_sink_volume_channel_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *bxv = data;
Emix_Sink *sink = evas_object_data_get(bxv, "sink");
double vol = elm_slider_value_get(obj);
sink->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")] = vol;
elm_slider_value_set(obj, vol);
emix_sink_volume_set(sink, &sink->volume);
}
static void
_cb_sink_mute_change(void *data,
Evas_Object *obj,
@ -55,18 +71,147 @@ _cb_sink_mute_change(void *data,
{
Evas_Object *bxv = data;
Emix_Sink *sink = evas_object_data_get(bxv, "sink");
Evas_Object *sl = evas_object_data_get(bxv, "volume");
Evas_Object *lock = evas_object_data_get(bxv, "lock");
Eina_Bool mute = elm_check_state_get(obj);
elm_object_disabled_set(sl, mute);
Eina_List *l;
Evas_Object *o;
if (lock && !elm_check_state_get(lock))
{
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), l, o)
{
elm_object_disabled_set(o, mute);
o = evas_object_data_get(o, "lb");
elm_object_disabled_set(o, mute);
}
}
else
{
o = evas_object_data_get(bxv, "volume");
elm_object_disabled_set(o, mute);
}
emix_sink_mute_set(sink, mute);
}
static void
_cb_sink_lock_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *bxv = data;
Emix_Sink *sink = evas_object_data_get(bxv, "sink");
Evas_Object *bx = evas_object_data_get(bxv, "volume_bx");
Eina_Bool lock = elm_check_state_get(obj);
if (lock)
VOLSET(sink->volume.volumes[0], sink->volume,
sink, emix_sink_volume_set);
_emix_sink_volume_fill(sink, bxv, bx, lock);
}
static void
_emix_sink_volume_fill(Emix_Sink *sink, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked)
{
Evas_Object *bxhv, *sl, *ck, *lb;
Eina_List *sls = NULL;
unsigned int i;
eina_list_free(evas_object_data_get(bxv, "volumes"));
elm_box_clear(bx);
bxhv = elm_box_add(bx);
evas_object_size_hint_weight_set(bxhv, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bxhv, EVAS_HINT_FILL, 0.5);
elm_box_pack_end(bx, bxhv);
evas_object_show(bxhv);
if (locked)
{
sl = elm_slider_add(bx);
evas_object_data_set(bxv, "volume", sl);
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
elm_slider_span_size_set(sl, emix_max_volume_get() * elm_config_scale_get());
elm_slider_unit_format_set(sl, "%1.0f");
elm_slider_indicator_format_set(sl, "%1.0f");
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_slider_value_set(sl, sink->volume.volumes[0]);
elm_box_pack_end(bxhv, sl);
evas_object_show(sl);
evas_object_smart_callback_add(sl, "changed", _cb_sink_volume_change, bxv);
elm_object_disabled_set(sl, sink->mute);
}
else
{
for (i = 0; i < sink->volume.channel_count; ++i)
{
lb = elm_label_add(bx);
if (!sink->volume.channel_names)
{
char buf[1024];
snprintf(buf, sizeof(buf), "Channel %d", i);
elm_object_text_set(lb, buf);
}
else
elm_object_text_set(lb, sink->volume.channel_names[i]);
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
evas_object_size_hint_align_set(lb, 0.0, 0.5);
elm_box_pack_end(bxhv, lb);
elm_object_disabled_set(lb, sink->mute);
evas_object_show(lb);
sl = elm_slider_add(bx);
evas_object_data_set(sl, "lb", lb);
evas_object_data_set(sl, "channel", (uintptr_t *)(uintptr_t)i);
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
elm_slider_unit_format_set(sl, "%1.0f");
elm_slider_indicator_format_set(sl, "%1.0f");
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_slider_value_set(sl, sink->volume.volumes[i]);
elm_box_pack_end(bxhv, sl);
evas_object_show(sl);
evas_object_smart_callback_add(sl, "changed", _cb_sink_volume_channel_change, bxv);
elm_object_disabled_set(sl, sink->mute);
sls = eina_list_append(sls, sl);
}
}
evas_object_data_set(bxv, "volumes", sls);
bxhv = elm_box_add(bx);
elm_box_pack_end(bx, bxhv);
evas_object_show(bxhv);
ck = elm_check_add(bx);
evas_object_data_set(bxv, "mute", ck);
elm_object_text_set(ck, "Mute");
elm_check_state_set(ck, sink->mute);
elm_box_pack_end(bxhv, ck);
evas_object_show(ck);
evas_object_smart_callback_add(ck, "changed", _cb_sink_mute_change, bxv);
if (sink->volume.channel_count > 1)
{
ck = elm_check_add(bx);
elm_object_text_set(ck, "Lock");
evas_object_data_set(bxv, "lock", ck);
elm_check_state_set(ck, locked);
elm_box_pack_end(bxhv, ck);
evas_object_show(ck);
evas_object_smart_callback_add(ck, "changed", _cb_sink_lock_change, bxv);
}
}
static void
_emix_sink_add(Emix_Sink *sink)
{
Evas_Object *bxv, *bx, *lb, *ck, *sl, *hv, *sep;
Evas_Object *bxv, *bx, *lb, *hv, *sep;
const Eina_List *l;
Emix_Port *port;
Eina_Bool locked = EINA_TRUE;
unsigned int i;
bxv = elm_box_add(win);
sink_list = eina_list_append(sink_list, bxv);
@ -104,34 +249,27 @@ _emix_sink_add(Emix_Sink *sink)
elm_box_pack_end(bx, hv);
evas_object_show(hv);
bx = elm_box_add(win);
/* Compare each volume level and check if they differ. If they differ unlock
the volume control and let user set each channel volume level */
for (i = 1; i < sink->volume.channel_count; ++i)
{
if (sink->volume.volumes[i - 1] != sink->volume.volumes[i])
{
locked = EINA_FALSE;
break;
}
}
bx = elm_box_add(bxv);
evas_object_data_set(bxv, "volume_bx", bx);
elm_box_horizontal_set(bx, EINA_TRUE);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.5);
elm_box_pack_end(bxv, bx);
evas_object_show(bx);
sl = elm_slider_add(win);
evas_object_data_set(bxv, "volume", sl);
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
elm_slider_span_size_set(sl, emix_max_volume_get() * elm_config_scale_get());
elm_slider_unit_format_set(sl, "%1.0f");
elm_slider_indicator_format_set(sl, "%1.0f");
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.5);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
elm_slider_value_set(sl, sink->volume.volumes[0]);
elm_box_pack_end(bx, sl);
evas_object_show(sl);
evas_object_smart_callback_add(sl, "changed", _cb_sink_volume_change, bxv);
ck = elm_check_add(win);
evas_object_data_set(bxv, "mute", ck);
elm_object_text_set(ck, "Mute");
elm_check_state_set(ck, sink->mute);
elm_object_disabled_set(sl, sink->mute);
elm_box_pack_end(bx, ck);
evas_object_show(ck);
evas_object_smart_callback_add(ck, "changed", _cb_sink_mute_change, bxv);
_emix_sink_volume_fill(sink, bxv, bx, locked);
sep = elm_separator_add(win);
elm_separator_horizontal_set(sep, EINA_TRUE);
@ -164,7 +302,8 @@ static void
_emix_sink_change(Emix_Sink *sink)
{
const Eina_List *l;
Evas_Object *bxv, *hv, *ck, *sl;
Eina_List *ll;
Evas_Object *bxv, *hv, *ck, *sl, *lb;
Emix_Port *port;
EINA_LIST_FOREACH(sink_list, l, bxv)
@ -181,15 +320,35 @@ _emix_sink_change(Emix_Sink *sink)
_cb_sink_port_change, port);
if (port->active) elm_object_text_set(hv, port->description);
}
sl = evas_object_data_get(bxv, "volume");
elm_slider_value_set(sl, sink->volume.volumes[0]);
ck = evas_object_data_get(bxv, "lock");
if (ck && !elm_check_state_get(ck))
{
ck = evas_object_data_get(bxv, "mute");
elm_check_state_set(ck, sink->mute);
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), ll, sl)
{
elm_slider_value_set(sl,
sink->volume.volumes[(uintptr_t)evas_object_data_get(sl, "channel")]);
elm_object_disabled_set(sl, sink->mute);
lb = evas_object_data_get(sl, "lb");
elm_object_disabled_set(lb, sink->mute);
}
}
else
{
ck = evas_object_data_get(bxv, "mute");
elm_check_state_set(ck, sink->mute);
sl = evas_object_data_get(bxv, "volume");
elm_slider_value_set(sl, sink->volume.volumes[0]);
elm_object_disabled_set(sl, sink->mute);
}
ck = evas_object_data_get(bxv, "mute");
elm_check_state_set(ck, sink->mute);
elm_object_disabled_set(sl, sink->mute);
}
//////////////////////////////////////////////////////////////////////////////
static void _emix_sink_input_volume_fill(Emix_Sink_Input *input, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked);
static void
_cb_sink_input_port_change(void *data,
@ -215,6 +374,19 @@ _cb_sink_input_volume_change(void *data,
elm_slider_value_set(obj, vol);
}
static void
_cb_sink_input_volume_channel_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *bxv = data;
Emix_Sink_Input *input = evas_object_data_get(bxv, "input");
double vol = elm_slider_value_get(obj);
input->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")] = vol;
elm_slider_value_set(obj, vol);
emix_sink_input_volume_set(input, &input->volume);
}
static void
_cb_sink_input_volume_drag_stop(void *data,
Evas_Object *obj,
@ -226,6 +398,17 @@ _cb_sink_input_volume_drag_stop(void *data,
elm_slider_value_set(obj, vol);
}
static void
_cb_sink_input_volume_channel_drag_stop(void *data,
Evas_Object *obj,
void *event EINA_UNUSED)
{
Evas_Object *bxv = data;
Emix_Sink_Input *input = evas_object_data_get(bxv, "input");
int vol = input->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")];
elm_slider_value_set(obj, vol);
}
static void
_cb_sink_input_mute_change(void *data,
Evas_Object *obj,
@ -233,18 +416,156 @@ _cb_sink_input_mute_change(void *data,
{
Evas_Object *bxv = data;
Emix_Sink_Input *input = evas_object_data_get(bxv, "input");
Evas_Object *sl = evas_object_data_get(bxv, "volume");
Evas_Object *sl;
Evas_Object *lock = evas_object_data_get(bxv, "lock");
Eina_Bool mute = elm_check_state_get(obj);
elm_object_disabled_set(sl, mute);
Evas_Object *lb;
Eina_List *l;
if (lock && !elm_check_state_get(lock))
{
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), l, sl)
{
elm_object_disabled_set(sl, mute);
lb = evas_object_data_get(sl, "lb");
elm_object_disabled_set(lb, mute);
}
}
else
{
sl = evas_object_data_get(bxv, "volume");
elm_object_disabled_set(sl, mute);
}
emix_sink_input_mute_set(input, mute);
}
static void
_cb_sink_input_lock_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *bxv = data;
Emix_Sink_Input *input = evas_object_data_get(bxv, "input");
Evas_Object *bx = evas_object_data_get(bxv, "volume_bx");
Eina_Bool lock = elm_check_state_get(obj);
if (lock)
VOLSET(input->volume.volumes[0], input->volume,
input, emix_sink_input_volume_set);
_emix_sink_input_volume_fill(input, bxv, bx, lock);
}
static void
_emix_sink_input_volume_fill(Emix_Sink_Input *input, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked)
{
Evas_Object *bxhv, *lb, *sl, *ck;
unsigned int i;
Eina_List *sls = NULL;
eina_list_free(evas_object_data_get(bxv, "volumes"));
elm_box_clear(bx);
bxhv = elm_box_add(bx);
evas_object_size_hint_weight_set(bxhv, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bxhv, EVAS_HINT_FILL, 0.5);
elm_box_pack_end(bx, bxhv);
evas_object_show(bxhv);
if (locked)
{
sl = elm_slider_add(bx);
evas_object_data_set(bxv, "volume", sl);
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
elm_slider_unit_format_set(sl, "%1.0f");
elm_slider_indicator_format_set(sl, "%1.0f");
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
elm_slider_value_set(sl, input->volume.volumes[0]);
elm_box_pack_end(bxhv, sl);
evas_object_show(sl);
evas_object_smart_callback_add(sl, "changed",
_cb_sink_input_volume_change, bxv);
evas_object_smart_callback_add(sl, "slider,drag,stop",
_cb_sink_input_volume_drag_stop, bxv);
}
else
{
for (i = 0; i < input->volume.channel_count; ++i)
{
lb = elm_label_add(bx);
if (!input->volume.channel_names)
{
char buf[1024];
snprintf(buf, sizeof(buf), "Channel %d", i);
elm_object_text_set(lb, buf);
}
else
elm_object_text_set(lb, input->volume.channel_names[i]);
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
evas_object_size_hint_align_set(lb, 0.0, 0.5);
elm_box_pack_end(bxhv, lb);
elm_object_disabled_set(lb, input->mute);
evas_object_show(lb);
sl = elm_slider_add(bx);
evas_object_data_set(sl, "lb", lb);
evas_object_data_set(sl, "channel", (uintptr_t *)(uintptr_t)i);
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
elm_slider_unit_format_set(sl, "%1.0f");
elm_slider_indicator_format_set(sl, "%1.0f");
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_slider_value_set(sl, input->volume.volumes[i]);
elm_box_pack_end(bxhv, sl);
evas_object_show(sl);
evas_object_smart_callback_add(sl, "changed",
_cb_sink_input_volume_channel_change, bxv);
evas_object_smart_callback_add(sl, "slider,drag,stop",
_cb_sink_input_volume_channel_drag_stop, bxv);
elm_object_disabled_set(sl, input->mute);
sls = eina_list_append(sls, sl);
}
}
evas_object_data_set(bxv, "volumes", sls);
bxhv = elm_box_add(bx);
elm_box_pack_end(bx, bxhv);
evas_object_show(bxhv);
ck = elm_check_add(bx);
evas_object_data_set(bxv, "mute", ck);
elm_object_text_set(ck, "Mute");
elm_check_state_set(ck, input->mute);
elm_object_disabled_set(sl, input->mute);
elm_box_pack_end(bxhv, ck);
evas_object_show(ck);
evas_object_smart_callback_add(ck, "changed",
_cb_sink_input_mute_change, bxv);
if (input->volume.channel_count > 1)
{
ck = elm_check_add(bx);
evas_object_data_set(bxv, "lock", ck);
elm_object_text_set(ck, "Lock");
elm_check_state_set(ck, locked);
elm_box_pack_end(bxhv, ck);
evas_object_show(ck);
evas_object_smart_callback_add(ck, "changed",
_cb_sink_input_lock_change, bxv);
}
}
static void
_emix_sink_input_add(Emix_Sink_Input *input)
{
Evas_Object *bxv, *bx, *lb, *ck, *sl, *hv, *sep;
Evas_Object *bxv, *bx, *lb, *hv, *sep;
const Eina_List *l;
Emix_Sink *sink;
Eina_Bool locked = EINA_TRUE;
unsigned int i;
bxv = elm_box_add(win);
sink_input_list = eina_list_append(sink_input_list, bxv);
@ -255,13 +576,13 @@ _emix_sink_input_add(Emix_Sink_Input *input)
bx = elm_box_add(win);
elm_box_horizontal_set(bx, EINA_TRUE);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.5);
elm_box_pack_end(bxv, bx);
evas_object_show(bx);
lb = elm_label_add(win);
elm_object_text_set(lb, input->name);
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(lb, 0.0, 0.5);
elm_box_pack_end(bx, lb);
evas_object_show(lb);
@ -283,37 +604,25 @@ _emix_sink_input_add(Emix_Sink_Input *input)
evas_object_show(hv);
bx = elm_box_add(win);
evas_object_data_set(bxv, "volume_bx", bx);
elm_box_horizontal_set(bx, EINA_TRUE);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.5);
elm_box_pack_end(bxv, bx);
evas_object_show(bx);
sl = elm_slider_add(win);
evas_object_data_set(bxv, "volume", sl);
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
elm_slider_unit_format_set(sl, "%1.0f");
elm_slider_indicator_format_set(sl, "%1.0f");
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.5);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
elm_slider_value_set(sl, input->volume.volumes[0]);
elm_box_pack_end(bx, sl);
evas_object_show(sl);
evas_object_smart_callback_add(sl, "changed",
_cb_sink_input_volume_change, bxv);
evas_object_smart_callback_add(sl, "slider,drag,stop",
_cb_sink_input_volume_drag_stop, bxv);
/* Compare each volume level and check if they differ. If they differ unlock
the volume control and let user set each channel volume level */
for (i = 1; i < input->volume.channel_count; ++i)
{
if (input->volume.volumes[i - 1] != input->volume.volumes[i])
{
locked = EINA_FALSE;
break;
}
}
ck = elm_check_add(win);
evas_object_data_set(bxv, "mute", ck);
elm_object_text_set(ck, "Mute");
elm_check_state_set(ck, input->mute);
elm_object_disabled_set(sl, input->mute);
elm_box_pack_end(bx, ck);
evas_object_show(ck);
evas_object_smart_callback_add(ck, "changed",
_cb_sink_input_mute_change, bxv);
_emix_sink_input_volume_fill(input, bxv, bx, locked);
sep = elm_separator_add(win);
elm_separator_horizontal_set(sep, EINA_TRUE);
@ -346,7 +655,8 @@ static void
_emix_sink_input_change(Emix_Sink_Input *input)
{
const Eina_List *l;
Evas_Object *bxv, *hv, *ck, *sl;
Eina_List *ll;
Evas_Object *bxv, *hv, *ck, *sl, *lb;
Emix_Sink *sink;
EINA_LIST_FOREACH(sink_input_list, l, bxv)
@ -363,15 +673,35 @@ _emix_sink_input_change(Emix_Sink_Input *input)
_cb_sink_input_port_change, sink);
if (input->sink == sink) elm_object_text_set(hv, sink->name);
}
sl = evas_object_data_get(bxv, "volume");
elm_slider_value_set(sl, input->volume.volumes[0]);
ck = evas_object_data_get(bxv, "mute");
elm_check_state_set(ck, input->mute);
elm_object_disabled_set(sl, input->mute);
ck = evas_object_data_get(bxv, "lock");
if (ck && !elm_check_state_get(ck))
{
ck = evas_object_data_get(bxv, "mute");
elm_check_state_set(ck, input->mute);
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), ll, sl)
{
elm_slider_value_set(sl,
input->volume.volumes[(uintptr_t)evas_object_data_get(sl, "channel")]);
elm_object_disabled_set(sl, input->mute);
lb = evas_object_data_get(sl, "lb");
elm_object_disabled_set(lb, input->mute);
}
}
else
{
ck = evas_object_data_get(bxv, "mute");
elm_check_state_set(ck, input->mute);
sl = evas_object_data_get(bxv, "volume");
elm_slider_value_set(sl, input->volume.volumes[0]);
elm_object_disabled_set(sl, input->mute);
}
}
//////////////////////////////////////////////////////////////////////////////
static void _emix_source_volume_fill(Emix_Source *source, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked);
static void
_cb_source_volume_change(void *data,
@ -385,6 +715,20 @@ _cb_source_volume_change(void *data,
elm_slider_value_set(obj, vol);
}
static void
_cb_source_volume_channel_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *bxv = data;
Emix_Source *source = evas_object_data_get(bxv, "source");
double vol = elm_slider_value_get(obj);
source->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")] = vol;
elm_slider_value_set(obj, vol);
emix_source_volume_set(source, &source->volume);
}
static void
_cb_source_volume_drag_stop(void *data,
Evas_Object *obj,
@ -396,6 +740,17 @@ _cb_source_volume_drag_stop(void *data,
elm_slider_value_set(obj, vol);
}
static void
_cb_source_volume_channel_drag_stop(void *data,
Evas_Object *obj,
void *event EINA_UNUSED)
{
Evas_Object *bxv = data;
Emix_Source *source = evas_object_data_get(bxv, "source");
int vol = source->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")];
elm_slider_value_set(obj, vol);
}
static void
_cb_source_mute_change(void *data,
Evas_Object *obj,
@ -403,16 +758,153 @@ _cb_source_mute_change(void *data,
{
Evas_Object *bxv = data;
Emix_Source *source = evas_object_data_get(bxv, "source");
Evas_Object *sl = evas_object_data_get(bxv, "volume");
Evas_Object *sl;
Evas_Object *lock = evas_object_data_get(bxv, "lock");
Eina_Bool mute = elm_check_state_get(obj);
elm_object_disabled_set(sl, mute);
Evas_Object *lb;
Eina_List *l;
if (lock && !elm_check_state_get(lock))
{
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), l, sl)
{
elm_object_disabled_set(sl, mute);
lb = evas_object_data_get(sl, "lb");
elm_object_disabled_set(lb, mute);
}
}
else
{
sl = evas_object_data_get(bxv, "volume");
elm_object_disabled_set(sl, mute);
}
emix_source_mute_set(source, mute);
}
static void
_cb_source_lock_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Evas_Object *bxv = data;
Emix_Source *source = evas_object_data_get(bxv, "source");
Evas_Object *bx = evas_object_data_get(bxv, "volume_bx");
Eina_Bool lock = elm_check_state_get(obj);
if (lock)
VOLSET(source->volume.volumes[0], source->volume,
source, emix_source_volume_set);
_emix_source_volume_fill(source, bxv, bx, lock);
}
static void
_emix_source_volume_fill(Emix_Source *source, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked)
{
Evas_Object *bxhv, *lb, *sl, *ck;
Eina_List *sls = NULL;
unsigned int i;
eina_list_free(evas_object_data_get(bxv, "volumes"));
elm_box_clear(bx);
bxhv = elm_box_add(bx);
evas_object_size_hint_weight_set(bxhv, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bxhv, EVAS_HINT_FILL, 0.5);
elm_box_pack_end(bx, bxhv);
evas_object_show(bxhv);
if (locked)
{
sl = elm_slider_add(bx);
evas_object_data_set(bxv, "volume", sl);
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
elm_slider_unit_format_set(sl, "%1.0f");
elm_slider_indicator_format_set(sl, "%1.0f");
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_slider_value_set(sl, source->volume.volumes[0]);
elm_box_pack_end(bxhv, sl);
evas_object_show(sl);
evas_object_smart_callback_add(sl, "changed",
_cb_source_volume_change, bxv);
evas_object_smart_callback_add(sl, "slider,drag,stop",
_cb_source_volume_drag_stop, bxv);
elm_object_disabled_set(sl, source->mute);
}
else
{
for (i = 0; i < source->volume.channel_count; ++i)
{
lb = elm_label_add(bx);
if (!source->volume.channel_names)
{
char buf[1024];
snprintf(buf, sizeof(buf), "Channel %d", i);
elm_object_text_set(lb, buf);
}
else
elm_object_text_set(lb, source->volume.channel_names[i]);
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
evas_object_size_hint_align_set(lb, 0.0, 0.5);
elm_box_pack_end(bxhv, lb);
elm_object_disabled_set(lb, source->mute);
evas_object_show(lb);
sl = elm_slider_add(bx);
evas_object_data_set(sl, "lb", lb);
evas_object_data_set(sl, "channel", (uintptr_t *)(uintptr_t)i);
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
elm_slider_unit_format_set(sl, "%1.0f");
elm_slider_indicator_format_set(sl, "%1.0f");
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_slider_value_set(sl, source->volume.volumes[i]);
elm_box_pack_end(bxhv, sl);
evas_object_show(sl);
evas_object_smart_callback_add(sl, "changed",
_cb_source_volume_channel_change, bxv);
evas_object_smart_callback_add(sl, "slider,drag,stop",
_cb_source_volume_channel_drag_stop, bxv);
elm_object_disabled_set(sl, source->mute);
sls = eina_list_append(sls, sl);
}
}
evas_object_data_set(bxv, "volumes", sls);
bxhv = elm_box_add(bx);
elm_box_pack_end(bx, bxhv);
evas_object_show(bxhv);
ck = elm_check_add(bx);
evas_object_data_set(bxv, "mute", ck);
elm_object_text_set(ck, "Mute");
elm_check_state_set(ck, source->mute);
elm_box_pack_end(bxhv, ck);
evas_object_show(ck);
evas_object_smart_callback_add(ck, "changed",
_cb_source_mute_change, bxv);
if (source->volume.channel_count > 1)
{
ck = elm_check_add(bx);
evas_object_data_set(bxv, "lock", ck);
elm_object_text_set(ck, "Lock");
elm_check_state_set(ck, locked);
elm_box_pack_end(bxhv, ck);
evas_object_show(ck);
evas_object_smart_callback_add(ck, "changed",
_cb_source_lock_change, bxv);
}
}
static void
_emix_source_add(Emix_Source *source)
{
Evas_Object *bxv, *bx, *lb, *ck, *sl, *sep;
Evas_Object *bxv, *bx, *lb, *sep;
unsigned int i;
Eina_Bool locked = EINA_TRUE;
bxv = elm_box_add(win);
source_list = eina_list_append(source_list, bxv);
@ -429,43 +921,32 @@ _emix_source_add(Emix_Source *source)
lb = elm_label_add(win);
elm_object_text_set(lb, source->name);
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(lb, 0.0, 0.5);
elm_box_pack_end(bx, lb);
evas_object_show(lb);
bx = elm_box_add(win);
evas_object_data_set(bxv, "volume_bx", bx);
elm_box_horizontal_set(bx, EINA_TRUE);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.5);
elm_box_pack_end(bxv, bx);
evas_object_show(bx);
sl = elm_slider_add(win);
evas_object_data_set(bxv, "volume", sl);
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
elm_slider_unit_format_set(sl, "%1.0f");
elm_slider_indicator_format_set(sl, "%1.0f");
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.5);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
elm_slider_value_set(sl, source->volume.volumes[0]);
elm_box_pack_end(bx, sl);
evas_object_show(sl);
evas_object_smart_callback_add(sl, "changed",
_cb_source_volume_change, bxv);
evas_object_smart_callback_add(sl, "slider,drag,stop",
_cb_source_volume_drag_stop, bxv);
/* Compare each volume level and check if they differ. If they differ unlock
the volume control and let user set each channel volume level */
for (i = 1; i < source->volume.channel_count; ++i)
{
if (source->volume.volumes[i - 1] != source->volume.volumes[i])
{
locked = EINA_FALSE;
break;
}
}
_emix_source_volume_fill(source, bxv, bx, locked);
ck = elm_check_add(win);
evas_object_data_set(bxv, "mute", ck);
elm_object_text_set(ck, "Mute");
elm_check_state_set(ck, source->mute);
elm_object_disabled_set(sl, source->mute);
elm_box_pack_end(bx, ck);
evas_object_show(ck);
evas_object_smart_callback_add(ck, "changed",
_cb_source_mute_change, bxv);
sep = elm_separator_add(win);
elm_separator_horizontal_set(sep, EINA_TRUE);
@ -498,19 +979,39 @@ static void
_emix_source_change(Emix_Source *source)
{
const Eina_List *l;
Evas_Object *bxv, *ck, *sl;
Eina_List *ll;
Evas_Object *bxv, *ck, *sl, *lb;
EINA_LIST_FOREACH(source_list, l, bxv)
{
if (evas_object_data_get(bxv, "source") == source) break;
}
if (!l) return;
sl = evas_object_data_get(bxv, "volume");
elm_slider_value_set(sl, source->volume.volumes[0]);
ck = evas_object_data_get(bxv, "mute");
elm_check_state_set(ck, source->mute);
elm_object_disabled_set(sl, source->mute);
ck = evas_object_data_get(bxv, "lock");
if (ck && !elm_check_state_get(ck))
{
ck = evas_object_data_get(bxv, "mute");
elm_check_state_set(ck, source->mute);
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), ll, sl)
{
elm_slider_value_set(sl,
source->volume.volumes[(uintptr_t)evas_object_data_get(sl, "channel")]);
elm_object_disabled_set(sl, source->mute);
lb = evas_object_data_get(sl, "lb");
elm_object_disabled_set(lb, source->mute);
}
}
else
{
ck = evas_object_data_get(bxv, "mute");
elm_check_state_set(ck, source->mute);
sl = evas_object_data_get(bxv, "volume");
elm_slider_value_set(sl, source->volume.volumes[0]);
elm_object_disabled_set(sl, source->mute);
}
}
//////////////////////////////////////////////////////////////////////////////

View File

@ -158,7 +158,7 @@ _volume_increase_cb(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED)
volume.volumes[i] = s->volume.volumes[i];
}
emix_sink_volume_set(s, volume);
emix_sink_volume_set(s, &volume);
emix_config_save_state_get();
if (emix_config_save_get()) e_config_save_queue();
free(volume.volumes);
@ -184,7 +184,7 @@ _volume_decrease_cb(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED)
volume.volumes[i] = s->volume.volumes[i];
}
emix_sink_volume_set((Emix_Sink *)_sink_default, volume);
emix_sink_volume_set((Emix_Sink *)_sink_default, &volume);
emix_config_save_state_get();
if (emix_config_save_get()) e_config_save_queue();
free(volume.volumes);

View File

@ -408,25 +408,25 @@ _alsa_sources_mute_set(Emix_Source *source, Eina_Bool mute)
}
static void
_alsa_sources_volume_set(Emix_Source *source, Emix_Volume v)
_alsa_sources_volume_set(Emix_Source *source, Emix_Volume *v)
{
Alsa_Emix_Source *s = (Alsa_Emix_Source*) source;
unsigned int i;
snd_mixer_elem_t *elem;
EINA_SAFETY_ON_FALSE_RETURN((ctx && source));
EINA_SAFETY_ON_FALSE_RETURN((ctx && source && v));
if (v.channel_count != eina_list_count(s->channels))
if (v->channel_count != eina_list_count(s->channels))
{
ERR("Volume struct doesn't have the same length than the channels");
return;
}
for (i = 0; i < v.channel_count; i++ )
for (i = 0; i < v->channel_count; i++ )
{
elem = eina_list_nth(s->channels, i);
_alsa_channel_volume_set(elem, v.volumes[i], EINA_FALSE);
s->source.volume.volumes[i] = v.volumes[i];
_alsa_channel_volume_set(elem, v->volumes[i], EINA_FALSE);
s->source.volume.volumes[i] = v->volumes[i];
}
if (ctx->cb)
ctx->cb((void *)ctx->userdata, EMIX_SOURCE_CHANGED_EVENT,
@ -480,25 +480,25 @@ _alsa_sink_mute_set(Emix_Sink *sink, Eina_Bool mute)
}
static void
_alsa_sink_volume_set(Emix_Sink *sink, Emix_Volume v)
_alsa_sink_volume_set(Emix_Sink *sink, Emix_Volume *v)
{
Alsa_Emix_Sink *s = (Alsa_Emix_Sink *)sink;
unsigned int i;
snd_mixer_elem_t *elem;
EINA_SAFETY_ON_FALSE_RETURN((ctx && sink));
EINA_SAFETY_ON_FALSE_RETURN((ctx && sink && v));
if (v.channel_count != eina_list_count(s->channels))
if (v->channel_count != eina_list_count(s->channels))
{
ERR("Volume struct doesn't have the same length than the channels");
return;
}
for (i = 0; i < v.channel_count; i++ )
for (i = 0; i < v->channel_count; i++ )
{
elem = eina_list_nth(s->channels, i);
_alsa_channel_volume_set(elem, v.volumes[i], EINA_FALSE);
s->sink.volume.volumes[i] = v.volumes[i];
_alsa_channel_volume_set(elem, v->volumes[i], EINA_FALSE);
s->sink.volume.volumes[i] = v->volumes[i];
}
if (ctx->cb)
ctx->cb((void *)ctx->userdata, EMIX_SINK_CHANGED_EVENT,

View File

@ -66,14 +66,14 @@ static Context *ctx = NULL;
extern pa_mainloop_api functable;
static pa_cvolume
_emix_volume_convert(const Emix_Volume volume)
_emix_volume_convert(const Emix_Volume *volume)
{
pa_cvolume vol;
unsigned int i;
vol.channels = volume.channel_count;
for (i = 0; i < volume.channel_count; i++)
vol.values[i] = INT_TO_PA_VOLUME(volume.volumes[i]);
vol.channels = volume->channel_count;
for (i = 0; i < volume->channel_count; i++)
vol.values[i] = INT_TO_PA_VOLUME(volume->volumes[i]);
return vol;
}
@ -98,6 +98,7 @@ _pa_cvolume_convert(const pa_cvolume *volume, Emix_Volume *vol)
static void
_sink_del(Sink *sink)
{
unsigned int i;
Emix_Port *port;
EINA_SAFETY_ON_NULL_RETURN(sink);
@ -109,6 +110,9 @@ _sink_del(Sink *sink)
}
free(sink->base.volume.volumes);
for(i = 0; i < sink->base.volume.channel_count; ++i)
eina_stringshare_del(sink->base.volume.channel_names[i]);
free(sink->base.volume.channel_names);
eina_stringshare_del(sink->base.name);
free(sink);
}
@ -116,9 +120,13 @@ _sink_del(Sink *sink)
static void
_sink_input_del(Sink_Input *input)
{
unsigned int i;
EINA_SAFETY_ON_NULL_RETURN(input);
free(input->base.volume.volumes);
for(i = 0; i < input->base.volume.channel_count; ++i)
eina_stringshare_del(input->base.volume.channel_names[i]);
free(input->base.volume.channel_names);
eina_stringshare_del(input->base.name);
eina_stringshare_del(input->icon);
free(input);
@ -127,9 +135,13 @@ _sink_input_del(Sink_Input *input)
static void
_source_del(Source *source)
{
unsigned int i;
EINA_SAFETY_ON_NULL_RETURN(source);
free(source->base.volume.volumes);
for(i = 0; i < source->base.volume.channel_count; ++i)
eina_stringshare_del(source->base.volume.channel_names[i]);
free(source->base.volume.channel_names);
eina_stringshare_del(source->base.name);
free(source);
}
@ -177,6 +189,9 @@ _sink_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
sink->idx = info->index;
sink->base.name = eina_stringshare_add(info->description);
_pa_cvolume_convert(&info->volume, &sink->base.volume);
sink->base.volume.channel_names = calloc(sink->base.volume.channel_count, sizeof(Emix_Channel));
for (i = 0; i < sink->base.volume.channel_count; ++i)
sink->base.volume.channel_names[i] = eina_stringshare_add(pa_channel_position_to_pretty_string(info->channel_map.map[i]));
sink->base.mute = !!info->mute;
for (i = 0; i < info->n_ports; i++)
@ -238,7 +253,18 @@ _sink_changed_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
EINA_SAFETY_ON_NULL_RETURN(sink);
eina_stringshare_replace(&sink->base.name, info->description);
if (sink->base.volume.channel_count != info->volume.channels)
{
for (i = 0; i < sink->base.volume.channel_count; ++i)
eina_stringshare_del(sink->base.volume.channel_names[i]);
free(sink->base.volume.channel_names);
sink->base.volume.channel_names = calloc(info->volume.channels, sizeof(Emix_Channel));
}
_pa_cvolume_convert(&info->volume, &sink->base.volume);
for (i = 0; i < sink->base.volume.channel_count; ++i)
eina_stringshare_replace(&sink->base.volume.channel_names[i],
pa_channel_position_to_pretty_string(info->channel_map.map[i]));
sink->base.mute = !!info->mute;
if (sink->base.ports)
@ -335,6 +361,7 @@ _sink_input_cb(pa_context *c EINA_UNUSED, const pa_sink_input_info *info,
Eina_List *l;
Sink *s;
const char *t;
unsigned int i;
EINA_SAFETY_ON_NULL_RETURN(ctx);
if (eol < 0)
@ -374,6 +401,9 @@ _sink_input_cb(pa_context *c EINA_UNUSED, const pa_sink_input_info *info,
input->base.name = eina_stringshare_add(eina_strbuf_string_get(input_name));
eina_strbuf_free(input_name);
_pa_cvolume_convert(&info->volume, &input->base.volume);
input->base.volume.channel_names = calloc(input->base.volume.channel_count, sizeof(Emix_Channel));
for (i = 0; i < input->base.volume.channel_count; ++i)
input->base.volume.channel_names[i] = eina_stringshare_add(pa_channel_position_to_pretty_string(info->channel_map.map[i]));
input->base.mute = !!info->mute;
EINA_LIST_FOREACH(ctx->sinks, l, s)
{
@ -398,10 +428,11 @@ _sink_input_changed_cb(pa_context *c EINA_UNUSED,
const pa_sink_input_info *info, int eol,
void *userdata EINA_UNUSED)
{
Sink_Input *input = NULL, *i;
Sink_Input *input = NULL, *si;
Sink *s = NULL;
Eina_List *l;
const char *t;
unsigned int i;
EINA_SAFETY_ON_NULL_RETURN(ctx);
if (eol < 0)
@ -416,11 +447,11 @@ _sink_input_changed_cb(pa_context *c EINA_UNUSED,
if (eol > 0)
return;
EINA_LIST_FOREACH(ctx->inputs, l, i)
EINA_LIST_FOREACH(ctx->inputs, l, si)
{
if (i->idx == (int)info->index)
if (si->idx == (int)info->index)
{
input = i;
input = si;
break;
}
}
@ -434,7 +465,18 @@ _sink_input_changed_cb(pa_context *c EINA_UNUSED,
ctx->inputs = eina_list_append(ctx->inputs, input);
}
input->idx = info->index;
if (input->base.volume.channel_count != info->volume.channels)
{
for (i = 0; i < input->base.volume.channel_count; ++i)
eina_stringshare_del(input->base.volume.channel_names[i]);
free(input->base.volume.channel_names);
input->base.volume.channel_names = calloc(info->volume.channels, sizeof(Emix_Channel));
}
_pa_cvolume_convert(&info->volume, &input->base.volume);
for (i = 0; i < input->base.volume.channel_count; ++i)
eina_stringshare_replace(&input->base.volume.channel_names[i],
pa_channel_position_to_pretty_string(info->channel_map.map[i]));
input->base.mute = !!info->mute;
EINA_LIST_FOREACH(ctx->sinks, l, s)
@ -482,6 +524,7 @@ _source_cb(pa_context *c EINA_UNUSED, const pa_source_info *info,
int eol, void *userdata EINA_UNUSED)
{
Source *source;
unsigned int i;
EINA_SAFETY_ON_NULL_RETURN(ctx);
if (eol < 0)
@ -502,6 +545,9 @@ _source_cb(pa_context *c EINA_UNUSED, const pa_source_info *info,
source->idx = info->index;
source->base.name = eina_stringshare_add(info->name);
_pa_cvolume_convert(&info->volume, &source->base.volume);
source->base.volume.channel_names = calloc(source->base.volume.channel_count, sizeof(Emix_Channel));
for (i = 0; i < source->base.volume.channel_count; ++i)
source->base.volume.channel_names[i] = eina_stringshare_add(pa_channel_position_to_pretty_string(info->channel_map.map[i]));
source->base.mute = !!info->mute;
ctx->sources = eina_list_append(ctx->sources, source);
@ -517,6 +563,7 @@ _source_changed_cb(pa_context *c EINA_UNUSED,
{
Source *source = NULL, *s;
Eina_List *l;
unsigned int i;
EINA_SAFETY_ON_NULL_RETURN(ctx);
if (eol < 0)
@ -549,7 +596,17 @@ _source_changed_cb(pa_context *c EINA_UNUSED,
ctx->sources = eina_list_append(ctx->sources, source);
}
source->idx= info->index;
if (source->base.volume.channel_count != info->volume.channels)
{
for (i = 0; i < source->base.volume.channel_count; ++i)
eina_stringshare_del(source->base.volume.channel_names[i]);
free(source->base.volume.channel_names);
source->base.volume.channel_names = calloc(info->volume.channels, sizeof(Emix_Channel));
}
_pa_cvolume_convert(&info->volume, &source->base.volume);
for (i = 0; i < source->base.volume.channel_count; ++i)
eina_stringshare_replace(&source->base.volume.channel_names[i],
pa_channel_position_to_pretty_string(info->channel_map.map[i]));
source->base.mute = !!info->mute;
if (ctx->cb)
@ -1164,7 +1221,7 @@ _disconnect_cb()
}
static void
_source_volume_set(Emix_Source *source, Emix_Volume volume)
_source_volume_set(Emix_Source *source, Emix_Volume *volume)
{
pa_operation* o;
pa_cvolume vol = _emix_volume_convert(volume);
@ -1211,7 +1268,7 @@ _sink_inputs_get(void)
}
static void
_sink_volume_set(Emix_Sink *sink, Emix_Volume volume)
_sink_volume_set(Emix_Sink *sink, Emix_Volume *volume)
{
pa_operation* o;
Sink *s = (Sink *)sink;
@ -1236,7 +1293,7 @@ _sink_mute_set(Emix_Sink *sink, Eina_Bool mute)
}
static void
_sink_input_volume_set(Emix_Sink_Input *input, Emix_Volume volume)
_sink_input_volume_set(Emix_Sink_Input *input, Emix_Volume *volume)
{
pa_operation* o;
Sink_Input *sink_input = (Sink_Input *)input;

View File

@ -282,7 +282,7 @@ emix_sink_mute_set(Emix_Sink *sink, Eina_Bool mute)
}
void
emix_sink_volume_set(Emix_Sink *sink, Emix_Volume volume)
emix_sink_volume_set(Emix_Sink *sink, Emix_Volume *volume)
{
EINA_SAFETY_ON_FALSE_RETURN((ctx && ctx->loaded &&
ctx->loaded->ebackend_sink_volume_set &&
@ -320,7 +320,7 @@ emix_sink_input_mute_set(Emix_Sink_Input *input, Eina_Bool mute)
}
void
emix_sink_input_volume_set(Emix_Sink_Input *input, Emix_Volume volume)
emix_sink_input_volume_set(Emix_Sink_Input *input, Emix_Volume *volume)
{
EINA_SAFETY_ON_FALSE_RETURN((ctx && ctx->loaded &&
ctx->loaded->ebackend_sink_input_volume_set &&
@ -359,7 +359,7 @@ emix_source_mute_set(Emix_Source *source, Eina_Bool mute)
}
void
emix_source_volume_set(Emix_Source *source, Emix_Volume volume)
emix_source_volume_set(Emix_Source *source, Emix_Volume *volume)
{
EINA_SAFETY_ON_FALSE_RETURN((ctx && ctx->loaded &&
ctx->loaded->ebackend_source_volume_set &&

View File

@ -42,10 +42,13 @@ enum Emix_Event {
EMIX_CARD_CHANGED_EVENT
};
typedef const char * Emix_Channel;
typedef struct _Emix_Volume {
unsigned int channel_count;
// the index of the field is the id of the channel, the value the volume
int *volumes;
Emix_Channel *channel_names;
} Emix_Volume;
typedef struct _Emix_Port {
@ -104,7 +107,7 @@ typedef struct _Emix_Backend {
void (*ebackend_sink_mute_set)(Emix_Sink *sink,
Eina_Bool mute);
void (*ebackend_sink_volume_set)(Emix_Sink *sink,
Emix_Volume volume);
Emix_Volume *volume);
Eina_Bool (*ebackend_sink_port_set)(Emix_Sink *sink,
const Emix_Port *port);
Eina_Bool (*ebackend_sink_change_support)(void);
@ -113,7 +116,7 @@ typedef struct _Emix_Backend {
void (*ebackend_sink_input_mute_set)(
Emix_Sink_Input *input, Eina_Bool mute);
void (*ebackend_sink_input_volume_set)(
Emix_Sink_Input *input, Emix_Volume volume);
Emix_Sink_Input *input, Emix_Volume *volume);
void (*ebackend_sink_input_sink_change)(
Emix_Sink_Input *input, Emix_Sink *sink);
@ -121,7 +124,7 @@ typedef struct _Emix_Backend {
void (*ebackend_source_mute_set)(Emix_Source *source,
Eina_Bool mute);
void (*ebackend_source_volume_set)(Emix_Source *source,
Emix_Volume volume);
Emix_Volume *volume);
Evas_Object* (*ebackend_advanced_options_add)(Evas_Object *parent);
const Eina_List* (*ebackend_cards_get)(void);
@ -132,17 +135,13 @@ typedef struct _Emix_Backend {
#define VOLSET(vol, srcvol, target, func) \
do { \
Emix_Volume _v; \
int _pvol = srcvol.volumes[0]; \
if ((_pvol > 80) && (_pvol <= 100) && \
(vol > 100) && (vol < 120)) vol = 100; \
_v.channel_count = srcvol.channel_count; \
_v.volumes = calloc(srcvol.channel_count, sizeof(int)); \
if (_v.volumes) { \
if (srcvol.volumes) { \
unsigned int _i; \
for (_i = 0; _i < _v.channel_count; _i++) _v.volumes[_i] = vol; \
func(target, _v); \
free(_v.volumes); \
for (_i = 0; _i < srcvol.channel_count; _i++) srcvol.volumes[_i] = vol; \
func(target, &srcvol); \
} \
} while (0)
@ -167,14 +166,14 @@ E_API Eina_Bool emix_sink_port_set(Emix_Sink *sink, Emix_Port *port);
E_API void emix_sink_default_set(Emix_Sink *sink);
E_API void emix_sink_mute_set(Emix_Sink *sink, Eina_Bool mute);
E_API void emix_sink_volume_set(Emix_Sink *sink,
Emix_Volume volume);
Emix_Volume *volume);
E_API Eina_Bool emix_sink_change_support(void);
E_API const Eina_List* emix_sink_inputs_get(void);
E_API void emix_sink_input_mute_set(Emix_Sink_Input *input,
Eina_Bool mute);
E_API void emix_sink_input_volume_set(Emix_Sink_Input *input,
Emix_Volume volume);
Emix_Volume *volume);
E_API void emix_sink_input_sink_change(Emix_Sink_Input *input,
Emix_Sink *sink);
@ -182,7 +181,7 @@ E_API const Eina_List* emix_sources_get(void);
E_API void emix_source_mute_set(Emix_Source *source,
Eina_Bool mute);
E_API void emix_source_volume_set(Emix_Source *source,
Emix_Volume volume);
Emix_Volume *volume);
E_API Evas_Object* emix_advanced_options_add(Evas_Object *parent);
E_API const Eina_List* emix_cards_get(void);