]> git.alsa-project.org Git - alsa-lib.git/commitdiff
- splitted pcm channels in two different devices to handle mmap correctly
authorAbramo Bagnara <abramo@alsa-project.org>
Sat, 8 Jan 2000 20:11:33 +0000 (20:11 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Sat, 8 Jan 2000 20:11:33 +0000 (20:11 +0000)
- 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

include/control.h
include/pcm.h
src/control/control.c
src/pcm/pcm.c
src/pcm/pcm_local.h
src/pcm/pcm_plugin_build.c
src/pcm/plugin/interleave.c
src/pcm/plugin/linear.c
src/pcm/plugin/mulaw.c
src/pcm/plugin/rate.c
src/pcm/plugin/voices.c

index e89fc7f739ff2eaab216475bcf0a568ea436d62e..a4c9f4084e4c6889e16e9c7cca2b94b943682867 100644 (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);
index e6ffb772df826eed7f83a63d3ce8e51da4f39863..8fe0a6ccc6cff152bbc74603e23f12e89124ca87 100644 (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);
index cc8560e9b1c22a1348600224d3abeb9a2d68a48c..cc17729d89931485d86c7b4462fdf950dcfbab6f 100644 (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_read(snd_ctl_t *handle, int dev, snd_switch_t * sw)
+int snd_ctl_pcm_playback_switch_list(snd_ctl_t *handle, int dev, snd_switch_list_t *list)
 {
-       snd_ctl_t *ctl;
+       return snd_ctl_pcm_channel_switch_list(handle, dev, SND_PCM_CHANNEL_PLAYBACK, list);
+}
 
-       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_READ, sw) < 0)
-               return -errno;
-       return 0;
+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_playback_switch_write(snd_ctl_t *handle, int dev, snd_switch_t * sw)
+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 || 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_WRITE, sw) < 0)
+       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_capture_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)
 {
-       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;
+       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_CSWITCH_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_capture_switch_write(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)
 {
-       snd_ctl_t *ctl;
+       return snd_ctl_pcm_channel_switch_write(handle, dev, SND_PCM_CHANNEL_PLAYBACK, sw);
+}
 
-       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;
+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)
index dd91f5b6cf9be82b473e0f5e2973ee3788b11e1c..177138e859940a7d5cd9c7b0fc4a9edb431ee743 100644 (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,66 +38,50 @@ int snd_pcm_open(snd_pcm_t **handle, int card, int device, int mode)
        return snd_pcm_open_subdevice(handle, card, device, -1, mode);
 }
 
-int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int mode)
+static int snd_pcm_open_channel(int card, int device, int channel, int subdevice, int fmode, snd_ctl_t *ctl, int *ver)
 {
-       int fd, fmode, ver, err, attempt = 0;
        char filename[32];
-       snd_pcm_t *pcm;
-       snd_ctl_t *ctl;
+       char *filefmt;
+       int err, fd;
+       int attempt = 0;
        snd_pcm_channel_info_t info;
-
-       *handle = NULL;
-       
-       if (card < 0 || card >= SND_CARDS)
-               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);
+       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 (mode & SND_PCM_OPEN_NONBLOCK)
-               fmode |= O_NONBLOCK;
+       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 ((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) {
+       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)) {
+       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) {
+       if (subdevice >= 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);
-                       snd_ctl_close(ctl);
                        return err;
                }
                if (info.subdevice != subdevice) {
@@ -105,89 +89,140 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi
                        goto __again;
                }
        }
-       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);
+       return fd;
+}
+
+int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int mode)
+{
+       int fmode, ver, err;
+       snd_pcm_t *pcm;
+       snd_ctl_t *ctl;
+       int pfd = -1, cfd = -1;
+
+       *handle = NULL;
+       
+       if (card < 0 || card >= SND_CARDS)
+               return -EINVAL;
+       if ((err = snd_ctl_open(&ctl, card)) < 0)
+               return err;
+       fmode = O_RDWR;
+       if (mode & SND_PCM_OPEN_NONBLOCK)
+               fmode |= O_NONBLOCK;
+       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;
+                       return pfd;
                }
-               if (info.subdevice != subdevice) {
-                       close(fd);
-                       goto __again;
+       }
+       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 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;
 }
index 7fd9714adc9e8b1f5fcba14bad258fff62fb8bb4..0ba3089314b5f531126e7f1a004ea4d8b7da3742 100644 (file)
 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);
index 410d3aca9c27ba0dc362aab2dce5aabd6d2bfc70..10a24d8da1be4366253f2ad3ec178f80d4dabf50 100644 (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));
                
index cd1a17d89bf73e2f84dc84d39f6fd5154e990fca..24dbae47d04ff7698ab77bbc9ceed4c81fd73d7c 100644 (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;
 
index eabb5fc6402096369f0852c1477c53745e19a48f..7bca57357beb892e5db407276004c6eaaf93c28e 100644 (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];
 
index 44b23830fd1fc3a96c78f8593c2d17d121f97ee7..b5b40b80ba08c3c18279ab0039b1a9f2b0928f85 100644 (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;
 
index 0c03b66d89ff8a361e8417f51a7f0be574a064c2..5842d3360cc38228ce1e59fd0db3dce3015f2e28 100644 (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;
 
index 34b9992e7196c3fcbd64ec63fdac2f281da06ace..7997600efdc03b5679cadf8657b5dc986e9ae2f4 100644 (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;