]> git.alsa-project.org Git - alsa-lib.git/commitdiff
New universal switch v2.0 interface.
authorJaroslav Kysela <perex@perex.cz>
Sat, 27 Mar 1999 19:44:51 +0000 (19:44 +0000)
committerJaroslav Kysela <perex@perex.cz>
Sat, 27 Mar 1999 19:44:51 +0000 (19:44 +0000)
include/control.h
include/mixer.h
include/pcm.h
include/rawmidi.h
src/control/control.c
src/mixer/mixer.c
src/pcm/pcm.c
src/rawmidi/rawmidi.c
test/switches.c

index c5cd4c097a00e1fcc863088071141bf62c9e9b75..86cb4c56108f4f6e77d0d7ff414f8a6a94752bfa 100644 (file)
@@ -18,37 +18,31 @@ int snd_ctl_open(void **handle, int card);
 int snd_ctl_close(void *handle);
 int snd_ctl_file_descriptor(void *handle);
 int snd_ctl_hw_info(void *handle, struct snd_ctl_hw_info *info);
-int snd_ctl_switches(void *handle);
-int snd_ctl_switch(void *handle, const char *switch_id);
-int snd_ctl_switch_read(void *handle, int switchn, snd_ctl_switch_t * data);
-int snd_ctl_switch_write(void *handle, int switchn, snd_ctl_switch_t * data);
+int snd_ctl_switch_list(void *handle, snd_switch_list_t * list);
+int snd_ctl_switch_read(void *handle, snd_switch_t * sw);
+int snd_ctl_switch_write(void *handle, snd_switch_t * sw);
 int snd_ctl_pcm_info(void *handle, int dev, snd_pcm_info_t * info);
 int snd_ctl_pcm_playback_info(void *handle, int dev, snd_pcm_playback_info_t * info);
 int snd_ctl_pcm_record_info(void *handle, int dev, snd_pcm_record_info_t * info);
-int snd_ctl_pcm_playback_switches(void *handle, int dev);
-int snd_ctl_pcm_playback_switch(void *handle, int dev, const char *switch_id);
-int snd_ctl_pcm_playback_switch_read(void *handle, int dev, int switchn, snd_pcm_switch_t * data);
-int snd_ctl_pcm_playback_switch_write(void *handle, int dev, int switchn, snd_pcm_switch_t * data);
-int snd_ctl_pcm_record_switches(void *handle, int dev);
-int snd_ctl_pcm_record_switch(void *handle, int dev, const char *switch_id);
-int snd_ctl_pcm_record_switch_read(void *handle, int dev, int switchn, snd_pcm_switch_t * data);
-int snd_ctl_pcm_record_switch_write(void *handle, int dev, int switchn, snd_pcm_switch_t * data);
+int snd_ctl_pcm_playback_switch_list(void *handle, int dev, snd_switch_list_t * list);
+int snd_ctl_pcm_playback_switch_read(void *handle, int dev, snd_switch_t * sw);
+int snd_ctl_pcm_playback_switch_write(void *handle, int dev, snd_switch_t * sw);
+int snd_ctl_pcm_record_switch_list(void *handle, int dev, snd_switch_list_t * list);
+int snd_ctl_pcm_record_switch_read(void *handle, int dev, snd_switch_t * sw);
+int snd_ctl_pcm_record_switch_write(void *handle, int dev, snd_switch_t * sw);
 int snd_ctl_mixer_info(void *handle, int dev, snd_mixer_info_t * info);
-int snd_ctl_mixer_switches(void *handle, int dev);
-int snd_ctl_mixer_switch(void *handle, int dev, const char *switch_id);
-int snd_ctl_mixer_switch_read(void *handle, int dev, int switchn, snd_mixer_switch_t * data);
-int snd_ctl_mixer_switch_write(void *handle, int dev, int switchn, snd_mixer_switch_t * data);
+int snd_ctl_mixer_switch_list(void *handle, int dev, snd_switch_list_t *list);
+int snd_ctl_mixer_switch_read(void *handle, int dev, snd_switch_t * sw);
+int snd_ctl_mixer_switch_write(void *handle, int dev, snd_switch_t * sw);
 int snd_ctl_rawmidi_info(void *handle, int dev, snd_rawmidi_info_t * info);
 int snd_ctl_rawmidi_output_info(void *handle, int dev, snd_rawmidi_output_info_t * info);
 int snd_ctl_rawmidi_input_info(void *handle, int dev, snd_rawmidi_input_info_t * info);
-int snd_ctl_rawmidi_output_switches(void *handle, int dev);
-int snd_ctl_rawmidi_output_switch(void *handle, int dev, const char *switch_id);
-int snd_ctl_rawmidi_output_switch_read(void *handle, int dev, int switchn, snd_rawmidi_switch_t * data);
-int snd_ctl_rawmidi_output_switch_write(void *handle, int dev, int switchn, snd_rawmidi_switch_t * data);
-int snd_ctl_rawmidi_input_switches(void *handle, int dev);
-int snd_ctl_rawmidi_input_switch(void *handle, int dev, const char *switch_id);
-int snd_ctl_rawmidi_input_switch_read(void *handle, int dev, int switchn, snd_rawmidi_switch_t * data);
-int snd_ctl_rawmidi_input_switch_write(void *handle, int dev, int switchn, snd_rawmidi_switch_t * data);
+int snd_ctl_rawmidi_output_switch_list(void *handle, int dev, snd_switch_list_t *list);
+int snd_ctl_rawmidi_output_switch_read(void *handle, int dev, snd_switch_t * sw);
+int snd_ctl_rawmidi_output_switch_write(void *handle, int dev, snd_switch_t * sw);
+int snd_ctl_rawmidi_input_switch_list(void *handle, int dev, snd_switch_list_t *list);
+int snd_ctl_rawmidi_input_switch_read(void *handle, int dev, snd_switch_t * sw);
+int snd_ctl_rawmidi_input_switch_write(void *handle, int dev, snd_switch_t * sw);
 
 #ifdef __cplusplus
 }
