The device lists use the next device syntax now.
case SND_CTL_IOCTL_CONTROL_WRITE:
ctrl->result = snd_ctl_cwrite(ctl, &ctrl->u.cwrite);
break;
+ case SND_CTL_IOCTL_HWDEP_NEXT_DEVICE:
+ ctrl->result = snd_ctl_hwdep_next_device(ctl, &ctrl->u.device);
+ break;
case SND_CTL_IOCTL_HWDEP_INFO:
ctrl->result = snd_ctl_hwdep_info(ctl, &ctrl->u.hwdep_info);
break;
+ case SND_CTL_IOCTL_PCM_NEXT_DEVICE:
+ ctrl->result = snd_ctl_pcm_next_device(ctl, &ctrl->u.device);
+ break;
case SND_CTL_IOCTL_PCM_INFO:
ctrl->result = snd_ctl_pcm_info(ctl, &ctrl->u.pcm_info);
break;
case SND_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
ctrl->result = snd_ctl_pcm_prefer_subdevice(ctl, ctrl->u.pcm_prefer_subdevice);
break;
+ case SND_CTL_IOCTL_RAWMIDI_NEXT_DEVICE:
+ ctrl->result = snd_ctl_rawmidi_next_device(ctl, &ctrl->u.device);
+ break;
case SND_CTL_IOCTL_RAWMIDI_INFO:
ctrl->result = snd_ctl_rawmidi_info(ctl, &ctrl->u.rawmidi_info);
break;
int result;
int cmd;
union {
+ int device;
snd_ctl_hw_info_t hw_info;
snd_control_list_t clist;
snd_control_info_t cinfo;
#endif
int snd_card_load(int card);
-int snd_cards(void);
-unsigned int snd_cards_mask(void);
+int snd_card_next(int *card);
int snd_card_get_index(const char *name);
int snd_card_get_name(int card, char **name);
int snd_card_get_longname(int card, char **name);
int snd_ctl_cinfo(snd_ctl_t *handle, snd_control_info_t * sw);
int snd_ctl_cread(snd_ctl_t *handle, snd_control_t * control);
int snd_ctl_cwrite(snd_ctl_t *handle, snd_control_t * control);
+int snd_ctl_hwdep_next_device(snd_ctl_t *handle, int * device);
int snd_ctl_hwdep_info(snd_ctl_t *handle, snd_hwdep_info_t * info);
+int snd_ctl_pcm_next_device(snd_ctl_t *handle, int *device);
int snd_ctl_pcm_info(snd_ctl_t *handle, snd_pcm_info_t * info);
int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *handle, int subdev);
+int snd_ctl_rawmidi_next_device(snd_ctl_t *handle, int * device);
int snd_ctl_rawmidi_info(snd_ctl_t *handle, snd_rawmidi_info_t * info);
int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *handle, int subdev);
int snd_timer_open(snd_timer_t **handle);
int snd_timer_close(snd_timer_t *handle);
int snd_timer_poll_descriptor(snd_timer_t *handle);
-int snd_timer_general_info(snd_timer_t *handle, snd_timer_general_info_t * info);
+int snd_timer_next_device(snd_timer_t *handle, snd_timer_id_t *tid);
int snd_timer_select(snd_timer_t *handle, snd_timer_select_t *tselect);
int snd_timer_info(snd_timer_t *handle, snd_timer_info_t *timer);
int snd_timer_params(snd_timer_t *handle, snd_timer_params_t *params);
return open_dev;
}
-int snd_cards(void)
+int snd_card_next(int *rcard)
{
- int idx, count;
- unsigned int mask;
-
- mask = snd_cards_mask();
- for (idx = 0, count = 0; idx < SND_CARDS; idx++) {
- if (mask & (1 << idx))
- count++;
- }
- return count;
-}
-
-/*
- * this routine uses very ugly method...
- * need to do... (use only stat on /proc/asound?)
- * now is information cached over static variable
- */
-
-unsigned int snd_cards_mask(void)
-{
- int idx;
- unsigned int mask;
- static unsigned int save_mask = 0;
-
- if (save_mask)
- return save_mask;
- for (idx = 0, mask = 0; idx < SND_CARDS; idx++) {
- if (snd_card_load(idx) >= 0)
- mask |= 1 << idx;
+ int card;
+
+ if (rcard == NULL)
+ return -EINVAL;
+ card = *rcard;
+ card = card < 0 ? 0 : card + 1;
+ for (; card < 32; card++) {
+ if (!snd_card_load(card)) {
+ *rcard = card;
+ return 0;
+ }
}
- save_mask = mask;
- return mask;
+ *rcard = -1;
+ return 0;
}
int snd_card_get_index(const char *string)
return ctl->ops->cwrite(ctl, control);
}
+int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int * device)
+{
+ assert(ctl && device);
+ return ctl->ops->hwdep_next_device(ctl, device);
+}
+
int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info)
{
assert(ctl && info);
return ctl->ops->hwdep_info(ctl, info);
}
+int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int * device)
+{
+ assert(ctl && device);
+ return ctl->ops->pcm_next_device(ctl, device);
+}
+
int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info)
{
assert(ctl && info);
return ctl->ops->pcm_prefer_subdevice(ctl, subdev);
}
+int snd_ctl_rawmidi_next_device(snd_ctl_t *ctl, int * device)
+{
+ assert(ctl && device);
+ return ctl->ops->rawmidi_next_device(ctl, device);
+}
+
int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
{
assert(ctl && info);
return 0;
}
+static int snd_ctl_hw_hwdep_next_device(snd_ctl_t *handle, int * device)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_HWDEP_NEXT_DEVICE, device) < 0)
+ return -errno;
+ return 0;
+}
+
static int snd_ctl_hw_hwdep_info(snd_ctl_t *handle, snd_hwdep_info_t * info)
{
snd_ctl_hw_t *hw = handle->private;
return 0;
}
+static int snd_ctl_hw_pcm_next_device(snd_ctl_t *handle, int * device)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_PCM_NEXT_DEVICE, device) < 0)
+ return -errno;
+ return 0;
+}
+
static int snd_ctl_hw_pcm_info(snd_ctl_t *handle, snd_pcm_info_t * info)
{
snd_ctl_hw_t *hw = handle->private;
return 0;
}
+static int snd_ctl_hw_rawmidi_next_device(snd_ctl_t *handle, int * device)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ if (ioctl(hw->fd, SND_CTL_IOCTL_RAWMIDI_NEXT_DEVICE, device) < 0)
+ return -errno;
+ return 0;
+}
+
static int snd_ctl_hw_rawmidi_info(snd_ctl_t *handle, snd_rawmidi_info_t * info)
{
snd_ctl_hw_t *hw = handle->private;
cinfo: snd_ctl_hw_cinfo,
cread: snd_ctl_hw_cread,
cwrite: snd_ctl_hw_cwrite,
+ hwdep_next_device: snd_ctl_hw_hwdep_next_device,
hwdep_info: snd_ctl_hw_hwdep_info,
+ pcm_next_device: snd_ctl_hw_pcm_next_device,
pcm_info: snd_ctl_hw_pcm_info,
pcm_prefer_subdevice: snd_ctl_hw_pcm_prefer_subdevice,
+ rawmidi_next_device: snd_ctl_hw_rawmidi_next_device,
rawmidi_info: snd_ctl_hw_rawmidi_info,
rawmidi_prefer_subdevice: snd_ctl_hw_rawmidi_prefer_subdevice,
read: snd_ctl_hw_read,
int (*cinfo)(snd_ctl_t *handle, snd_control_info_t *info);
int (*cread)(snd_ctl_t *handle, snd_control_t *control);
int (*cwrite)(snd_ctl_t *handle, snd_control_t *control);
+ int (*hwdep_next_device)(snd_ctl_t *handle, int *device);
int (*hwdep_info)(snd_ctl_t *handle, snd_hwdep_info_t * info);
+ int (*pcm_next_device)(snd_ctl_t *handle, int *device);
int (*pcm_info)(snd_ctl_t *handle, snd_pcm_info_t * info);
int (*pcm_prefer_subdevice)(snd_ctl_t *handle, int subdev);
+ int (*rawmidi_next_device)(snd_ctl_t *handle, int *device);
int (*rawmidi_info)(snd_ctl_t *handle, snd_rawmidi_info_t * info);
int (*rawmidi_prefer_subdevice)(snd_ctl_t *handle, int subdev);
int (*read)(snd_ctl_t *handle, snd_ctl_event_t *event);
return err;
}
+static int snd_ctl_shm_hwdep_next_device(snd_ctl_t *ctl, int * device)
+{
+ snd_ctl_shm_t *shm = ctl->private;
+ snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
+ int err;
+ ctrl->u.device = *device;
+ ctrl->cmd = SND_CTL_IOCTL_HWDEP_NEXT_DEVICE;
+ err = snd_ctl_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *device = ctrl->u.device;
+ return err;
+}
+
static int snd_ctl_shm_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info)
{
snd_ctl_shm_t *shm = ctl->private;
return err;
}
+static int snd_ctl_shm_pcm_next_device(snd_ctl_t *ctl, int * device)
+{
+ snd_ctl_shm_t *shm = ctl->private;
+ snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
+ int err;
+ ctrl->u.device = *device;
+ ctrl->cmd = SND_CTL_IOCTL_PCM_NEXT_DEVICE;
+ err = snd_ctl_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *device = ctrl->u.device;
+ return err;
+}
+
static int snd_ctl_shm_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info)
{
snd_ctl_shm_t *shm = ctl->private;
return err;
}
+static int snd_ctl_shm_rawmidi_next_device(snd_ctl_t *ctl, int * device)
+{
+ snd_ctl_shm_t *shm = ctl->private;
+ snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
+ int err;
+ ctrl->u.device = *device;
+ ctrl->cmd = SND_CTL_IOCTL_RAWMIDI_NEXT_DEVICE;
+ err = snd_ctl_shm_action(ctl);
+ if (err < 0)
+ return err;
+ *device = ctrl->u.device;
+ return err;
+}
+
static int snd_ctl_shm_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
{
snd_ctl_shm_t *shm = ctl->private;
cinfo: snd_ctl_shm_cinfo,
cread: snd_ctl_shm_cread,
cwrite: snd_ctl_shm_cwrite,
+ hwdep_next_device: snd_ctl_shm_hwdep_next_device,
hwdep_info: snd_ctl_shm_hwdep_info,
+ pcm_next_device: snd_ctl_shm_pcm_next_device,
pcm_info: snd_ctl_shm_pcm_info,
pcm_prefer_subdevice: snd_ctl_shm_pcm_prefer_subdevice,
+ rawmidi_next_device: snd_ctl_shm_rawmidi_next_device,
rawmidi_info: snd_ctl_shm_rawmidi_info,
rawmidi_prefer_subdevice: snd_ctl_shm_rawmidi_prefer_subdevice,
read: snd_ctl_shm_read,
int snd_defaults_card(void)
{
int result;
- unsigned int mask;
result = defaults_card("ALSA_CARD");
if (result >= 0)
return result;
- mask = snd_cards_mask();
- for (result = 0; result < 31; result++)
- if (mask & (1 << result))
- return result;
- return -ENOENT;
+ result = -1;
+ if (snd_card_next(&result))
+ return -ENOENT;
+ return result;
}
int snd_defaults_mixer_card(void)
int snd_defaults_pcm_device(void)
{
- return defaults_device("ALSA_PCM_DEVICE");
+ snd_ctl_t *handle;
+ char id[16];
+ int result;
+
+ result = defaults_device("ALSA_PCM_DEVICE");
+ if (result >= 0)
+ return result;
+ sprintf(id, "hw:%i", snd_defaults_pcm_card());
+ if (snd_ctl_open(&handle, id) < 0)
+ return -ENOENT;
+ result = -1;
+ if (snd_ctl_pcm_next_device(handle, &result) < 0) {
+ snd_ctl_close(handle);
+ return -ENOENT;
+ }
+ return result;
}
int snd_defaults_rawmidi_card(void)
int snd_defaults_rawmidi_device(void)
{
- return defaults_device("ALSA_RAWMIDI_DEVICE");
+ snd_ctl_t *handle;
+ char id[16];
+ int result;
+
+ result = defaults_device("ALSA_RAWMIDI_DEVICE");
+ if (result >= 0)
+ return result;
+ sprintf(id, "hw:%i", snd_defaults_rawmidi_card());
+ if (snd_ctl_open(&handle, id) < 0)
+ return -ENOENT;
+ result = -1;
+ if (snd_ctl_rawmidi_next_device(handle, &result) < 0) {
+ snd_ctl_close(handle);
+ return -ENOENT;
+ }
+ return result;
}
*handle = NULL;
- if ((fd = open(SND_FILE_TIMER, O_RDONLY)) < 0) {
- snd_cards_mask();
- if ((fd = open(SND_FILE_TIMER, O_RDONLY)) < 0)
- return -errno;
- }
+ if ((fd = open(SND_FILE_TIMER, O_RDONLY)) < 0)
+ return -errno;
if (ioctl(fd, SND_TIMER_IOCTL_PVERSION, &ver) < 0) {
close(fd);
return -errno;
return tmr->fd;
}
-int snd_timer_general_info(snd_timer_t *handle, snd_timer_general_info_t * info)
+int snd_timer_next_device(snd_timer_t *handle, snd_timer_id_t * tid)
{
snd_timer_t *tmr;
tmr = handle;
- if (!tmr || !info)
+ if (!tmr || !tid)
return -EINVAL;
- if (ioctl(tmr->fd, SND_TIMER_IOCTL_GINFO, info) < 0)
+ if (ioctl(tmr->fd, SND_TIMER_IOCTL_NEXT_DEVICE, tid) < 0)
return -errno;
return 0;
}
int main(int argc, char *argv[])
{
int idx, err;
- int timer = SND_TIMER_GLOBAL(SND_TIMER_GLOBAL_SYSTEM);
- int slave = 0;
- int slave_type = SND_TIMER_STYPE_SEQUENCER, slave_id = 0;
+ int type = SND_TIMER_TYPE_GLOBAL;
+ int stype = SND_TIMER_TYPE_NONE;
+ int card = 0;
+ int device = SND_TIMER_GLOBAL_SYSTEM;
+ int subdevice = 0;
+ int list = 0;
snd_timer_t *handle;
- snd_timer_general_info_t ginfo;
snd_timer_select_t sel;
snd_timer_info_t info;
snd_timer_params_t params;
idx = 1;
while (idx < argc) {
- if (!strncmp(argv[idx], "timer=", 6)) {
- timer = atoi(argv[idx]+6);
- } else if (!strcmp(argv[idx], "slave")) {
- slave = 1;
- } else if (!strncmp(argv[idx], "slave_type=", 11)) {
- slave_type = atoi(argv[idx]+11);
- } else if (!strncmp(argv[idx], "slave_id=", 9)) {
- slave_id = atoi(argv[idx]+9);
+ if (!strncmp(argv[idx], "type=", 5)) {
+ type = atoi(argv[idx]+5);
+ } else if (!strncmp(argv[idx], "stype=", 6)) {
+ stype = atoi(argv[idx]+6);
+ } else if (!strncmp(argv[idx], "card=", 5)) {
+ card = atoi(argv[idx]+5);
+ } else if (!strncmp(argv[idx], "device=", 7)) {
+ device = atoi(argv[idx]+7);
+ } else if (!strncmp(argv[idx], "subdevice=", 10)) {
+ subdevice = atoi(argv[idx]+10);
+ } else if (!strcmp(argv[idx], "list")) {
+ list = 1;
}
idx++;
}
- if (slave && slave_type == SND_TIMER_STYPE_NONE) {
+ if (type == SND_TIMER_TYPE_SLAVE && stype == SND_TIMER_STYPE_NONE) {
fprintf(stderr, "sync_type is not set\n");
exit(0);
}
fprintf(stderr, "timer open %i (%s)\n", err, snd_strerror(err));
exit(0);
}
- if (snd_timer_general_info(handle, &ginfo)<0) {
- fprintf(stderr, "timer general info %i (%s)\n", err, snd_strerror(err));
- exit(0);
+ if (list) {
+ bzero(&sel.id, sizeof(sel.id));
+ sel.id.type = -1;
+ while (1) {
+ if ((err = snd_timer_next_device(handle, &sel.id)) < 0) {
+ fprintf(stderr, "timer next device error: %s\n", snd_strerror(err));
+ break;
+ }
+ if (sel.id.type < 0)
+ break;
+ printf("Timer device: type %i, stype %i, card %i, device %i, subdevice %i\n",
+ sel.id.type, sel.id.stype, sel.id.card, sel.id.device, sel.id.subdevice);
+ }
}
- printf("Global timers = %i\n", ginfo.count);
- printf("Using timer %i, slave %i, slave_type %i, slave_id %i\n", timer, slave, slave_type, slave_id);
+ printf("Using timer type %i, slave type %i, card %i, device %i, subdevice %i\n", type, stype, card, device, subdevice);
bzero(&sel, sizeof(sel));
- sel.slave = slave;
- if (!sel.slave) {
- sel.data.number = timer;
- } else {
- sel.data.slave.type = slave_type;
- sel.data.slave.id = slave_id;
- }
+ sel.id.type = type;
+ sel.id.stype = stype;
+ sel.id.card = card;
+ sel.id.device = device;
+ sel.id.subdevice = subdevice;
if ((err = snd_timer_select(handle, &sel)) < 0) {
fprintf(stderr, "timer select %i (%s)\n", err, snd_strerror(err));
exit(0);
}
- if (!sel.slave) {
+ if (type != SND_TIMER_TYPE_SLAVE) {
if ((err = snd_timer_info(handle, &info)) < 0) {
fprintf(stderr, "timer info %i (%s)\n", err, snd_strerror(err));
exit(0);
}
- printf("Timer %i info:\n", sel.data.number);
+ printf("Timer info:\n");
printf(" flags = 0x%x\n", info.flags);
printf(" id = '%s'\n", info.id);
printf(" name = '%s'\n", info.name);
fprintf(stderr, "timer start %i (%s)\n", err, snd_strerror(err));
exit(0);
}
- read_loop(handle, 25, sel.slave ? 10000 : 1);
+ read_loop(handle, 25, type == SND_TIMER_TYPE_SLAVE ? 10000 : 1);
show_status(handle);
snd_timer_close(handle);
return 0;