- splitted pcm channels in two different devices to handle mmap correctly

- removed mmap control device
- reordered pcm shared and not shared code
- changed O_WRONLY oss pcm modifier in a more symmetric and elegant way
- changed slightly control interface
- added snd-debug-check
- uniformed null pointer check
- fixed a typo in linear plugin
This commit is contained in:
Abramo Bagnara 2000-01-08 20:11:33 +00:00
parent 62380b0f43
commit 63f5a79562
11 changed files with 263 additions and 216 deletions

View file

@ -42,13 +42,16 @@ int snd_ctl_switch_read(snd_ctl_t *handle, snd_switch_t * sw);
int snd_ctl_switch_write(snd_ctl_t *handle, snd_switch_t * sw);
int snd_ctl_hwdep_info(snd_ctl_t *handle, int dev, snd_hwdep_info_t * info);
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 subdev, snd_pcm_channel_info_t * info);
int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *handle, int dev, int subdev);
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_playback_switch_read(snd_ctl_t *handle, int dev, 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_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);

View file

@ -20,7 +20,7 @@ typedef struct snd_pcm_loopback snd_pcm_loopback_t;
int snd_pcm_open(snd_pcm_t **handle, int card, int device, int mode);
int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int mode);
int snd_pcm_close(snd_pcm_t *handle);
int snd_pcm_file_descriptor(snd_pcm_t *handle);
int snd_pcm_file_descriptor(snd_pcm_t *handle, int channel);
int snd_pcm_nonblock_mode(snd_pcm_t *handle, int nonblock);
int snd_pcm_info(snd_pcm_t *handle, snd_pcm_info_t * info);
int snd_pcm_channel_info(snd_pcm_t *handle, snd_pcm_channel_info_t * info);

View file

@ -171,15 +171,17 @@ int snd_ctl_pcm_info(snd_ctl_t *handle, int dev, snd_pcm_info_t * info)
return 0;
}
int snd_ctl_pcm_channel_info(snd_ctl_t *handle, int dev, int subdev, snd_pcm_channel_info_t * info)
int snd_ctl_pcm_channel_info(snd_ctl_t *handle, int dev, int chn, int subdev, snd_pcm_channel_info_t * info)
{
snd_ctl_t *ctl;
ctl = handle;
if (!ctl || !info || dev < 0 || subdev < 0)
if (!ctl || !info || dev < 0 || chn < 0 || chn > 1 || subdev < 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_SUBDEVICE, &subdev) < 0)
return -errno;
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_CHANNEL_INFO, info) < 0)
@ -187,102 +189,98 @@ int snd_ctl_pcm_channel_info(snd_ctl_t *handle, int dev, int subdev, snd_pcm_cha
return 0;
}
int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *handle, int dev, int subdev)
int snd_ctl_pcm_channel_prefer_subdevice(snd_ctl_t *handle, int dev, int chn, int subdev)
{
snd_ctl_t *ctl;
ctl = handle;
if (!ctl || dev < 0)
if (!ctl || dev < 0 || chn < 0 || chn > 1)
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_PREFER_SUBDEVICE, &subdev) < 0)
return -errno;
return 0;
}
int snd_ctl_pcm_playback_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t *list)
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 || !list)
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_PSWITCH_LIST, list) < 0)
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 || sw->name[0] == '\0')
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_PSWITCH_READ, sw) < 0)
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)
{
snd_ctl_t *ctl;
ctl = handle;
if (!ctl || !sw || dev < 0 || 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_PSWITCH_WRITE, sw) < 0)
return -errno;
return 0;
}
int snd_ctl_pcm_capture_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_PCM_DEVICE, &dev) < 0)
return -errno;
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_CSWITCH_LIST, list) < 0)
return -errno;
return 0;
}
int snd_ctl_pcm_capture_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_PCM_DEVICE, &dev) < 0)
return -errno;
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_CSWITCH_READ, sw) < 0)
return -errno;
return 0;
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)
{
snd_ctl_t *ctl;
ctl = handle;
if (!ctl || !sw || dev < 0 || 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_CSWITCH_WRITE, sw) < 0)
return -errno;
return 0;
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)

View file

@ -29,8 +29,8 @@
#include <sys/mman.h>
#include "pcm_local.h"
#define SND_FILE_PCM "/dev/snd/pcmC%iD%i"
#define SND_FILE_PCM_CONTROL "/dev/snd/pcmcontrol"
#define SND_FILE_PCM_PLAYBACK "/dev/snd/pcmC%iD%ip"
#define SND_FILE_PCM_CAPTURE "/dev/snd/pcmC%iD%ic"
#define SND_PCM_VERSION_MAX SND_PROTOCOL_VERSION(1, 0, 0)
int snd_pcm_open(snd_pcm_t **handle, int card, int device, int mode)
@ -38,13 +38,66 @@ int snd_pcm_open(snd_pcm_t **handle, int card, int device, int mode)
return snd_pcm_open_subdevice(handle, card, device, -1, mode);
}
static int snd_pcm_open_channel(int card, int device, int channel, int subdevice, int fmode, snd_ctl_t *ctl, int *ver)
{
char filename[32];
char *filefmt;
int err, fd;
int attempt = 0;
snd_pcm_channel_info_t info;
switch (channel) {
case SND_PCM_CHANNEL_PLAYBACK:
filefmt = SND_FILE_PCM_PLAYBACK;
break;
case SND_PCM_CHANNEL_CAPTURE:
filefmt = SND_FILE_PCM_CAPTURE;
break;
default:
return -EINVAL;
}
if ((err = snd_ctl_pcm_channel_prefer_subdevice(ctl, device, channel, subdevice)) < 0)
return err;
sprintf(filename, filefmt, card, device);
__again:
if (attempt++ > 3) {
snd_ctl_close(ctl);
return -EBUSY;
}
if ((fd = open(filename, fmode)) < 0) {
err = -errno;
return err;
}
if (ioctl(fd, SND_PCM_IOCTL_PVERSION, ver) < 0) {
err = -errno;
close(fd);
return err;
}
if (SND_PROTOCOL_INCOMPATIBLE(*ver, SND_PCM_VERSION_MAX)) {
close(fd);
return -SND_ERROR_INCOMPATIBLE_VERSION;
}
if (subdevice >= 0) {
memset(&info, 0, sizeof(info));
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, &info) < 0) {
err = -errno;
close(fd);
return err;
}
if (info.subdevice != subdevice) {
close(fd);
goto __again;
}
}
return fd;
}
int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int mode)
{
int fd, fmode, ver, err, attempt = 0;
char filename[32];
int fmode, ver, err;
snd_pcm_t *pcm;
snd_ctl_t *ctl;
snd_pcm_channel_info_t info;
int pfd = -1, cfd = -1;
*handle = NULL;
@ -52,142 +105,124 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi
return -EINVAL;
if ((err = snd_ctl_open(&ctl, card)) < 0)
return err;
if ((mode & (SND_PCM_OPEN_PLAYBACK|SND_PCM_OPEN_CAPTURE)) ==
(SND_PCM_OPEN_PLAYBACK|SND_PCM_OPEN_CAPTURE)) {
fmode = O_RDWR;
} else if (mode & SND_PCM_OPEN_PLAYBACK) {
fmode = O_WRONLY;
} else if (mode & SND_PCM_OPEN_CAPTURE) {
fmode = O_RDONLY;
} else {
snd_ctl_close(ctl);
return -EINVAL;
}
fmode = O_RDWR;
if (mode & SND_PCM_OPEN_NONBLOCK)
fmode |= O_NONBLOCK;
__again:
if (attempt++ > 3) {
snd_ctl_close(ctl);
return -EBUSY;
}
if ((err = snd_ctl_pcm_prefer_subdevice(ctl, device, subdevice)) < 0) {
snd_ctl_close(ctl);
return err;
}
sprintf(filename, SND_FILE_PCM, card, device);
if ((fd = open(filename, fmode)) < 0) {
err = -errno;
snd_ctl_close(ctl);
return err;
}
if (ioctl(fd, SND_PCM_IOCTL_PVERSION, &ver) < 0) {
err = -errno;
close(fd);
snd_ctl_close(ctl);
return err;
}
if (SND_PROTOCOL_INCOMPATIBLE(ver, SND_PCM_VERSION_MAX)) {
close(fd);
snd_ctl_close(ctl);
return -SND_ERROR_INCOMPATIBLE_VERSION;
}
if (subdevice >= 0 && (mode & SND_PCM_OPEN_PLAYBACK) != 0) {
memset(&info, 0, sizeof(info));
info.channel = SND_PCM_CHANNEL_PLAYBACK;
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, &info) < 0) {
err = -errno;
close(fd);
if (mode & SND_PCM_OPEN_PLAYBACK) {
pfd = snd_pcm_open_channel(card, device, SND_PCM_CHANNEL_PLAYBACK,
subdevice, fmode, ctl, &ver);
if (pfd < 0) {
snd_ctl_close(ctl);
return err;
}
if (info.subdevice != subdevice) {
close(fd);
goto __again;
return pfd;
}
}
if (subdevice >= 0 && (mode & SND_PCM_OPEN_CAPTURE) != 0) {
memset(&info, 0, sizeof(info));
info.channel = SND_PCM_CHANNEL_CAPTURE;
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, &info) < 0) {
err = -errno;
close(fd);
if (mode & SND_PCM_OPEN_CAPTURE) {
cfd = snd_pcm_open_channel(card, device, SND_PCM_CHANNEL_CAPTURE,
subdevice, fmode, ctl, &ver);
if (cfd < 0) {
if (pfd >= 0)
close(pfd);
snd_ctl_close(ctl);
return err;
}
if (info.subdevice != subdevice) {
close(fd);
goto __again;
return cfd;
}
}
snd_ctl_close(ctl);
if (pfd < 0 && cfd < 0)
return -EINVAL;
pcm = (snd_pcm_t *) calloc(1, sizeof(snd_pcm_t));
if (pcm == NULL) {
close(fd);
if (pfd >= 0)
close(pfd);
if (cfd >= 0)
close(cfd);
return -ENOMEM;
}
pcm->card = card;
pcm->device = device;
pcm->fd = fd;
pcm->fd[SND_PCM_CHANNEL_PLAYBACK] = pfd;
pcm->fd[SND_PCM_CHANNEL_CAPTURE] = cfd;
pcm->mode = mode;
pcm->ver = ver;
pcm->mmap_ctrl_fd[0] = pcm->mmap_ctrl_fd[1] = -1;
*handle = pcm;
return 0;
}
int snd_pcm_close(snd_pcm_t *pcm)
{
int res;
int res = -EINVAL;
int channel;
if (!pcm)
return -EINVAL;
snd_pcm_munmap(pcm, SND_PCM_CHANNEL_PLAYBACK);
snd_pcm_munmap(pcm, SND_PCM_CHANNEL_CAPTURE);
snd_pcm_plugin_clear(pcm, SND_PCM_CHANNEL_PLAYBACK);
snd_pcm_plugin_clear(pcm, SND_PCM_CHANNEL_CAPTURE);
res = close(pcm->fd) < 0 ? -errno : 0;
for (channel = 0; channel < 2; ++channel) {
snd_pcm_munmap(pcm, channel);
snd_pcm_plugin_clear(pcm, channel);
if (pcm->fd[channel] >= 0)
if (close(pcm->fd[channel]))
res = -errno;
}
free(pcm);
return res;
}
int snd_pcm_file_descriptor(snd_pcm_t *pcm)
int snd_pcm_file_descriptor(snd_pcm_t *pcm, int channel)
{
if (!pcm)
return -EINVAL;
return pcm->fd;
if (channel < 0 || channel > 1)
return -EINVAL;
return pcm->fd[channel];
}
int snd_pcm_nonblock_mode(snd_pcm_t *pcm, int nonblock)
{
long flags;
int fd, channel;
if (!pcm)
return -EINVAL;
if ((flags = fcntl(pcm->fd, F_GETFL)) < 0)
return -errno;
if (nonblock)
flags |= O_NONBLOCK;
else
flags &= ~O_NONBLOCK;
if (fcntl(pcm->fd, F_SETFL, flags) < 0)
return -errno;
for (channel = 0; channel < 2; ++channel) {
fd = pcm->fd[channel];
if (fd < 0)
continue;
if ((flags = fcntl(fd, F_GETFL)) < 0)
return -errno;
if (nonblock)
flags |= O_NONBLOCK;
else
flags &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0)
return -errno;
}
return 0;
}
int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
{
int fd, channel;
if (!pcm || !info)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_INFO, info) < 0)
for (channel = 0; channel < 2; ++channel) {
fd = pcm->fd[channel];
if (fd >= 0)
break;
}
if (ioctl(fd, SND_PCM_IOCTL_INFO, info) < 0)
return -errno;
return 0;
}
int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
{
int fd;
if (!pcm || !info)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_CHANNEL_INFO, info) < 0)
if (info->channel < 0 || info->channel > 1)
return -EINVAL;
fd = pcm->fd[info->channel];
if (fd < 0)
return -EINVAL;
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, info) < 0)
return -errno;
return 0;
}
@ -195,12 +230,16 @@ int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
int snd_pcm_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t * params)
{
int err;
int fd;
if (!pcm || !params)
return -EINVAL;
if (params->channel < 0 || params->channel > 1)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_CHANNEL_PARAMS, params) < 0)
fd = pcm->fd[params->channel];
if (fd < 0)
return -EINVAL;
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_PARAMS, params) < 0)
return -errno;
pcm->setup_is_valid[params->channel] = 0;
memset(&pcm->setup[params->channel], 0, sizeof(snd_pcm_channel_setup_t));
@ -213,14 +252,18 @@ int snd_pcm_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t * params)
int snd_pcm_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * setup)
{
int fd;
if (!pcm || !setup)
return -EINVAL;
if (setup->channel < 0 || setup->channel > 1)
return -EINVAL;
fd = pcm->fd[setup->channel];
if (fd < 0)
return -EINVAL;
if (pcm->setup_is_valid[setup->channel]) {
memcpy(setup, &pcm->setup[setup->channel], sizeof(*setup));
} else {
if (ioctl(pcm->fd, SND_PCM_IOCTL_CHANNEL_SETUP, setup) < 0)
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_SETUP, setup) < 0)
return -errno;
memcpy(&pcm->setup[setup->channel], setup, sizeof(*setup));
pcm->setup_is_valid[setup->channel] = 1;
@ -230,9 +273,13 @@ int snd_pcm_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * setup)
int snd_pcm_channel_status(snd_pcm_t *pcm, snd_pcm_channel_status_t * status)
{
int fd;
if (!pcm || !status)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_CHANNEL_STATUS, status) < 0)
fd = pcm->fd[status->channel];
if (fd < 0)
return -EINVAL;
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_STATUS, status) < 0)
return -errno;
return 0;
}
@ -241,7 +288,9 @@ int snd_pcm_playback_prepare(snd_pcm_t *pcm)
{
if (!pcm)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_PLAYBACK_PREPARE) < 0)
if (pcm->fd[SND_PCM_CHANNEL_PLAYBACK] < 0)
return -EINVAL;
if (ioctl(pcm->fd[SND_PCM_CHANNEL_PLAYBACK], SND_PCM_IOCTL_CHANNEL_PREPARE) < 0)
return -errno;
return 0;
}
@ -250,7 +299,9 @@ int snd_pcm_capture_prepare(snd_pcm_t *pcm)
{
if (!pcm)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_CAPTURE_PREPARE) < 0)
if (pcm->fd[SND_PCM_CHANNEL_CAPTURE] < 0)
return -EINVAL;
if (ioctl(pcm->fd[SND_PCM_CHANNEL_CAPTURE], SND_PCM_IOCTL_CHANNEL_PREPARE) < 0)
return -errno;
return 0;
}
@ -271,7 +322,9 @@ int snd_pcm_playback_go(snd_pcm_t *pcm)
{
if (!pcm)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_PLAYBACK_GO) < 0)
if (pcm->fd[SND_PCM_CHANNEL_PLAYBACK] < 0)
return -EINVAL;
if (ioctl(pcm->fd[SND_PCM_CHANNEL_PLAYBACK], SND_PCM_IOCTL_CHANNEL_GO) < 0)
return -errno;
return 0;
}
@ -280,7 +333,9 @@ int snd_pcm_capture_go(snd_pcm_t *pcm)
{
if (!pcm)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_CAPTURE_GO) < 0)
if (pcm->fd[SND_PCM_CHANNEL_CAPTURE] < 0)
return -EINVAL;
if (ioctl(pcm->fd[SND_PCM_CHANNEL_CAPTURE], SND_PCM_IOCTL_CHANNEL_GO) < 0)
return -errno;
return 0;
}
@ -301,7 +356,9 @@ int snd_pcm_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
{
if (!pcm || !sync)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_SYNC_GO, sync) < 0)
if (pcm->fd[SND_PCM_CHANNEL_PLAYBACK] < 0)
return -EINVAL;
if (ioctl(pcm->fd[SND_PCM_CHANNEL_PLAYBACK], SND_PCM_IOCTL_SYNC_GO, sync) < 0)
return -errno;
return 0;
}
@ -310,7 +367,9 @@ int snd_pcm_drain_playback(snd_pcm_t *pcm)
{
if (!pcm)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_DRAIN_PLAYBACK) < 0)
if (pcm->fd[SND_PCM_CHANNEL_PLAYBACK] < 0)
return -EINVAL;
if (ioctl(pcm->fd[SND_PCM_CHANNEL_PLAYBACK], SND_PCM_IOCTL_CHANNEL_DRAIN) < 0)
return -errno;
return 0;
}
@ -319,7 +378,9 @@ int snd_pcm_flush_playback(snd_pcm_t *pcm)
{
if (!pcm)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_FLUSH_PLAYBACK) < 0)
if (pcm->fd[SND_PCM_CHANNEL_PLAYBACK] < 0)
return -EINVAL;
if (ioctl(pcm->fd[SND_PCM_CHANNEL_PLAYBACK], SND_PCM_IOCTL_CHANNEL_FLUSH) < 0)
return -errno;
return 0;
}
@ -328,7 +389,9 @@ int snd_pcm_flush_capture(snd_pcm_t *pcm)
{
if (!pcm)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_FLUSH_CAPTURE) < 0)
if (pcm->fd[SND_PCM_CHANNEL_CAPTURE] < 0)
return -EINVAL;
if (ioctl(pcm->fd[SND_PCM_CHANNEL_CAPTURE], SND_PCM_IOCTL_CHANNEL_FLUSH) < 0)
return -errno;
return 0;
}
@ -349,7 +412,9 @@ int snd_pcm_playback_pause(snd_pcm_t *pcm, int enable)
{
if (!pcm)
return -EINVAL;
if (ioctl(pcm->fd, SND_PCM_IOCTL_PLAYBACK_PAUSE, &enable) < 0)
if (pcm->fd[SND_PCM_CHANNEL_PLAYBACK] < 0)
return -EINVAL;
if (ioctl(pcm->fd[SND_PCM_CHANNEL_PLAYBACK], SND_PCM_IOCTL_CHANNEL_PAUSE, &enable) < 0)
return -errno;
return 0;
}
@ -371,7 +436,9 @@ ssize_t snd_pcm_write(snd_pcm_t *pcm, const void *buffer, size_t size)
if (!pcm || (!buffer && size > 0) || size < 0)
return -EINVAL;
result = write(pcm->fd, buffer, size);
if (pcm->fd[SND_PCM_CHANNEL_PLAYBACK] < 0)
return -EINVAL;
result = write(pcm->fd[SND_PCM_CHANNEL_PLAYBACK], buffer, size);
if (result < 0)
return -errno;
return result;
@ -383,7 +450,9 @@ ssize_t snd_pcm_read(snd_pcm_t *pcm, void *buffer, size_t size)
if (!pcm || (!buffer && size > 0) || size < 0)
return -EINVAL;
result = read(pcm->fd, buffer, size);
if (pcm->fd[SND_PCM_CHANNEL_CAPTURE] < 0)
return -EINVAL;
result = read(pcm->fd[SND_PCM_CHANNEL_CAPTURE], buffer, size);
if (result < 0)
return -errno;
return result;
@ -392,8 +461,7 @@ ssize_t snd_pcm_read(snd_pcm_t *pcm, void *buffer, size_t size)
int snd_pcm_mmap(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t **control, void **buffer)
{
snd_pcm_channel_info_t info;
snd_pcm_mmap_select_t sel;
int err, ctrl_fd, ver, prot;
int err, fd, prot;
void *caddr, *daddr;
if (control)
@ -402,48 +470,26 @@ int snd_pcm_mmap(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t **control,
*buffer = NULL;
if (!pcm || channel < 0 || channel > 1 || !control || !buffer)
return -EINVAL;
fd = pcm->fd[channel];
if (fd < 0)
return -EINVAL;
memset(&info, 0, sizeof(info));
info.channel = channel;
if ((err = snd_pcm_channel_info(pcm, &info))<0)
return err;
ctrl_fd = open(SND_FILE_PCM_CONTROL, O_RDWR);
if (ctrl_fd < 0)
caddr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, SND_PCM_MMAP_OFFSET_CONTROL);
if (caddr == (caddr_t)-1 || caddr == NULL)
return -errno;
if (ioctl(ctrl_fd, SND_PCM_CTRL_IOCTL_PVERSION, &ver) < 0) {
err = -errno;
close(ctrl_fd);
return err;
}
if (pcm->ver != ver) {
close(ctrl_fd);
return -SND_ERROR_INCOMPATIBLE_VERSION;
}
sel.card = pcm->card;
sel.device = pcm->device;
sel.subdevice = info.subdevice;
sel.channel = channel;
if (ioctl(ctrl_fd, SND_PCM_CTRL_IOCTL_SELECT, &sel) < 0) {
err = -errno;
close(ctrl_fd);
return err;
}
caddr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, ctrl_fd, SND_PCM_MMAP_OFFSET_CONTROL);
if (caddr == (caddr_t)-1 || caddr == NULL) {
close(ctrl_fd);
return -errno;
}
prot = channel == SND_PCM_CHANNEL_PLAYBACK ? PROT_WRITE : PROT_READ;
daddr = mmap(NULL, info.mmap_size, prot, MAP_FILE|MAP_SHARED, ctrl_fd, SND_PCM_MMAP_OFFSET_DATA);
daddr = mmap(NULL, info.mmap_size, prot, MAP_FILE|MAP_SHARED, fd, SND_PCM_MMAP_OFFSET_DATA);
if (daddr == (caddr_t)-1 || daddr == NULL) {
err = -errno;
munmap(caddr, sizeof(snd_pcm_mmap_control_t));
close(ctrl_fd);
return err;
}
*control = pcm->mmap_caddr[channel] = caddr;
*buffer = pcm->mmap_daddr[channel] = daddr;
pcm->mmap_size[channel] = info.mmap_size;
pcm->mmap_ctrl_fd[channel] = ctrl_fd;
return 0;
}
@ -460,9 +506,5 @@ int snd_pcm_munmap(snd_pcm_t *pcm, int channel)
pcm->mmap_daddr[channel] = NULL;
pcm->mmap_size[channel] = 0;
}
if (pcm->mmap_ctrl_fd[channel] >= 0) {
close(pcm->mmap_ctrl_fd[channel]);
pcm->mmap_ctrl_fd[channel] = -1;
}
return 0;
}

View file

@ -24,12 +24,11 @@
struct snd_pcm {
int card;
int device;
int fd;
int mode;
int ver;
int fd[2];
int setup_is_valid[2];
snd_pcm_channel_setup_t setup[2];
int mmap_ctrl_fd[2];
snd_pcm_mmap_control_t *mmap_caddr[2];
char *mmap_daddr[2];
long mmap_size[2];
@ -46,7 +45,7 @@ unsigned int snd_pcm_plugin_formats(unsigned int formats);
int snd_pcm_plugin_hwparams(snd_pcm_channel_params_t *params,
snd_pcm_channel_info_t *hwinfo,
snd_pcm_channel_params_t *hwparams);
int snd_pcm_plugin_format(snd_pcm_t *pcm,
int snd_pcm_plugin_format(snd_pcm_t *pcm,
snd_pcm_channel_params_t *params,
snd_pcm_channel_params_t *hwparams,
snd_pcm_channel_info_t *hwinfo);

View file

@ -40,7 +40,7 @@ ssize_t snd_pcm_plugin_transfer_size(PLUGIN_BASE *pb, int channel, size_t drv_si
{
snd_pcm_plugin_t *plugin, *plugin_prev, *plugin_next;
if (!pb || (channel != SND_PCM_CHANNEL_PLAYBACK &&
if (pb == NULL || (channel != SND_PCM_CHANNEL_PLAYBACK &&
channel != SND_PCM_CHANNEL_CAPTURE))
return -EINVAL;
if (drv_size == 0)
@ -71,7 +71,7 @@ ssize_t snd_pcm_plugin_hardware_size(PLUGIN_BASE *pb, int channel, size_t trf_si
{
snd_pcm_plugin_t *plugin, *plugin_prev, *plugin_next;
if (!pb || (channel != SND_PCM_CHANNEL_PLAYBACK &&
if (pb == NULL || (channel != SND_PCM_CHANNEL_PLAYBACK &&
channel != SND_PCM_CHANNEL_CAPTURE))
return -EINVAL;
if (trf_size == 0)
@ -237,14 +237,19 @@ int snd_pcm_plugin_format(PLUGIN_BASE *pb,
snd_pcm_plugin_t *plugin;
int err;
if (params->channel == SND_PCM_CHANNEL_PLAYBACK) {
switch (params->channel) {
case SND_PCM_CHANNEL_PLAYBACK:
memcpy(&dstparams, hwparams, sizeof(*hwparams));
srcparams = hwparams;
memcpy(srcparams, params, sizeof(*params));
} else {
break;
case SND_PCM_CHANNEL_CAPTURE:
memcpy(&dstparams, params, sizeof(*params));
srcparams = params;
memcpy(srcparams, hwparams, sizeof(*hwparams));
break;
default:
return -EINVAL;
}
memcpy(&tmpparams, srcparams, sizeof(*srcparams));

View file

@ -191,7 +191,7 @@ int snd_pcm_plugin_build_interleave(snd_pcm_format_t *src_format,
combination_t cmd;
int size;
if (!r_plugin)
if (r_plugin == NULL)
return -EINVAL;
*r_plugin = NULL;

View file

@ -321,7 +321,7 @@ static ssize_t linear_src_size(snd_pcm_plugin_t *plugin, size_t size)
{
struct linear_private_data *data;
if (!plugin || size <= 0)
if (plugin == NULL || size <= 0)
return -EINVAL;
data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
if (data == NULL)
@ -333,7 +333,7 @@ static ssize_t linear_dst_size(snd_pcm_plugin_t *plugin, size_t size)
{
struct linear_private_data *data;
if (!plugin || size <= 0)
if (plugin == NULL || size <= 0)
return -EINVAL;
data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
if (data == NULL)
@ -351,7 +351,7 @@ int snd_pcm_plugin_build_linear(snd_pcm_format_t *src_format,
int src_endian, dst_endian, sign, src_width, dst_width;
int src_sample_size, dst_sample_size;
if (!r_plugin)
if (r_plugin == NULL)
return -EINVAL;
*r_plugin = NULL;
@ -424,7 +424,7 @@ int snd_pcm_plugin_build_linear(snd_pcm_format_t *src_format,
if (src_endian < 0)
src_endian = 0;
if (dst_endian < 0)
src_endian = 0;
dst_endian = 0;
func = convert_functions[src_width][dst_width][src_endian][dst_endian][sign];

View file

@ -378,7 +378,7 @@ static ssize_t mulaw_src_size(snd_pcm_plugin_t *plugin, size_t size)
{
struct mulaw_private_data *data;
if (!plugin || size <= 0)
if (plugin == NULL || size <= 0)
return -EINVAL;
data = (struct mulaw_private_data *)snd_pcm_plugin_extra_data(plugin);
switch (data->cmd) {
@ -406,7 +406,7 @@ static ssize_t mulaw_dst_size(snd_pcm_plugin_t *plugin, size_t size)
{
struct mulaw_private_data *data;
if (!plugin || size <= 0)
if (plugin == NULL || size <= 0)
return -EINVAL;
data = (struct mulaw_private_data *)snd_pcm_plugin_extra_data(plugin);
switch (data->cmd) {
@ -438,7 +438,7 @@ int snd_pcm_plugin_build_mulaw(snd_pcm_format_t *src_format,
snd_pcm_plugin_t *plugin;
combination_t cmd;
if (!r_plugin)
if (r_plugin == NULL)
return -EINVAL;
*r_plugin = NULL;

View file

@ -239,7 +239,7 @@ static ssize_t rate_src_size(snd_pcm_plugin_t *plugin, size_t size)
struct rate_private_data *data;
ssize_t res;
if (!plugin || size <= 0)
if (plugin == NULL || size <= 0)
return -EINVAL;
data = (struct rate_private_data *)snd_pcm_plugin_extra_data(plugin);
if (data->expand) {
@ -271,7 +271,7 @@ static ssize_t rate_dst_size(snd_pcm_plugin_t *plugin, size_t size)
struct rate_private_data *data;
ssize_t res;
if (!plugin || size <= 0)
if (plugin == NULL || size <= 0)
return -EINVAL;
data = (struct rate_private_data *)snd_pcm_plugin_extra_data(plugin);
if (data->expand) {
@ -366,7 +366,7 @@ int snd_pcm_plugin_build_rate(snd_pcm_format_t *src_format,
snd_pcm_plugin_t *plugin;
int voice;
if (!r_plugin)
if (r_plugin == NULL)
return -EINVAL;
*r_plugin = NULL;

View file

@ -148,7 +148,7 @@ static ssize_t voices_src_size(snd_pcm_plugin_t *plugin, size_t size)
{
struct voices_private_data *data;
if (!plugin || size <= 0)
if (plugin == NULL || size <= 0)
return -EINVAL;
data = (struct voices_private_data *)snd_pcm_plugin_extra_data(plugin);
return (size * data->src_voices) / data->dst_voices;
@ -158,7 +158,7 @@ static ssize_t voices_dst_size(snd_pcm_plugin_t *plugin, size_t size)
{
struct voices_private_data *data;
if (!plugin || size <= 0)
if (plugin == NULL || size <= 0)
return -EINVAL;
data = (struct voices_private_data *)snd_pcm_plugin_extra_data(plugin);
return (size * data->dst_voices) / data->src_voices;
@ -171,7 +171,7 @@ int snd_pcm_plugin_build_voices(snd_pcm_format_t *src_format,
struct voices_private_data *data;
snd_pcm_plugin_t *plugin;
if (!r_plugin)
if (r_plugin == NULL)
return -EINVAL;
*r_plugin = NULL;