mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2026-03-22 05:33:43 -04:00
control: remap - separate event handling from map (preparation for sync)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
fb285b366f
commit
42b8f1299f
1 changed files with 58 additions and 31 deletions
|
|
@ -79,26 +79,36 @@ typedef struct {
|
||||||
unsigned int src_channels;
|
unsigned int src_channels;
|
||||||
long *channel_map;
|
long *channel_map;
|
||||||
} *controls;
|
} *controls;
|
||||||
unsigned int event_mask;
|
|
||||||
} snd_ctl_map_t;
|
} snd_ctl_map_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
snd_ctl_elem_id_t *id;
|
||||||
|
unsigned int numid_app;
|
||||||
|
unsigned int event_mask;
|
||||||
|
} snd_ctl_map_event_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
snd_ctl_t *child;
|
snd_ctl_t *child;
|
||||||
int numid_remap_active;
|
int numid_remap_active;
|
||||||
unsigned int numid_app_last;
|
unsigned int numid_app_last;
|
||||||
|
|
||||||
size_t numid_items;
|
size_t numid_items;
|
||||||
size_t numid_alloc;
|
size_t numid_alloc;
|
||||||
snd_ctl_numid_t *numid;
|
snd_ctl_numid_t *numid;
|
||||||
snd_ctl_numid_t numid_temp;
|
snd_ctl_numid_t numid_temp;
|
||||||
|
|
||||||
size_t remap_items;
|
size_t remap_items;
|
||||||
size_t remap_alloc;
|
size_t remap_alloc;
|
||||||
snd_ctl_remap_id_t *remap;
|
snd_ctl_remap_id_t *remap;
|
||||||
|
|
||||||
size_t map_items;
|
size_t map_items;
|
||||||
size_t map_alloc;
|
size_t map_alloc;
|
||||||
snd_ctl_map_t *map;
|
snd_ctl_map_t *map;
|
||||||
size_t map_read_queue_head;
|
|
||||||
size_t map_read_queue_tail;
|
size_t event_items;
|
||||||
snd_ctl_map_t **map_read_queue;
|
size_t event_queue_head;
|
||||||
|
size_t event_queue_tail;
|
||||||
|
snd_ctl_map_event_t *event_queue;
|
||||||
} snd_ctl_remap_t;
|
} snd_ctl_remap_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -303,7 +313,7 @@ static void remap_free(snd_ctl_remap_t *priv)
|
||||||
free(map->controls[idx2].channel_map);
|
free(map->controls[idx2].channel_map);
|
||||||
free(map->controls);
|
free(map->controls);
|
||||||
}
|
}
|
||||||
free(priv->map_read_queue);
|
free(priv->event_queue);
|
||||||
free(priv->map);
|
free(priv->map);
|
||||||
free(priv->remap);
|
free(priv->remap);
|
||||||
free(priv->numid);
|
free(priv->numid);
|
||||||
|
|
@ -831,19 +841,45 @@ static void _next_ptr(size_t *ptr, size_t count)
|
||||||
*ptr = (*ptr + 1) % count;
|
*ptr = (*ptr + 1) % count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void event_add(snd_ctl_remap_t *priv, snd_ctl_elem_id_t *id,
|
||||||
|
unsigned int numid_app, unsigned int event_mask)
|
||||||
|
{
|
||||||
|
snd_ctl_map_event_t *map_event;
|
||||||
|
int found = 0;
|
||||||
|
size_t head;
|
||||||
|
|
||||||
|
for (head = priv->event_queue_head;
|
||||||
|
head != priv->event_queue_tail;
|
||||||
|
_next_ptr(&head, priv->event_items))
|
||||||
|
if (priv->event_queue[head].numid_app == numid_app) {
|
||||||
|
found = 1;
|
||||||
|
priv->event_queue[head].event_mask |= event_mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debug_id(id, "%s marking for read (already %d)\n", __func__, found);
|
||||||
|
if (found)
|
||||||
|
return;
|
||||||
|
map_event = &priv->event_queue[priv->event_queue_tail];
|
||||||
|
map_event->id = id;
|
||||||
|
map_event->numid_app = numid_app;
|
||||||
|
map_event->event_mask = event_mask;
|
||||||
|
_next_ptr(&priv->event_queue_tail, priv->event_items);
|
||||||
|
}
|
||||||
|
|
||||||
static void remap_event_for_all_map_controls(snd_ctl_remap_t *priv,
|
static void remap_event_for_all_map_controls(snd_ctl_remap_t *priv,
|
||||||
snd_ctl_elem_id_t *id,
|
snd_ctl_elem_id_t *id,
|
||||||
unsigned int event_mask)
|
unsigned int event_mask)
|
||||||
{
|
{
|
||||||
size_t count, index, head;
|
size_t count, index;
|
||||||
snd_ctl_map_t *map;
|
snd_ctl_map_t *map;
|
||||||
struct snd_ctl_map_ctl *mctl;
|
struct snd_ctl_map_ctl *mctl;
|
||||||
int found;
|
int changed = 0;
|
||||||
|
|
||||||
if (event_mask == SNDRV_CTL_EVENT_MASK_REMOVE)
|
if (event_mask == SNDRV_CTL_EVENT_MASK_REMOVE)
|
||||||
event_mask = SNDRV_CTL_EVENT_MASK_INFO;
|
event_mask = SNDRV_CTL_EVENT_MASK_INFO;
|
||||||
map = priv->map;
|
map = priv->map;
|
||||||
for (count = priv->map_items; count > 0; count--, map++) {
|
for (count = priv->map_items; count > 0; count--, map++) {
|
||||||
|
changed = 0;
|
||||||
for (index = 0; index < map->controls_items; index++) {
|
for (index = 0; index < map->controls_items; index++) {
|
||||||
mctl = &map->controls[index];
|
mctl = &map->controls[index];
|
||||||
if (mctl->id_child.numid == 0) {
|
if (mctl->id_child.numid == 0) {
|
||||||
|
|
@ -854,21 +890,10 @@ static void remap_event_for_all_map_controls(snd_ctl_remap_t *priv,
|
||||||
if (id->numid != mctl->id_child.numid)
|
if (id->numid != mctl->id_child.numid)
|
||||||
continue;
|
continue;
|
||||||
debug_id(&map->map_id, "%s found (all)\n", __func__);
|
debug_id(&map->map_id, "%s found (all)\n", __func__);
|
||||||
map->event_mask |= event_mask;
|
changed = 1;
|
||||||
found = 0;
|
|
||||||
for (head = priv->map_read_queue_head;
|
|
||||||
head != priv->map_read_queue_tail;
|
|
||||||
_next_ptr(&head, priv->map_items))
|
|
||||||
if (priv->map_read_queue[head] == map) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (found)
|
|
||||||
continue;
|
|
||||||
debug_id(&map->map_id, "%s marking for read\n", __func__);
|
|
||||||
priv->map_read_queue[priv->map_read_queue_tail] = map;
|
|
||||||
_next_ptr(&priv->map_read_queue_tail, priv->map_items);
|
|
||||||
}
|
}
|
||||||
|
if (changed)
|
||||||
|
event_add(priv, &map->map_id, map->map_id.numid, event_mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -877,18 +902,18 @@ static int snd_ctl_remap_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
|
||||||
snd_ctl_remap_t *priv = ctl->private_data;
|
snd_ctl_remap_t *priv = ctl->private_data;
|
||||||
snd_ctl_remap_id_t *rid;
|
snd_ctl_remap_id_t *rid;
|
||||||
snd_ctl_numid_t *numid;
|
snd_ctl_numid_t *numid;
|
||||||
snd_ctl_map_t *map;
|
snd_ctl_map_event_t *map_event;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (priv->map_read_queue_head != priv->map_read_queue_tail) {
|
if (priv->event_queue_head != priv->event_queue_tail) {
|
||||||
map = priv->map_read_queue[priv->map_read_queue_head];
|
map_event = &priv->event_queue[priv->event_queue_head];
|
||||||
_next_ptr(&priv->map_read_queue_head, priv->map_items);
|
_next_ptr(&priv->event_queue_head, priv->event_items);
|
||||||
memset(event, 0, sizeof(*event));
|
memset(event, 0, sizeof(*event));
|
||||||
event->type = SNDRV_CTL_EVENT_ELEM;
|
event->type = SNDRV_CTL_EVENT_ELEM;
|
||||||
event->data.elem.mask = map->event_mask;
|
event->data.elem.mask = map_event->event_mask;
|
||||||
event->data.elem.id = map->map_id;
|
event->data.elem.id = *map_event->id;
|
||||||
map->event_mask = 0;
|
event->data.elem.id.numid = map_event->numid_app;
|
||||||
debug_id(&map->map_id, "%s queue read\n", __func__);
|
debug_id(&event->data.elem.id, "%s queue read\n", __func__);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
err = snd_ctl_read(priv->child, event);
|
err = snd_ctl_read(priv->child, event);
|
||||||
|
|
@ -951,6 +976,7 @@ static int add_to_remap(snd_ctl_remap_t *priv,
|
||||||
{
|
{
|
||||||
snd_ctl_remap_id_t *rid;
|
snd_ctl_remap_id_t *rid;
|
||||||
|
|
||||||
|
|
||||||
if (priv->remap_alloc == priv->remap_items) {
|
if (priv->remap_alloc == priv->remap_items) {
|
||||||
rid = realloc(priv->remap, (priv->remap_alloc + 16) * sizeof(*rid));
|
rid = realloc(priv->remap, (priv->remap_alloc + 16) * sizeof(*rid));
|
||||||
if (rid == NULL)
|
if (rid == NULL)
|
||||||
|
|
@ -1266,8 +1292,9 @@ int snd_ctl_remap_open(snd_ctl_t **handlep, const char *name, snd_config_t *rema
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->map_read_queue = calloc(priv->map_items, sizeof(priv->map_read_queue[0]));
|
priv->event_items = priv->map_items;
|
||||||
if (priv->map_read_queue == NULL) {
|
priv->event_queue = calloc(priv->event_items, sizeof(priv->event_queue[0]));
|
||||||
|
if (priv->event_queue == NULL) {
|
||||||
result = -ENOMEM;
|
result = -ENOMEM;
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue