mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-12-16 08:56:42 -05:00
Added functions:
snd_ctl_rawmidi_prefer_subdevice snd_rawmidi_open_subdevice Fixed functions: snd_pcm_hw_open - fixed prefer subdevice code
This commit is contained in:
parent
8a625fd63b
commit
0e561770c6
10 changed files with 93 additions and 9 deletions
|
|
@ -627,6 +627,9 @@ int ctl_shm_cmd(client_t *client)
|
||||||
case SND_CTL_IOCTL_RAWMIDI_INFO:
|
case SND_CTL_IOCTL_RAWMIDI_INFO:
|
||||||
ctrl->result = snd_ctl_rawmidi_info(ctl, &ctrl->u.rawmidi_info);
|
ctrl->result = snd_ctl_rawmidi_info(ctl, &ctrl->u.rawmidi_info);
|
||||||
break;
|
break;
|
||||||
|
case SND_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE:
|
||||||
|
ctrl->result = snd_ctl_rawmidi_prefer_subdevice(ctl, ctrl->u.rawmidi_prefer_subdevice);
|
||||||
|
break;
|
||||||
case SND_CTL_IOCTL_READ:
|
case SND_CTL_IOCTL_READ:
|
||||||
ctrl->result = snd_ctl_read1(ctl, &ctrl->u.read);
|
ctrl->result = snd_ctl_read1(ctl, &ctrl->u.read);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ typedef struct {
|
||||||
snd_pcm_info_t pcm_info;
|
snd_pcm_info_t pcm_info;
|
||||||
int pcm_prefer_subdevice;
|
int pcm_prefer_subdevice;
|
||||||
snd_rawmidi_info_t rawmidi_info;
|
snd_rawmidi_info_t rawmidi_info;
|
||||||
|
int rawmidi_prefer_subdevice;
|
||||||
snd_ctl_event_t read;
|
snd_ctl_event_t read;
|
||||||
} u;
|
} u;
|
||||||
char data[0];
|
char data[0];
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ int snd_ctl_hwdep_info(snd_ctl_t *handle, snd_hwdep_info_t * info);
|
||||||
int snd_ctl_pcm_info(snd_ctl_t *handle, snd_pcm_info_t * info);
|
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_pcm_prefer_subdevice(snd_ctl_t *handle, int subdev);
|
||||||
int snd_ctl_rawmidi_info(snd_ctl_t *handle, snd_rawmidi_info_t * info);
|
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_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks);
|
int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ extern "C" {
|
||||||
|
|
||||||
typedef struct snd_rawmidi snd_rawmidi_t;
|
typedef struct snd_rawmidi snd_rawmidi_t;
|
||||||
|
|
||||||
|
int snd_rawmidi_open_subdevice(snd_rawmidi_t **handle, int card, int device, int subdevice, int mode);
|
||||||
int snd_rawmidi_open(snd_rawmidi_t **handle, int card, int device, int mode);
|
int snd_rawmidi_open(snd_rawmidi_t **handle, int card, int device, int mode);
|
||||||
int snd_rawmidi_close(snd_rawmidi_t *handle);
|
int snd_rawmidi_close(snd_rawmidi_t *handle);
|
||||||
int snd_rawmidi_poll_descriptor(snd_rawmidi_t *handle);
|
int snd_rawmidi_poll_descriptor(snd_rawmidi_t *handle);
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,12 @@ int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
|
||||||
return ctl->ops->rawmidi_info(ctl, info);
|
return ctl->ops->rawmidi_info(ctl, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev)
|
||||||
|
{
|
||||||
|
assert(ctl);
|
||||||
|
return ctl->ops->rawmidi_prefer_subdevice(ctl, subdev);
|
||||||
|
}
|
||||||
|
|
||||||
int snd_ctl_read1(snd_ctl_t *ctl, snd_ctl_event_t *event)
|
int snd_ctl_read1(snd_ctl_t *ctl, snd_ctl_event_t *event)
|
||||||
{
|
{
|
||||||
assert(ctl && event);
|
assert(ctl && event);
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,14 @@ static int snd_ctl_hw_rawmidi_info(snd_ctl_t *handle, snd_rawmidi_info_t * info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int snd_ctl_hw_rawmidi_prefer_subdevice(snd_ctl_t *handle, int subdev)
|
||||||
|
{
|
||||||
|
snd_ctl_hw_t *hw = handle->private;
|
||||||
|
if (ioctl(hw->fd, SND_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE, &subdev) < 0)
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_ctl_hw_read(snd_ctl_t *handle, snd_ctl_event_t *event)
|
static int snd_ctl_hw_read(snd_ctl_t *handle, snd_ctl_event_t *event)
|
||||||
{
|
{
|
||||||
snd_ctl_hw_t *hw = handle->private;
|
snd_ctl_hw_t *hw = handle->private;
|
||||||
|
|
@ -144,6 +152,7 @@ struct snd_ctl_ops snd_ctl_hw_ops = {
|
||||||
pcm_info: snd_ctl_hw_pcm_info,
|
pcm_info: snd_ctl_hw_pcm_info,
|
||||||
pcm_prefer_subdevice: snd_ctl_hw_pcm_prefer_subdevice,
|
pcm_prefer_subdevice: snd_ctl_hw_pcm_prefer_subdevice,
|
||||||
rawmidi_info: snd_ctl_hw_rawmidi_info,
|
rawmidi_info: snd_ctl_hw_rawmidi_info,
|
||||||
|
rawmidi_prefer_subdevice: snd_ctl_hw_rawmidi_prefer_subdevice,
|
||||||
read: snd_ctl_hw_read,
|
read: snd_ctl_hw_read,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ struct snd_ctl_ops {
|
||||||
int (*pcm_info)(snd_ctl_t *handle, snd_pcm_info_t * info);
|
int (*pcm_info)(snd_ctl_t *handle, snd_pcm_info_t * info);
|
||||||
int (*pcm_prefer_subdevice)(snd_ctl_t *handle, int subdev);
|
int (*pcm_prefer_subdevice)(snd_ctl_t *handle, int subdev);
|
||||||
int (*rawmidi_info)(snd_ctl_t *handle, snd_rawmidi_info_t * info);
|
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);
|
int (*read)(snd_ctl_t *handle, snd_ctl_event_t *event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,19 @@ static int snd_ctl_shm_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int snd_ctl_shm_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev)
|
||||||
|
{
|
||||||
|
snd_ctl_shm_t *shm = ctl->private;
|
||||||
|
snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
|
||||||
|
int err;
|
||||||
|
ctrl->u.rawmidi_prefer_subdevice = subdev;
|
||||||
|
ctrl->cmd = SND_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE;
|
||||||
|
err = snd_ctl_shm_action(ctl);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_ctl_shm_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
|
static int snd_ctl_shm_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
|
||||||
{
|
{
|
||||||
snd_ctl_shm_t *shm = ctl->private;
|
snd_ctl_shm_t *shm = ctl->private;
|
||||||
|
|
@ -265,6 +278,7 @@ struct snd_ctl_ops snd_ctl_shm_ops = {
|
||||||
pcm_info: snd_ctl_shm_pcm_info,
|
pcm_info: snd_ctl_shm_pcm_info,
|
||||||
pcm_prefer_subdevice: snd_ctl_shm_pcm_prefer_subdevice,
|
pcm_prefer_subdevice: snd_ctl_shm_pcm_prefer_subdevice,
|
||||||
rawmidi_info: snd_ctl_shm_rawmidi_info,
|
rawmidi_info: snd_ctl_shm_rawmidi_info,
|
||||||
|
rawmidi_prefer_subdevice: snd_ctl_shm_rawmidi_prefer_subdevice,
|
||||||
read: snd_ctl_shm_read,
|
read: snd_ctl_shm_read,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -579,15 +579,18 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
ret = snd_ctl_pcm_prefer_subdevice(ctl, subdevice);
|
|
||||||
snd_ctl_close(ctl);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
sprintf(filename, filefmt, card, device);
|
sprintf(filename, filefmt, card, device);
|
||||||
|
|
||||||
__again:
|
__again:
|
||||||
if (attempt++ > 3)
|
if (attempt++ > 3) {
|
||||||
|
snd_ctl_close(ctl);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
ret = snd_ctl_pcm_prefer_subdevice(ctl, subdevice);
|
||||||
|
if (ret < 0) {
|
||||||
|
snd_ctl_close(ctl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
fmode = O_RDWR;
|
fmode = O_RDWR;
|
||||||
if (mode & SND_PCM_NONBLOCK)
|
if (mode & SND_PCM_NONBLOCK)
|
||||||
fmode |= O_NONBLOCK;
|
fmode |= O_NONBLOCK;
|
||||||
|
|
@ -595,6 +598,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev
|
||||||
fmode |= O_ASYNC;
|
fmode |= O_ASYNC;
|
||||||
if ((fd = open(filename, fmode)) < 0) {
|
if ((fd = open(filename, fmode)) < 0) {
|
||||||
SYSERR("open %s failed", filename);
|
SYSERR("open %s failed", filename);
|
||||||
|
snd_ctl_close(ctl);
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_PVERSION, &ver) < 0) {
|
if (ioctl(fd, SND_PCM_IOCTL_PVERSION, &ver) < 0) {
|
||||||
|
|
@ -646,11 +650,13 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev
|
||||||
ret = snd_pcm_hw_mmap_status(pcm);
|
ret = snd_pcm_hw_mmap_status(pcm);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
snd_pcm_close(pcm);
|
snd_pcm_close(pcm);
|
||||||
|
snd_ctl_close(ctl);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = snd_pcm_hw_mmap_control(pcm);
|
ret = snd_pcm_hw_mmap_control(pcm);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
snd_pcm_close(pcm);
|
snd_pcm_close(pcm);
|
||||||
|
snd_ctl_close(ctl);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -661,6 +667,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev
|
||||||
if (pcm)
|
if (pcm)
|
||||||
free(pcm);
|
free(pcm);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
snd_ctl_close(ctl);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,33 +38,69 @@ struct snd_rawmidi {
|
||||||
int mode;
|
int mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
int snd_rawmidi_open(snd_rawmidi_t **handle, int card, int device, int mode)
|
int snd_rawmidi_open_subdevice(snd_rawmidi_t **handle, int card, int device, int subdevice, int mode)
|
||||||
{
|
{
|
||||||
int fd, ver;
|
int fd, ver, ret;
|
||||||
|
int attempt = 0;
|
||||||
char filename[32];
|
char filename[32];
|
||||||
|
snd_ctl_t *ctl;
|
||||||
snd_rawmidi_t *rmidi;
|
snd_rawmidi_t *rmidi;
|
||||||
|
snd_rawmidi_info_t info;
|
||||||
|
|
||||||
*handle = NULL;
|
*handle = NULL;
|
||||||
|
|
||||||
if (card < 0 || card >= SND_CARDS)
|
if (card < 0 || card >= SND_CARDS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if ((ret = snd_ctl_hw_open(&ctl, NULL, card)) < 0)
|
||||||
|
return ret;
|
||||||
sprintf(filename, SND_FILE_RAWMIDI, card, device);
|
sprintf(filename, SND_FILE_RAWMIDI, card, device);
|
||||||
|
|
||||||
|
__again:
|
||||||
|
if (attempt++ > 3) {
|
||||||
|
snd_ctl_close(ctl);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
ret = snd_ctl_rawmidi_prefer_subdevice(ctl, subdevice);
|
||||||
|
if (ret < 0) {
|
||||||
|
snd_ctl_close(ctl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
if ((fd = open(filename, mode)) < 0) {
|
if ((fd = open(filename, mode)) < 0) {
|
||||||
snd_card_load(card);
|
snd_card_load(card);
|
||||||
if ((fd = open(filename, mode)) < 0)
|
if ((fd = open(filename, mode)) < 0) {
|
||||||
|
snd_ctl_close(ctl);
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ioctl(fd, SND_RAWMIDI_IOCTL_PVERSION, &ver) < 0) {
|
if (ioctl(fd, SND_RAWMIDI_IOCTL_PVERSION, &ver) < 0) {
|
||||||
|
ret = -errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
return -errno;
|
snd_ctl_close(ctl);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
if (SND_PROTOCOL_INCOMPATIBLE(ver, SND_RAWMIDI_VERSION_MAX)) {
|
if (SND_PROTOCOL_INCOMPATIBLE(ver, SND_RAWMIDI_VERSION_MAX)) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
snd_ctl_close(ctl);
|
||||||
return -SND_ERROR_INCOMPATIBLE_VERSION;
|
return -SND_ERROR_INCOMPATIBLE_VERSION;
|
||||||
}
|
}
|
||||||
|
if (subdevice >= 0) {
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
if (ioctl(fd, SND_RAWMIDI_IOCTL_INFO, &info) < 0) {
|
||||||
|
ret = -errno;
|
||||||
|
close(fd);
|
||||||
|
snd_ctl_close(ctl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (info.subdevice != subdevice) {
|
||||||
|
close(fd);
|
||||||
|
goto __again;
|
||||||
|
}
|
||||||
|
}
|
||||||
rmidi = (snd_rawmidi_t *) calloc(1, sizeof(snd_rawmidi_t));
|
rmidi = (snd_rawmidi_t *) calloc(1, sizeof(snd_rawmidi_t));
|
||||||
if (rmidi == NULL) {
|
if (rmidi == NULL) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
snd_ctl_close(ctl);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
rmidi->card = card;
|
rmidi->card = card;
|
||||||
|
|
@ -75,6 +111,11 @@ int snd_rawmidi_open(snd_rawmidi_t **handle, int card, int device, int mode)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int snd_rawmidi_open(snd_rawmidi_t **handle, int card, int device, int mode)
|
||||||
|
{
|
||||||
|
return snd_rawmidi_open_subdevice(handle, card, device, -1, mode);
|
||||||
|
}
|
||||||
|
|
||||||
int snd_rawmidi_close(snd_rawmidi_t *rmidi)
|
int snd_rawmidi_close(snd_rawmidi_t *rmidi)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue