From 3f541735e3c99abff0120827ce0a0be54838f2d6 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sat, 27 Mar 1999 19:44:51 +0000 Subject: [PATCH] New universal switch v2.0 interface. --- include/control.h | 42 +++-- include/mixer.h | 6 +- include/pcm.h | 14 +- include/rawmidi.h | 14 +- src/control/control.c | 276 +++++++------------------------- src/mixer/mixer.c | 46 ++---- src/pcm/pcm.c | 92 +++-------- src/rawmidi/rawmidi.c | 90 +++-------- test/switches.c | 354 +++++++++++++++++++----------------------- 9 files changed, 305 insertions(+), 629 deletions(-) diff --git a/include/control.h b/include/control.h index c5cd4c09..86cb4c56 100644 --- a/include/control.h +++ b/include/control.h @@ -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 } diff --git a/include/mixer.h b/include/mixer.h index e2db9164..8879f62d 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -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 diff --git a/include/pcm.h b/include/pcm.h index 0509aace..95c2a70f 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -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); diff --git a/include/rawmidi.h b/include/rawmidi.h index ea504014..64250ff9 100644 --- a/include/rawmidi.h +++ b/include/rawmidi.h @@ -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); diff --git a/src/control/control.c b/src/control/control.c index ef4571f9..39840948 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -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; } diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c index 630e9f19..3ded577a 100644 --- a/src/mixer/mixer.c +++ b/src/mixer/mixer.c @@ -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; } diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 703e4c19..262ce9af 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -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; } diff --git a/src/rawmidi/rawmidi.c b/src/rawmidi/rawmidi.c index 3986cedf..95910af1 100644 --- a/src/rawmidi/rawmidi.c +++ b/src/rawmidi/rawmidi.c @@ -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; } diff --git a/test/switches.c b/test/switches.c index 67ac87bf..898a3643 100644 --- a/test/switches.c +++ b/test/switches.c @@ -1,230 +1,202 @@ #include #include +#include +#include #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); } - } -- 2.47.1