index e2db91642a46da20058ef630eeb007d0ee67c4e2..8879f62d7159212f8d709745b8af859a2379988c 100644 (file)
@@ -34,9 +34,9 @@ int snd_mixer_channel_output_read(void *handle, int channel, snd_mixer_channel_d
 int snd_mixer_channel_output_write(void *handle, int channel, snd_mixer_channel_direction_t * data);
 int snd_mixer_channel_input_read(void *handle, int channel, snd_mixer_channel_direction_t * data);
 int snd_mixer_channel_input_write(void *handle, int channel, snd_mixer_channel_direction_t * data);
-int snd_mixer_switches(void *handle);
-int snd_mixer_switch_read(void *handle, int switchn, snd_mixer_switch_t * data);
-int snd_mixer_switch_write(void *handle, int switchn, snd_mixer_switch_t * data);
+int snd_mixer_switch_list(void *handle, snd_switch_list_t * list);
+int snd_mixer_switch_read(void *handle, snd_switch_t * sw);
+int snd_mixer_switch_write(void *handle, snd_switch_t * sw);
 int snd_mixer_read(void *handle, snd_mixer_callbacks_t * callbacks);
 
 #ifdef __cplusplus
index 0509aace03beca1e4e7590a33a8f7c04fb74d697..95c2a70f970f4ebef021bf7bd7f99b0d7bc946e3 100644 (file)
@@ -20,14 +20,12 @@ int snd_pcm_block_mode(void *handle, int enable);
 int snd_pcm_info(void *handle, snd_pcm_info_t * info);
 int snd_pcm_playback_info(void *handle, snd_pcm_playback_info_t * info);
 int snd_pcm_record_info(void *handle, snd_pcm_record_info_t * info);
-int snd_pcm_playback_switches(void *handle);
-int snd_pcm_playback_switch(void *handle, const char *switch_id);
-int snd_pcm_playback_switch_read(void *handle, int switchn, snd_pcm_switch_t * data);
-int snd_pcm_playback_switch_write(void *handle, int switchn, snd_pcm_switch_t * data);
-int snd_pcm_record_switches(void *handle);
-int snd_pcm_record_switch(void *handle, const char *switch_id);
-int snd_pcm_record_switch_read(void *handle, int switchn, snd_pcm_switch_t * data);
-int snd_pcm_record_switch_write(void *handle, int switchn, snd_pcm_switch_t * data);
+int snd_pcm_playback_switch_list(void *handle, snd_switch_list_t * list);
+int snd_pcm_playback_switch_read(void *handle, snd_switch_t * sw);
+int snd_pcm_playback_switch_write(void *handle, snd_switch_t * sw);
+int snd_pcm_record_switch_list(void *handle, snd_switch_list_t * list);
+int snd_pcm_record_switch_read(void *handle, snd_switch_t * sw);
+int snd_pcm_record_switch_write(void *handle, snd_switch_t * sw);
 int snd_pcm_playback_format(void *handle, snd_pcm_format_t * format);
 int snd_pcm_record_format(void *handle, snd_pcm_format_t * format);
 int snd_pcm_playback_params(void *handle, snd_pcm_playback_params_t * params);
index ea504014bb7e5d78dae58959895918053a24dd09..64250ff94e77d36434cb9003aa291a5ca16ed06d 100644 (file)
@@ -18,14 +18,12 @@ int snd_rawmidi_close(void *handle);
 int snd_rawmidi_file_descriptor(void *handle);
 int snd_rawmidi_block_mode(void *handle, int enable);
 int snd_rawmidi_info(void *handle, snd_rawmidi_info_t * info);
-int snd_rawmidi_output_switches(void *handle);
-int snd_rawmidi_output_switch(void *handle, const char *switch_id);
-int snd_rawmidi_output_switch_read(void *handle, int switchn, snd_rawmidi_switch_t * data);
-int snd_rawmidi_output_switch_write(void *handle, int switchn, snd_rawmidi_switch_t * data);
-int snd_rawmidi_input_switches(void *handle);
-int snd_rawmidi_input_switch(void *handle, const char *switch_id);
-int snd_rawmidi_input_switch_read(void *handle, int switchn, snd_rawmidi_switch_t * data);
-int snd_rawmidi_input_switch_write(void *handle, int switchn, snd_rawmidi_switch_t * data);
+int snd_rawmidi_output_switch_list(void *handle, snd_switch_list_t * list);
+int snd_rawmidi_output_switch_read(void *handle, snd_switch_t * sw);
+int snd_rawmidi_output_switch_write(void *handle, snd_switch_t * sw);
+int snd_rawmidi_input_switch_list(void *handle, snd_switch_list_t * list);
+int snd_rawmidi_input_switch_read(void *handle, snd_switch_t * sw);
+int snd_rawmidi_input_switch_write(void *handle, snd_switch_t * sw);
 int snd_rawmidi_output_params(void *handle, snd_rawmidi_output_params_t * params);
 int snd_rawmidi_input_params(void *handle, snd_rawmidi_input_params_t * params);
 int snd_rawmidi_output_status(void *handle, snd_rawmidi_output_status_t * status);
index ef4571f98c3fe5d15248bc184461b43c471af06e..39840948645b976f9d909bab40416a9bdb0b3869 100644 (file)
@@ -107,64 +107,38 @@ int snd_ctl_hw_info(void *handle, struct snd_ctl_hw_info *info)
        return 0;
 }
 
-int snd_ctl_switches(void *handle)
+int snd_ctl_switch_list(void *handle, snd_switch_list_t *list)
 {
        snd_ctl_t *ctl;
-       int result;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl)
+       if (!ctl || !list)
                return -EINVAL;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_SWITCHES, &result) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_SWITCH_LIST, list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_ctl_switch(void *handle, const char *switch_id)
-{
-       snd_ctl_t *ctl;
-       struct snd_ctl_switch uswitch;
-       int idx, switches, err;
-
-       ctl = (snd_ctl_t *) handle;
-       if (!ctl || !switch_id)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_ctl_t structure */
-       if ((switches = snd_ctl_switches(handle)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_ctl_switch_read(handle, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_ctl_switch_read(void *handle, int switchn, snd_ctl_switch_t *data)
+int snd_ctl_switch_read(void *handle, snd_switch_t *sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || switchn < 0)
+       if (!ctl || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_ctl_switch_t));
-       data->switchn = switchn;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_SWITCH_READ, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_SWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_ctl_switch_write(void *handle, int switchn, snd_ctl_switch_t *data)
+int snd_ctl_switch_write(void *handle, snd_switch_t *sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || switchn < 0)
+       if (!ctl || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_SWITCH_WRITE, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_SWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
@@ -211,138 +185,86 @@ int snd_ctl_pcm_record_info(void *handle, int dev, snd_pcm_record_info_t * info)
        return 0;
 }
 
-int snd_ctl_pcm_playback_switches(void *handle, int dev)
+int snd_ctl_pcm_playback_switch_list(void *handle, int dev, snd_switch_list_t *list)
 {
        snd_ctl_t *ctl;
-       int result;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || dev < 0)
+       if (!ctl || dev < 0 || !list)
                return -EINVAL;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_PSWITCHES, &result) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_PSWITCH_LIST, list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_ctl_pcm_playback_switch(void *handle, int dev, const char *switch_id)
-{
-       snd_ctl_t *ctl;
-       snd_pcm_switch_t uswitch;
-       int idx, switches, err;
-
-       ctl = (snd_ctl_t *) handle;
-       if (!ctl || !switch_id || dev < 0)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_ctl_t structure */
-       if ((switches = snd_ctl_pcm_playback_switches(handle, dev)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_ctl_pcm_playback_switch_read(handle, dev, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_ctl_pcm_playback_switch_read(void *handle, int dev, int switchn, snd_pcm_switch_t * data)
+int snd_ctl_pcm_playback_switch_read(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_pcm_switch_t));
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_PSWITCH_READ, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_PSWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_ctl_pcm_playback_switch_write(void *handle, int dev, int switchn, snd_pcm_switch_t * data)
+int snd_ctl_pcm_playback_switch_write(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_PSWITCH_WRITE, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_PSWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_ctl_pcm_record_switches(void *handle, int dev)
+int snd_ctl_pcm_record_switch_list(void *handle, int dev, snd_switch_list_t * list)
 {
        snd_ctl_t *ctl;
-       int result;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || dev < 0)
+       if (!ctl || !list || dev < 0)
                return -EINVAL;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_RSWITCHES, &result) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_RSWITCH_LIST, list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_ctl_pcm_record_switch(void *handle, int dev, const char *switch_id)
-{
-       snd_ctl_t *ctl;
-       snd_pcm_switch_t uswitch;
-       int idx, switches, err;
-
-       ctl = (snd_ctl_t *) handle;
-       if (!ctl || !switch_id || dev < 0)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_ctl_t structure */
-       if ((switches = snd_ctl_pcm_record_switches(handle, dev)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_ctl_pcm_record_switch_read(handle, dev, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_ctl_pcm_record_switch_read(void *handle, int dev, int switchn, snd_pcm_switch_t * data)
+int snd_ctl_pcm_record_switch_read(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_pcm_switch_t));
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_RSWITCH_READ, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_RSWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_ctl_pcm_record_switch_write(void *handle, int dev, int switchn, snd_pcm_switch_t * data)
+int snd_ctl_pcm_record_switch_write(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_RSWITCH_WRITE, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_RSWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
@@ -361,70 +283,44 @@ int snd_ctl_mixer_info(void *handle, int dev, snd_mixer_info_t * info)
        return 0;
 }
 
-int snd_ctl_mixer_switches(void *handle, int dev)
+int snd_ctl_mixer_switch_list(void *handle, int dev, snd_switch_list_t * list)
 {
        snd_ctl_t *ctl;
-       int result;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || dev < 0)
+       if (!ctl || !list || dev < 0)
                return -EINVAL;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_SWITCHES, &result) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_SWITCH_LIST, list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_ctl_mixer_switch(void *handle, int dev, const char *switch_id)
-{
-       snd_ctl_t *ctl;
-       snd_mixer_switch_t uswitch;
-       int idx, switches, err;
-
-       ctl = (snd_ctl_t *) handle;
-       if (!ctl || !switch_id || dev < 0)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_ctl_t structure */
-       if ((switches = snd_ctl_mixer_switches(handle, dev)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_ctl_mixer_switch_read(handle, dev, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_ctl_mixer_switch_read(void *handle, int dev, int switchn, snd_mixer_switch_t * data)
+int snd_ctl_mixer_switch_read(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_mixer_switch_t));
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_SWITCH_READ, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_SWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_ctl_mixer_switch_write(void *handle, int dev, int switchn, snd_mixer_switch_t * data)
+int snd_ctl_mixer_switch_write(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_SWITCH_WRITE, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_SWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
@@ -471,138 +367,86 @@ int snd_ctl_rawmidi_input_info(void *handle, int dev, snd_rawmidi_input_info_t *
        return 0;
 }
 
-int snd_ctl_rawmidi_output_switches(void *handle, int dev)
+int snd_ctl_rawmidi_output_switch_list(void *handle, int dev, snd_switch_list_t *list)
 {
        snd_ctl_t *ctl;
-       int result;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || dev < 0)
+       if (!ctl || !list || dev < 0)
                return -EINVAL;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_OSWITCHES, &result) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_OSWITCH_LIST, list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_ctl_rawmidi_output_switch(void *handle, int dev, const char *switch_id)
-{
-       snd_ctl_t *ctl;
-       snd_rawmidi_switch_t uswitch;
-       int idx, switches, err;
-
-       ctl = (snd_ctl_t *) handle;
-       if (!ctl || !switch_id || dev < 0)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_ctl_t structure */
-       if ((switches = snd_ctl_rawmidi_output_switches(handle, dev)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_ctl_rawmidi_output_switch_read(handle, dev, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_ctl_rawmidi_output_switch_read(void *handle, int dev, int switchn, snd_rawmidi_switch_t * data)
+int snd_ctl_rawmidi_output_switch_read(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_rawmidi_switch_t));
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_OSWITCH_READ, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_OSWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_ctl_rawmidi_output_switch_write(void *handle, int dev, int switchn, snd_rawmidi_switch_t * data)
+int snd_ctl_rawmidi_output_switch_write(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_OSWITCH_WRITE, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_OSWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_ctl_rawmidi_input_switches(void *handle, int dev)
+int snd_ctl_rawmidi_input_switch_list(void *handle, int dev, snd_switch_list_t *list)
 {
        snd_ctl_t *ctl;
-       int result;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || dev < 0)
+       if (!ctl || !list || dev < 0)
                return -EINVAL;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_ISWITCHES, &result) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_ISWITCH_LIST, list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_ctl_rawmidi_input_switch(void *handle, int dev, const char *switch_id)
-{
-       snd_ctl_t *ctl;
-       snd_rawmidi_switch_t uswitch;
-       int idx, switches, err;
-
-       ctl = (snd_ctl_t *) handle;
-       if (!ctl || !switch_id || dev < 0)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_ctl_t structure */
-       if ((switches = snd_ctl_rawmidi_input_switches(handle, dev)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_ctl_rawmidi_input_switch_read(handle, dev, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_ctl_rawmidi_input_switch_read(void *handle, int dev, int switchn, snd_rawmidi_switch_t * data)
+int snd_ctl_rawmidi_input_switch_read(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_rawmidi_switch_t));
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_ISWITCH_READ, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_ISWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_ctl_rawmidi_input_switch_write(void *handle, int dev, int switchn, snd_rawmidi_switch_t * data)
+int snd_ctl_rawmidi_input_switch_write(void *handle, int dev, snd_switch_t * sw)
 {
        snd_ctl_t *ctl;
 
        ctl = (snd_ctl_t *) handle;
-       if (!ctl || !data || dev < 0 || switchn < 0)
+       if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
        if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_DEVICE, &dev) < 0)
                return -errno;
-       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_ISWITCH_WRITE, data) < 0)
+       if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_ISWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
index 630e9f193b8e40069fe3bdce15f451a0f5f3f8b4..3ded577aa2f65f2e53efe78469d7cf62ef61543f 100644 (file)
@@ -275,64 +275,38 @@ int snd_mixer_channel_input_write(void *handle, int channel, snd_mixer_channel_d
        return 0;
 }
 
-int snd_mixer_switches(void *handle)
+int snd_mixer_switch_list(void *handle, snd_switch_list_t * list)
 {
        snd_mixer_t *mixer;
-       int result;
 
        mixer = (snd_mixer_t *) handle;
-       if (!mixer)
+       if (!mixer || !list)
                return -EINVAL;
-       if (ioctl(mixer->fd, SND_MIXER_IOCTL_SWITCHES, &result) < 0)
+       if (ioctl(mixer->fd, SND_MIXER_IOCTL_SWITCH_LIST, &list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_mixer_switch(void *handle, const char *switch_id)
-{
-       snd_mixer_t *mixer;
-       snd_mixer_switch_t uswitch;
-       int idx, switches, err;
-
-       mixer = (snd_mixer_t *) handle;
-       if (!mixer || !switch_id)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_mixer_t structure */
-       if ((switches = snd_mixer_switches(handle)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_mixer_switch_read(handle, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_mixer_switch_read(void *handle, int switchn, snd_mixer_switch_t * data)
+int snd_mixer_switch_read(void *handle, snd_switch_t * sw)
 {
        snd_mixer_t *mixer;
 
        mixer = (snd_mixer_t *) handle;
-       if (!mixer || !data || switchn < 0)
+       if (!mixer || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_mixer_switch_t));
-       data->switchn = switchn;
-       if (ioctl(mixer->fd, SND_MIXER_IOCTL_SWITCH_READ, data) < 0)
+       if (ioctl(mixer->fd, SND_MIXER_IOCTL_SWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_mixer_switch_write(void *handle, int switchn, snd_mixer_switch_t * data)
+int snd_mixer_switch_write(void *handle, snd_switch_t * sw)
 {
        snd_mixer_t *mixer;
 
        mixer = (snd_mixer_t *) handle;
-       if (!mixer || !data || switchn < 0)
+       if (!mixer || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
-       if (ioctl(mixer->fd, SND_MIXER_IOCTL_SWITCH_WRITE, data) < 0)
+       if (ioctl(mixer->fd, SND_MIXER_IOCTL_SWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
index 703e4c196e8e774f584671905b283a5b32632ca6..262ce9af23d871e4a9f3d68a13afc4c574f698ab 100644 (file)
@@ -151,126 +151,74 @@ int snd_pcm_record_info(void *handle, snd_pcm_record_info_t * info)
        return 0;
 }
 
-int snd_pcm_playback_switches(void *handle)
+int snd_pcm_playback_switch_list(void *handle, snd_switch_list_t * list)
 {
        snd_pcm_t *pcm;
-       int result;
 
        pcm = (snd_pcm_t *) handle;
-       if (!pcm)
+       if (!pcm || !list)
                return -EINVAL;
-       if (ioctl(pcm->fd, SND_PCM_IOCTL_PSWITCHES, &result) < 0)
+       if (ioctl(pcm->fd, SND_PCM_IOCTL_PSWITCH_LIST, &list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_pcm_playback_switch(void *handle, const char *switch_id)
-{
-       snd_pcm_t *pcm;
-       snd_pcm_switch_t uswitch;
-       int idx, switches, err;
-
-       pcm = (snd_pcm_t *) handle;
-       if (!pcm || !switch_id)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_mixer_t structure */
-       if ((switches = snd_pcm_playback_switches(handle)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_pcm_playback_switch_read(handle, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_pcm_playback_switch_read(void *handle, int switchn, snd_pcm_switch_t * data)
+int snd_pcm_playback_switch_read(void *handle, snd_switch_t * sw)
 {
        snd_pcm_t *pcm;
 
        pcm = (snd_pcm_t *) handle;
-       if (!pcm || !data || switchn < 0)
+       if (!pcm || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_pcm_switch_t));
-       data->switchn = switchn;
-       if (ioctl(pcm->fd, SND_PCM_IOCTL_PSWITCH_READ, data) < 0)
+       if (ioctl(pcm->fd, SND_PCM_IOCTL_PSWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_pcm_playback_switch_write(void *handle, int switchn, snd_pcm_switch_t * data)
+int snd_pcm_playback_switch_write(void *handle, snd_switch_t * sw)
 {
        snd_pcm_t *pcm;
 
        pcm = (snd_pcm_t *) handle;
-       if (!pcm || !data || switchn < 0)
+       if (!pcm || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
-       if (ioctl(pcm->fd, SND_PCM_IOCTL_PSWITCH_WRITE, data) < 0)
+       if (ioctl(pcm->fd, SND_PCM_IOCTL_PSWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_pcm_record_switches(void *handle)
+int snd_pcm_record_switch_list(void *handle, snd_switch_list_t * list)
 {
        snd_pcm_t *pcm;
-       int result;
 
        pcm = (snd_pcm_t *) handle;
-       if (!pcm)
+       if (!pcm || !list)
                return -EINVAL;
-       if (ioctl(pcm->fd, SND_PCM_IOCTL_RSWITCHES, &result) < 0)
+       if (ioctl(pcm->fd, SND_PCM_IOCTL_RSWITCH_LIST, list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_pcm_record_switch(void *handle, const char *switch_id)
-{
-       snd_pcm_t *pcm;
-       snd_pcm_switch_t uswitch;
-       int idx, switches, err;
-
-       pcm = (snd_pcm_t *) handle;
-       if (!pcm || !switch_id)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_mixer_t structure */
-       if ((switches = snd_pcm_record_switches(handle)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_pcm_record_switch_read(handle, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_pcm_record_switch_read(void *handle, int switchn, snd_pcm_switch_t * data)
+int snd_pcm_record_switch_read(void *handle, snd_switch_t * sw)
 {
        snd_pcm_t *pcm;
 
        pcm = (snd_pcm_t *) handle;
-       if (!pcm || !data || switchn < 0)
+       if (!pcm || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_pcm_switch_t));
-       data->switchn = switchn;
-       if (ioctl(pcm->fd, SND_PCM_IOCTL_RSWITCH_READ, data) < 0)
+       if (ioctl(pcm->fd, SND_PCM_IOCTL_RSWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_pcm_record_switch_write(void *handle, int switchn, snd_pcm_switch_t * data)
+int snd_pcm_record_switch_write(void *handle, snd_switch_t * sw)
 {
        snd_pcm_t *pcm;
 
        pcm = (snd_pcm_t *) handle;
-       if (!pcm || !data || switchn < 0)
+       if (!pcm || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
-       if (ioctl(pcm->fd, SND_PCM_IOCTL_RSWITCH_WRITE, data) < 0)
+       if (ioctl(pcm->fd, SND_PCM_IOCTL_RSWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
index 3986cedfc16bbd5af2ddfaf0d89dba5adcc5f5fe..95910af1d7fd696facac5e2a40c2f4d2147f3d58 100644 (file)
@@ -127,126 +127,74 @@ int snd_rawmidi_info(void *handle, snd_rawmidi_info_t * info)
        return 0;
 }
 
-int snd_rawmidi_output_switches(void *handle)
+int snd_rawmidi_output_switch_list(void *handle, snd_switch_list_t * list)
 {
        snd_rawmidi_t *rmidi;
-       int result;
 
        rmidi = (snd_rawmidi_t *) handle;
-       if (!rmidi)
+       if (!rmidi || !list)
                return -EINVAL;
-       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_OSWITCHES, &result) < 0)
+       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_OSWITCH_LIST, list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_rawmidi_output_switch(void *handle, const char *switch_id)
-{
-       snd_rawmidi_t *rmidi;
-       snd_rawmidi_switch_t uswitch;
-       int idx, switches, err;
-
-       rmidi = (snd_rawmidi_t *) handle;
-       if (!rmidi || !switch_id)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_mixer_t structure */
-       if ((switches = snd_rawmidi_output_switches(handle)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_rawmidi_output_switch_read(handle, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_rawmidi_output_switch_read(void *handle, int switchn, snd_rawmidi_switch_t * data)
+int snd_rawmidi_output_switch_read(void *handle, snd_switch_t * sw)
 {
        snd_rawmidi_t *rmidi;
 
        rmidi = (snd_rawmidi_t *) handle;
-       if (!rmidi || !data || switchn < 0)
+       if (!rmidi || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_rawmidi_switch_t));
-       data->switchn = switchn;
-       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_OSWITCH_READ, data) < 0)
+       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_OSWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_rawmidi_output_switch_write(void *handle, int switchn, snd_rawmidi_switch_t * data)
+int snd_rawmidi_output_switch_write(void *handle, snd_switch_t * sw)
 {
        snd_rawmidi_t *rmidi;
 
        rmidi = (snd_rawmidi_t *) handle;
-       if (!rmidi || !data || switchn < 0)
+       if (!rmidi || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
-       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_OSWITCH_WRITE, data) < 0)
+       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_OSWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_rawmidi_input_switches(void *handle)
+int snd_rawmidi_input_switch_list(void *handle, snd_switch_list_t * list)
 {
        snd_rawmidi_t *rmidi;
-       int result;
 
        rmidi = (snd_rawmidi_t *) handle;
        if (!rmidi)
                return -EINVAL;
-       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_ISWITCHES, &result) < 0)
+       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_ISWITCH_LIST, list) < 0)
                return -errno;
-       return result;
-}
-
-int snd_rawmidi_input_switch(void *handle, const char *switch_id)
-{
-       snd_rawmidi_t *rmidi;
-       snd_rawmidi_switch_t uswitch;
-       int idx, switches, err;
-
-       rmidi = (snd_rawmidi_t *) handle;
-       if (!rmidi || !switch_id)
-               return -EINVAL;
-       /* bellow implementation isn't optimized for speed */
-       /* info about switches should be cached in the snd_mixer_t structure */
-       if ((switches = snd_rawmidi_input_switches(handle)) < 0)
-               return switches;
-       for (idx = 0; idx < switches; idx++) {
-               if ((err = snd_rawmidi_input_switch_read(handle, idx, &uswitch)) < 0)
-                       return err;
-               if (!strncmp(switch_id, uswitch.name, sizeof(uswitch.name)))
-                       return idx;
-       }
-       return -EINVAL;
+       return 0;
 }
 
-int snd_rawmidi_input_switch_read(void *handle, int switchn, snd_rawmidi_switch_t * data)
+int snd_rawmidi_input_switch_read(void *handle, snd_switch_t * sw)
 {
        snd_rawmidi_t *rmidi;
 
        rmidi = (snd_rawmidi_t *) handle;
-       if (!rmidi || !data || switchn < 0)
+       if (!rmidi || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       bzero(data, sizeof(snd_rawmidi_switch_t));
-       data->switchn = switchn;
-       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_ISWITCH_READ, data) < 0)
+       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_ISWITCH_READ, sw) < 0)
                return -errno;
        return 0;
 }
 
-int snd_rawmidi_input_switch_write(void *handle, int switchn, snd_rawmidi_switch_t * data)
+int snd_rawmidi_input_switch_write(void *handle, snd_switch_t * sw)
 {
        snd_rawmidi_t *rmidi;
 
        rmidi = (snd_rawmidi_t *) handle;
-       if (!rmidi || !data || switchn < 0)
+       if (!rmidi || !sw || sw->name[0] == '\0')
                return -EINVAL;
-       data->switchn = switchn;
-       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_ISWITCH_WRITE, data) < 0)
+       if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_ISWITCH_WRITE, sw) < 0)
                return -errno;
        return 0;
 }
index 67ac87bf4dc85ae05caf44b26f84ed27c8bd0672..898a3643fbefbb537b8c7a4206b94830846586b0 100644 (file)
 #include <stdio.h>
 #include <string.h>
+#include <malloc.h>
+#include <errno.h>
 #include "../include/asoundlib.h"
 
+static void *ctl_handle;
+static int sw_interface;
+static int sw_device;
+
 const char *get_type(unsigned int type)
 {
        switch (type) {
-       case 0:
+       case SND_SW_TYPE_BOOLEAN:
                return "Boolean";
-       case 1:
+       case SND_SW_TYPE_BYTE:
                return "Byte";
-       case 2:
+       case SND_SW_TYPE_WORD:
                return "Word";
-       case 3:
-               return "DWord";
-       case 4:
+       case SND_SW_TYPE_DWORD:
+               return "Double Word";
+       case SND_SW_TYPE_LIST:
+               return "List";
+       case SND_SW_TYPE_LIST_ITEM:
+               return "List Item";
+       case SND_SW_TYPE_USER:
                return "User";
        default:
                return "Unknown";
        }
 }
 
-void main(void)
+const char *get_interface(void)
 {
-       int cards, card, device, direction, idx, count, err;
-       void *handle, *chandle;
-       struct snd_ctl_hw_info info;
-       struct snd_ctl_switch ctl_switch;
-       snd_mixer_switch_t mixer_switch;
-       snd_pcm_info_t pcm_info;
-       snd_pcm_switch_t pcm_switch;
-       snd_rawmidi_switch_t rmidi_switch;
-       snd_rawmidi_info_t rmidi_info;
+       switch (sw_interface) {
+       case 0:
+               return "control";
+       case 1:
+               return "mixer";
+       case 2:
+               return "PCM playback";
+       case 3:
+               return "PCM record";
+       case 4:
+               return "rawmidi output";
+       case 5:
+               return "rawmidi input";
+       default:
+               return "unknown";
+       }
+}
 
-       cards = snd_cards();
-       printf("Detected %i soundcard%s...\n", cards, cards > 1 ? "s" : "");
-       if (cards <= 0) {
-               printf("Giving up...\n");
-               return;
+int switch_list(snd_switch_list_t *list)
+{
+       switch (sw_interface) {
+       case 0:
+               return snd_ctl_switch_list(ctl_handle, list);
+       case 1:
+               return snd_ctl_mixer_switch_list(ctl_handle, sw_device, list);
+       case 2:
+               return snd_ctl_pcm_playback_switch_list(ctl_handle, sw_device, list);
+       case 3:
+               return snd_ctl_pcm_record_switch_list(ctl_handle, sw_device, list);
+       case 4:
+               return snd_ctl_rawmidi_output_switch_list(ctl_handle, sw_device, list);
+       case 5:
+               return snd_ctl_rawmidi_input_switch_list(ctl_handle, sw_device, list);
+       default:
+               return -ENOLINK;
        }
-       /* control interface */
-       for (card = 0; card < cards; card++) {
-               if ((err = snd_ctl_open(&handle, card)) < 0) {
-                       printf("CTL open error: %s\n", snd_strerror(err));
-                       continue;
-               }
-               if ((err = snd_ctl_hw_info(handle, &info)) < 0) {
-                       printf("CTL hw info error: %s\n", snd_strerror(err));
-                       continue;
-               }
-               if ((count = snd_ctl_switches(handle)) < 0) {
-                       printf("CTL switches error: %s\n", snd_strerror(count));
-                       continue;
-               }
-               for (idx = 0; idx < count; idx++) {
-                       if ((err = snd_ctl_switch_read(handle, idx, &ctl_switch)) < 0) {
-                               printf("CTL switch read error: %s\n", snd_strerror(count));
-                               continue;
-                       }
-                       printf("CTL switch: '%s' %s (%i-%i)\n", ctl_switch.name, get_type(ctl_switch.type), ctl_switch.low, ctl_switch.high);
-                       if ((err = snd_ctl_switch_write(handle, idx, &ctl_switch)) < 0) {
-                               printf("CTL switch write error: %s\n", snd_strerror(count));
-                               continue;
-                       }
-               }
-               if (count <= 0)
-                       printf("No CTL switches detected for soundcard #%i '%s'...\n", idx, info.name);
-               snd_ctl_close(handle);
+}
+
+int switch_read(snd_switch_t *sw)
+{
+       switch (sw_interface) {
+       case 0:
+               return snd_ctl_switch_read(ctl_handle, sw);
+       case 1:
+               return snd_ctl_mixer_switch_read(ctl_handle, sw_device, sw);
+       case 2:
+               return snd_ctl_pcm_playback_switch_read(ctl_handle, sw_device, sw);
+       case 3:
+               return snd_ctl_pcm_record_switch_write(ctl_handle, sw_device, sw);
+       case 4:
+               return snd_ctl_rawmidi_output_switch_read(ctl_handle, sw_device, sw);
+       case 5:
+               return snd_ctl_rawmidi_input_switch_read(ctl_handle, sw_device, sw);
+       default:
+               return -ENOLINK;
        }
+}
 
-       /* mixer interface */
-       for (card = 0; card < cards; card++) {
-               if ((err = snd_ctl_open(&handle, card)) < 0) {
-                       printf("CTL open error: %s\n", snd_strerror(err));
-                       continue;
-               }
-               if ((err = snd_ctl_hw_info(handle, &info)) < 0) {
-                       printf("CTL hw info error: %s\n", snd_strerror(err));
-                       continue;
-               }
-               snd_ctl_close(handle);
-               for (device = 0; device < info.mixerdevs; device++) {
-                       if ((err = snd_mixer_open(&handle, card, device)) < 0) {
-                               printf("Mixer open error: %s\n", snd_strerror(err));
-                               continue;
-                       }
-                       if ((count = snd_mixer_switches(handle)) < 0) {
-                               printf("Mixer switches error: %s\n", snd_strerror(count));
+int switch_write(snd_switch_t *sw)
+{
+       switch (sw_interface) {
+       case 0:
+               return snd_ctl_switch_write(ctl_handle, sw);
+       case 1:
+               return snd_ctl_mixer_switch_write(ctl_handle, sw_device, sw);
+       case 2:
+               return snd_ctl_pcm_playback_switch_write(ctl_handle, sw_device, sw);
+       case 3:
+               return snd_ctl_pcm_record_switch_write(ctl_handle, sw_device, sw);
+       case 4:
+               return snd_ctl_rawmidi_output_switch_write(ctl_handle, sw_device, sw);
+       case 5:
+               return snd_ctl_rawmidi_input_switch_write(ctl_handle, sw_device, sw);
+       default:
+               return -ENOLINK;
+       }
+} 
+
+void print_switch(char *space, char *prefix, snd_switch_t *sw)
+{
+       snd_switch_t sw1;
+       int low, err;
+
+       printf("%s%s : '%s' [%s]\n", space, prefix, sw->name, get_type(sw->type));
+       if (sw->type == SND_SW_TYPE_LIST) {
+               for (low = sw->low; low <= sw->high; low++) {
+                       memcpy(&sw1, sw,  sizeof(sw1));
+                       sw1.type = SND_SW_TYPE_LIST_ITEM;
+                       sw1.low = sw1.high = low;
+                       if ((err = switch_read(&sw1)) < 0) {
+                               printf("Switch list item read failed for %s interface and device %i: %s\n", get_interface(), sw_device, snd_strerror(err));
                                continue;
                        }
-                       for (idx = 0; idx < count; idx++) {
-                               if ((err = snd_mixer_switch_read(handle, idx, &mixer_switch)) < 0) {
-                                       printf("Mixer switch read error: %s\n", snd_strerror(count));
-                                       continue;
-                               }
-                               printf("Mixer switch: '%s' %s (%i-%i)\n", mixer_switch.name, get_type(mixer_switch.type), mixer_switch.low, mixer_switch.high);
-                               if ((err = snd_mixer_switch_write(handle, idx, &mixer_switch)) < 0) {
-                                       printf("Mixer switch write error: %s\n", snd_strerror(count));
-                                       continue;
-                               }
-                       }
-                       if (count <= 0)
-                               printf("No mixer switches detected for soundcard #%i '%s'...\n", idx, info.name);
-                       snd_mixer_close(handle);
+                       printf("  %s%s : '%s' [%s] {%s}\n", space, prefix, sw1.name, get_type(sw1.type), sw1.value.item);
                }
        }
+}
 
-       /* pcm switches */
-       for (card = 0; card < cards; card++) {
-               if ((err = snd_ctl_open(&chandle, card)) < 0) {
-                       printf("CTL open error: %s\n", snd_strerror(err));
-                       continue;
-               }
-               if ((err = snd_ctl_hw_info(chandle, &info)) < 0) {
-                       printf("CTL hw info error: %s\n", snd_strerror(err));
-                       continue;
-               }
-               for (device = 0; device < info.pcmdevs; device++) {
-                       if ((err = snd_ctl_pcm_info(chandle, device, &pcm_info)) < 0) {
-                               printf("CTL PCM info error: %s\n", snd_strerror(err));
-                               continue;
-                       }
-                       for (direction = 0; direction < 2; direction++) {
-                               int (*switches) (void *handle);
-                               int (*switch_read) (void *handle, int switchn, snd_pcm_switch_t * data);
-                               int (*switch_write) (void *handle, int switchn, snd_pcm_switch_t * data);
-                               char *str;
+void process(char *space, char *prefix, int interface, int device)
+{
+       snd_switch_list_t list;
+       snd_switch_t sw;
+       int err, idx;
 
-                               if (!(pcm_info.flags & (!direction ? SND_PCM_INFO_PLAYBACK : SND_PCM_INFO_RECORD)))
-                                       continue;
-                               if ((err = snd_pcm_open(&handle, card, device, !direction ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_RECORD)) < 0) {
-                                       printf("PCM open error: %s\n", snd_strerror(err));
-                                       continue;
-                               }
-                               if (!direction) {
-                                       switches = snd_pcm_playback_switches;
-                                       switch_read = snd_pcm_playback_switch_read;
-                                       switch_write = snd_pcm_playback_switch_write;
-                                       str = "playback";
-                               } else {
-                                       switches = snd_pcm_record_switches;
-                                       switch_read = snd_pcm_record_switch_read;
-                                       switch_write = snd_pcm_record_switch_write;
-                                       str = "record";
-                               }
-                               if ((count = switches(handle)) < 0) {
-                                       printf("PCM %s switches error: %s\n", str, snd_strerror(count));
-                                       continue;
-                               }
-                               for (idx = 0; idx < count; idx++) {
-                                       if ((err = switch_read(handle, idx, &pcm_switch)) < 0) {
-                                               printf("PCM %s switch read error: %s\n", str, snd_strerror(count));
-                                               continue;
-                                       }
-                                       printf("PCM switch: '%s' %s (%i-%i)\n", pcm_switch.name, get_type(pcm_switch.type), pcm_switch.low, pcm_switch.high);
-                                       if ((err = switch_write(handle, idx, &pcm_switch)) < 0) {
-                                               printf("PCM %s switch write error: %s\n", str, snd_strerror(count));
-                                               continue;
-                                       }
-                               }
-                               if (count <= 0)
-                                       printf("No PCM %s switches detected for soundcard #%i/#%i '%s'/'%s'...\n", str, idx, device, info.name, pcm_info.name);
-                               snd_pcm_close(handle);
-                       }
+       sw_interface = interface;
+       sw_device = device;
+       bzero(&list, sizeof(list));
+       if ((err = switch_list(&list)) < 0) {
+               printf("Switch listing failed for the %s interface and the device %i: %s\n", get_interface(), device, snd_strerror(err));
+               return;
+       }
+       if (list.switches_over <= 0)
+               return;
+       list.switches_size = list.switches_over + 16;
+       list.switches = list.switches_over = 0;
+       list.pswitches = malloc(sizeof(snd_switch_list_item_t) * list.switches_size);
+       if (!list.pswitches) {
+               printf("No enough memory... (%i switches)\n", list.switches_size);
+               return;
+       }
+       if ((err = switch_list(&list)) < 0) {
+               printf("Second switch listing failed for the %s interface and the device %i: %s\n", get_interface(), device, snd_strerror(err));
+               return;
+       }
+       for (idx = 0; idx < list.switches; idx++) {
+               bzero(&sw, sizeof(sw));
+               strncpy(sw.name, list.pswitches[idx].name, sizeof(sw.name));
+               if ((err = switch_read(&sw)) < 0) {
+                       printf("Switch read failed for the %s interface and the device %i: %s\n", get_interface(), device, snd_strerror(err));
+                       continue;
                }
-               snd_ctl_close(chandle);
+               print_switch(space, prefix, &sw);
        }
+       free(list.pswitches);
+}
+
+void main(void)
+{
+       int cards, card, err, idx;
+       snd_ctl_hw_info_t info;
 
-       /* rawmidi switches */
+       cards = snd_cards();
+       printf("Detected %i soundcard%s...\n", cards, cards > 1 ? "s" : "");
+       if (cards <= 0) {
+               printf("Giving up...\n");
+               return;
+       }
+       /* control interface */
        for (card = 0; card < cards; card++) {
-               if ((err = snd_ctl_open(&chandle, card)) < 0) {
+               if ((err = snd_ctl_open(&ctl_handle, card)) < 0) {
                        printf("CTL open error: %s\n", snd_strerror(err));
                        continue;
                }
-               if ((err = snd_ctl_hw_info(chandle, &info)) < 0) {
-                       printf("CTL hw info error: %s\n", snd_strerror(err));
+               if ((err = snd_ctl_hw_info(ctl_handle, &info)) < 0) {
+                       printf("HWINFO error: %s\n", snd_strerror(err));
                        continue;
                }
-               for (device = 0; device < info.mididevs; device++) {
-                       if ((err = snd_ctl_rawmidi_info(chandle, device, &rmidi_info)) < 0) {
-                               printf("CTL RawMIDI info error: %s\n", snd_strerror(err));
-                               continue;
-                       }
-                       for (direction = 0; direction < 2; direction++) {
-                               int (*switches) (void *handle);
-                               int (*switch_read) (void *handle, int switchn, snd_rawmidi_switch_t * data);
-                               int (*switch_write) (void *handle, int switchn, snd_rawmidi_switch_t * data);
-                               char *str;
-
-                               if (!(pcm_info.flags & (!direction ? SND_RAWMIDI_INFO_OUTPUT : SND_RAWMIDI_INFO_INPUT)))
-                                       continue;
-                               if ((err = snd_rawmidi_open(&handle, card, device, !direction ? SND_RAWMIDI_OPEN_OUTPUT : SND_RAWMIDI_OPEN_INPUT)) < 0) {
-                                       printf("RawMIDI CTL open error: %s\n", snd_strerror(err));
-                                       continue;
-                               }
-                               if (!direction) {
-                                       switches = snd_rawmidi_output_switches;
-                                       switch_read = snd_rawmidi_output_switch_read;
-                                       switch_write = snd_rawmidi_output_switch_write;
-                                       str = "output";
-                               } else {
-                                       switches = snd_rawmidi_input_switches;
-                                       switch_read = snd_rawmidi_input_switch_read;
-                                       switch_write = snd_rawmidi_input_switch_write;
-                                       str = "input";
-                               }
-                               if ((count = switches(handle)) < 0) {
-                                       printf("RawMIDI %s switches error: %s\n", str, snd_strerror(count));
-                                       continue;
-                               }
-                               for (idx = 0; idx < count; idx++) {
-                                       if ((err = switch_read(handle, idx, &rmidi_switch)) < 0) {
-                                               printf("RawMIDI %s switch read error: %s\n", str, snd_strerror(count));
-                                               continue;
-                                       }
-                                       printf("RawMIDI switch: '%s' %s (%i-%i)\n", rmidi_switch.name, get_type(rmidi_switch.type), rmidi_switch.low, rmidi_switch.high);
-                                       if ((err = switch_write(handle, idx, &rmidi_switch)) < 0) {
-                                               printf("RawMIDI %s switch write error: %s\n", str, snd_strerror(count));
-                                               continue;
-                                       }
-                               }
-                               if (count <= 0)
-                                       printf("No RawMIDI %s switches detected for soundcard #%i/#%i '%s'/'%s'...\n", str, idx, device, info.name, rmidi_info.name);
-                               snd_rawmidi_close(handle);
-                       }
+               printf("CARD %i:\n", card);
+               process("  ", "Control", 0, 0);
+               for (idx = 0; idx < info.mixerdevs; idx++)
+                       process("  ", "Mixer", 1, idx);
+               for (idx = 0; idx < info.pcmdevs; idx++) {
+                       process("  ", "PCM playback", 2, idx);
+                       process("  ", "PCM record", 3, idx);
                }
-               snd_ctl_close(chandle);
+               snd_ctl_close(ctl_handle);
        }
-
 }