Every switches are accessible via one ioctl.
typedef struct snd_ctl_callbacks {
void *private_data; /* should be used by an application */
void (*rebuild) (void *private_data);
- void (*xswitch) (void *private_data, int cmd, int iface, snd_switch_list_item_t *item);
+ void (*xswitch) (void *private_data, int cmd,
+ int iface, int device, int channel,
+ snd_switch_list_item_t *item);
void *reserved[29]; /* reserved for the future use - must be NULL!!! */
} snd_ctl_callbacks_t;
int snd_ctl_pcm_info(snd_ctl_t *handle, int dev, snd_pcm_info_t * info);
int snd_ctl_pcm_channel_info(snd_ctl_t *handle, int dev, int channel, int subdev, snd_pcm_channel_info_t * info);
int snd_ctl_pcm_channel_prefer_subdevice(snd_ctl_t *handle, int dev, int channel, int subdev);
-int snd_ctl_pcm_channel_switch_list(snd_ctl_t *handle, int dev, int channel, snd_switch_list_t * list);
-int snd_ctl_pcm_playback_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t * list);
-int snd_ctl_pcm_capture_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t * list);
-int snd_ctl_pcm_channel_switch_read(snd_ctl_t *handle, int dev, int channel, snd_switch_t * sw);
-int snd_ctl_pcm_playback_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw);
-int snd_ctl_pcm_capture_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw);
-int snd_ctl_pcm_channel_switch_write(snd_ctl_t *handle, int dev, int channel, snd_switch_t * sw);
-int snd_ctl_pcm_playback_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw);
-int snd_ctl_pcm_capture_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw);
int snd_ctl_mixer_info(snd_ctl_t *handle, int dev, snd_mixer_info_t * info);
-int snd_ctl_mixer_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t *list);
-int snd_ctl_mixer_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw);
-int snd_ctl_mixer_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw);
int snd_ctl_rawmidi_info(snd_ctl_t *handle, int dev, snd_rawmidi_info_t * info);
-int snd_ctl_rawmidi_output_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t *list);
-int snd_ctl_rawmidi_output_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw);
-int snd_ctl_rawmidi_output_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw);
-int snd_ctl_rawmidi_input_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t *list);
-int snd_ctl_rawmidi_input_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw);
-int snd_ctl_rawmidi_input_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw);
int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks);
#ifdef __cplusplus
int snd_pcm_plugin_setup(snd_pcm_t *handle, snd_pcm_channel_setup_t *setup);
int snd_pcm_plugin_status(snd_pcm_t *handle, snd_pcm_channel_status_t *status);
int snd_pcm_plugin_prepare(snd_pcm_t *handle, int channel);
-int snd_pcm_plugin_drain_playback(snd_pcm_t *handle);
+int snd_pcm_plugin_playback_drain(snd_pcm_t *handle);
int snd_pcm_plugin_flush(snd_pcm_t *handle, int channel);
int snd_pcm_plugin_pointer(snd_pcm_t *pcm, int channel, void **ptr, size_t *size);
ssize_t snd_pcm_plugin_write(snd_pcm_t *handle, const void *buffer, size_t size);
/*
* Control Interface - main file
- * Copyright (c) 1998 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1998,1999,2000 by Jaroslav Kysela <perex@suse.cz>
*
*
* This library is free software; you can redistribute it and/or modify
return 0;
}
-int snd_ctl_pcm_channel_switch_list(snd_ctl_t *handle, int dev, int chn, snd_switch_list_t *list)
-{
- snd_ctl_t *ctl;
-
- ctl = handle;
- if (!ctl || dev < 0 || chn < 0 || chn > 1 || !list)
- return -EINVAL;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_CHANNEL, &chn) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_SWITCH_LIST, list) < 0)
- return -errno;
- return 0;
-}
-
-int snd_ctl_pcm_playback_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t *list)
-{
- return snd_ctl_pcm_channel_switch_list(handle, dev, SND_PCM_CHANNEL_PLAYBACK, list);
-}
-
-int snd_ctl_pcm_capture_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t *list)
-{
- return snd_ctl_pcm_channel_switch_list(handle, dev, SND_PCM_CHANNEL_CAPTURE, list);
-}
-
-int snd_ctl_pcm_channel_switch_read(snd_ctl_t *handle, int dev, int chn, snd_switch_t * sw)
-{
- snd_ctl_t *ctl;
-
- ctl = handle;
- if (!ctl || !sw || dev < 0 || chn < 0 || chn > 1 || sw->name[0] == '\0')
- return -EINVAL;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_CHANNEL, &chn) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_SWITCH_READ, sw) < 0)
- return -errno;
- return 0;
-}
-
-int snd_ctl_pcm_playback_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- return snd_ctl_pcm_channel_switch_read(handle, dev, SND_PCM_CHANNEL_PLAYBACK, sw);
-}
-
-int snd_ctl_pcm_capture_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- return snd_ctl_pcm_channel_switch_read(handle, dev, SND_PCM_CHANNEL_CAPTURE, sw);
-}
-
-int snd_ctl_pcm_channel_switch_write(snd_ctl_t *handle, int dev, int chn, snd_switch_t * sw)
-{
- snd_ctl_t *ctl;
-
- ctl = handle;
- if (!ctl || !sw || dev < 0 || chn < 0 || chn > 1 || sw->name[0] == '\0')
- return -EINVAL;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_CHANNEL, &chn) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_SWITCH_WRITE, sw) < 0)
- return -errno;
- return 0;
-}
-
-int snd_ctl_pcm_playback_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- return snd_ctl_pcm_channel_switch_write(handle, dev, SND_PCM_CHANNEL_PLAYBACK, sw);
-}
-
-int snd_ctl_pcm_capture_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- return snd_ctl_pcm_channel_switch_write(handle, dev, SND_PCM_CHANNEL_CAPTURE, sw);
-}
-
int snd_ctl_mixer_info(snd_ctl_t *handle, int dev, snd_mixer_info_t * info)
{
snd_ctl_t *ctl;
return 0;
}
-int snd_ctl_mixer_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t * list)
-{
- snd_ctl_t *ctl;
-
- ctl = handle;
- 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_SWITCH_LIST, list) < 0)
- return -errno;
- return 0;
-}
-
-int snd_ctl_mixer_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- snd_ctl_t *ctl;
-
- ctl = handle;
- if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
- return -EINVAL;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_DEVICE, &dev) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_SWITCH_READ, sw) < 0)
- return -errno;
- return 0;
-}
-
-int snd_ctl_mixer_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- snd_ctl_t *ctl;
-
- ctl = handle;
- if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
- return -EINVAL;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_DEVICE, &dev) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_MIXER_SWITCH_WRITE, sw) < 0)
- return -errno;
- return 0;
-}
-
int snd_ctl_rawmidi_info(snd_ctl_t *handle, int dev, snd_rawmidi_info_t * info)
{
snd_ctl_t *ctl;
return 0;
}
-int snd_ctl_rawmidi_channel_switch_list(snd_ctl_t *handle, int dev, int chn, snd_switch_list_t *list)
-{
- snd_ctl_t *ctl;
-
- ctl = handle;
- 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_CHANNEL, &chn) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_SWITCH_LIST, list) < 0)
- return -errno;
- return 0;
-}
-
-int snd_ctl_rawmidi_channel_switch_read(snd_ctl_t *handle, int dev, int chn, snd_switch_t * sw)
-{
- snd_ctl_t *ctl;
-
- ctl = handle;
- if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
- return -EINVAL;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_DEVICE, &dev) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_CHANNEL, &chn) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_SWITCH_READ, sw) < 0)
- return -errno;
- return 0;
-}
-
-int snd_ctl_rawmidi_channel_switch_write(snd_ctl_t *handle, int dev, int chn, snd_switch_t * sw)
-{
- snd_ctl_t *ctl;
-
- ctl = handle;
- if (!ctl || !sw || dev < 0 || sw->name[0] == '\0')
- return -EINVAL;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_DEVICE, &dev) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_CHANNEL, &chn) < 0)
- return -errno;
- if (ioctl(ctl->fd, SND_CTL_IOCTL_RAWMIDI_SWITCH_WRITE, sw) < 0)
- return -errno;
- return 0;
-}
-
-int snd_ctl_rawmidi_output_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t *list)
-{
- return snd_ctl_rawmidi_channel_switch_list(handle, dev, SND_RAWMIDI_CHANNEL_OUTPUT, list);
-}
-
-int snd_ctl_rawmidi_output_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- return snd_ctl_rawmidi_channel_switch_read(handle, dev, SND_RAWMIDI_CHANNEL_OUTPUT, sw);
-}
-
-int snd_ctl_rawmidi_output_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- return snd_ctl_rawmidi_channel_switch_write(handle, dev, SND_RAWMIDI_CHANNEL_OUTPUT, sw);
-}
-
-int snd_ctl_rawmidi_input_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t *list)
-{
- return snd_ctl_rawmidi_channel_switch_list(handle, dev, SND_RAWMIDI_CHANNEL_INPUT, list);
-}
-
-int snd_ctl_rawmidi_input_switch_read(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- return snd_ctl_rawmidi_channel_switch_read(handle, dev, SND_RAWMIDI_CHANNEL_INPUT, sw);
-}
-
-int snd_ctl_rawmidi_input_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw)
-{
- return snd_ctl_rawmidi_channel_switch_write(handle, dev, SND_RAWMIDI_CHANNEL_INPUT, sw);
-}
-
int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks)
{
snd_ctl_t *ctl;
case SND_CTL_READ_SWITCH_ADD:
case SND_CTL_READ_SWITCH_REMOVE:
if (callbacks->xswitch)
- callbacks->xswitch(callbacks->private_data, r.cmd, r.data.sw.iface, &r.data.sw.switem);
+ callbacks->xswitch(callbacks->private_data,
+ r.cmd, r.data.sw.iface,
+ r.data.sw.device,
+ r.data.sw.channel,
+ &r.data.sw.switem);
break;
}
count++;
return snd_pcm_channel_prepare(pcm, channel);
}
-int snd_pcm_plugin_drain_playback(snd_pcm_t *pcm)
+int snd_pcm_plugin_playback_drain(snd_pcm_t *pcm)
{
int err;
#include <errno.h>
#include "../include/asoundlib.h"
-static snd_ctl_t *ctl_handle;
-static int sw_interface;
-static int sw_device;
-
const char *get_type(unsigned int type)
{
switch (type) {
}
}
-const char *get_interface(void)
+const char *get_interface(int iface)
{
- switch (sw_interface) {
- case 0:
+ switch (iface) {
+ case SND_CTL_IFACE_CONTROL:
return "control";
- case 1:
+ case SND_CTL_IFACE_MIXER:
return "mixer";
- case 2:
- return "PCM playback";
- case 3:
- return "PCM capture";
- case 4:
- return "rawmidi output";
- case 5:
- return "rawmidi input";
+ case SND_CTL_IFACE_PCM:
+ return "pcm";
+ case SND_CTL_IFACE_RAWMIDI:
+ return "rawmidi";
default:
return "unknown";
}
}
-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_capture_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;
- }
-}
-
-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_capture_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;
- }
-}
-
-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_capture_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)
+void print_switch(snd_ctl_t *ctl_handle, char *space, char *prefix, snd_switch_t *sw)
{
snd_switch_t sw1;
int low, err;
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));
+ if ((err = snd_ctl_switch_read(ctl_handle, &sw1)) < 0) {
+ printf("Switch list item read failed for %s interface and device %i channel %i: %s\n", get_interface(sw->iface), sw->device, sw->channel, snd_strerror(err));
continue;
}
printf(" %s%s : '%s' [%s] {%s}\n", space, prefix, sw1.name, get_type(sw1.type), sw1.value.item);
}
}
-void process(char *space, char *prefix, int interface, int device)
+void process(snd_ctl_t *ctl_handle, char *space, char *prefix, int iface, int device, int channel)
{
snd_switch_list_t list;
snd_switch_t sw;
int err, idx;
- 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));
+ list.iface = iface;
+ list.device = device;
+ list.channel = channel;
+ if ((err = snd_ctl_switch_list(ctl_handle, &list)) < 0) {
+ printf("Switch listing failed for the %s interface and the device %i: %s\n", get_interface(iface), device, snd_strerror(err));
return;
}
if (list.switches_over <= 0)
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));
+ if ((err = snd_ctl_switch_list(ctl_handle, &list)) < 0) {
+ printf("Second switch listing failed for the %s interface and the device %i: %s\n", get_interface(iface), device, snd_strerror(err));
return;
}
for (idx = 0; idx < list.switches; idx++) {
bzero(&sw, sizeof(sw));
+ sw.iface = iface;
+ sw.device = device;
+ sw.channel = channel;
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));
+ if ((err = snd_ctl_switch_read(ctl_handle, &sw)) < 0) {
+ printf("Switch read failed for the %s interface and the device %i channel %i: %s\n", get_interface(iface), device, channel, snd_strerror(err));
continue;
}
- print_switch(space, prefix, &sw);
+ print_switch(ctl_handle, space, prefix, &sw);
}
free(list.pswitches);
}
int main(void)
{
+ snd_ctl_t *ctl_handle;
int cards, card, err, idx;
snd_ctl_hw_info_t info;
continue;
}
printf("CARD %i:\n", card);
- process(" ", "Control", 0, 0);
+ process(ctl_handle, " ", "Control", SND_CTL_IFACE_CONTROL, 0, 0);
for (idx = 0; idx < info.mixerdevs; idx++)
- process(" ", "Mixer", 1, idx);
+ process(ctl_handle, " ", "Mixer", SND_CTL_IFACE_MIXER, idx, 0);
for (idx = 0; idx < info.pcmdevs; idx++) {
- process(" ", "PCM playback", 2, idx);
- process(" ", "PCM capture", 3, idx);
+ process(ctl_handle, " ", "PCM playback", SND_CTL_IFACE_PCM, idx, SND_PCM_CHANNEL_PLAYBACK);
+ process(ctl_handle, " ", "PCM capture", SND_CTL_IFACE_PCM, idx, SND_PCM_CHANNEL_CAPTURE);
}
snd_ctl_close(ctl_handle);
}