By default, all mixer applications are required to keep up-to-date with all mixer changes.
Keeping up-to-date with all mixer changes is done by enqueuing a mixer-change event on all applications other than the application making a change. The driver enqueues these events on all applications that have an open mixer handle, unless the application uses the snd_mixer_set_filter() API call to mask out events it's not interested in.
Applications use the snd_mixer_read() function to read the enqueued mixer events. The arguments to this functions are the mixer handle and a structure of callback functions to call based on the event type.
You can use the select() function to determine when to call snd_mixer_read(). To get the file descriptor to pass to select(), call snd_mixer_file_descriptor() .
Here's a short example:
static void mixer_callback_group (void *private_data,
int cmd,
snd_mixer_gid_t * gid)
{
switch (cmd)
{
case SND_MIXER_READ_GROUP_VALUE:
printf ("Mixer group %s %d changed value \n",
gid->name, gid->index);
break;
case SND_MIXER_READ_GROUP_ADD:
break;
case SND_MIXER_READ_GROUP_REMOVE:
break;
}
}
int mixer_update (int fd, void *data, unsigned mode)
{
snd_mixer_callbacks_t callbacks = { 0, 0, 0, 0 };
callbacks.group = mixer_callback_group;
snd_mixer_read (mixer_handle, &callbacks);
return (Pt_CONTINUE);
}
int main (void)
{
snd_mixer_t *mixer_handle;
int ret;
if ((ret = snd_mixer_open (&mixer_handle, 0, 0) < 0))
printf ("Unable to open/read mixer - %s",
snd_strerror (ret));
PtAppAddFd (NULL,
snd_mixer_file_descriptor (mixer_handle),
Pt_FD_READ, mixer_update, NULL);
...
}