]> git.alsa-project.org Git - alsa-lib.git/commitdiff
improved stream linking and plugin code cleanups
authorJaroslav Kysela <perex@perex.cz>
Thu, 20 Jan 2005 15:07:51 +0000 (15:07 +0000)
committerJaroslav Kysela <perex@perex.cz>
Thu, 20 Jan 2005 15:07:51 +0000 (15:07 +0000)
- added link/unlink/link_fd fast_ops callbacks
- moved code from snd_pcm_link to pcm_hw.c
- moved "empty" routines pointing to slave to pcm_generic.c
- introduced snd_pcm_generic_t

25 files changed:
src/pcm/Makefile.am
src/pcm/pcm.c
src/pcm/pcm_adpcm.c
src/pcm/pcm_alaw.c
src/pcm/pcm_copy.c
src/pcm/pcm_dmix.c
src/pcm/pcm_dshare.c
src/pcm/pcm_dsnoop.c
src/pcm/pcm_file.c
src/pcm/pcm_generic.c [new file with mode: 0644]
src/pcm/pcm_generic.h [new file with mode: 0644]
src/pcm/pcm_hooks.c
src/pcm/pcm_hw.c
src/pcm/pcm_iec958.c
src/pcm/pcm_ladspa.c
src/pcm/pcm_lfloat.c
src/pcm/pcm_linear.c
src/pcm/pcm_local.h
src/pcm/pcm_mulaw.c
src/pcm/pcm_plug.c
src/pcm/pcm_plugin.c
src/pcm/pcm_plugin.h
src/pcm/pcm_rate.c
src/pcm/pcm_route.c
src/pcm/pcm_softvol.c

index 5a11ef62509aefa29ae997bb37589574cb9ad369..4d9a8a640e077f9dd872bd48491aee91d1bbbe62 100644 (file)
@@ -5,7 +5,7 @@ EXTRA_LTLIBRARIES = libpcm.la
 
 libpcm_la_SOURCES = atomic.c mask.c interval.c \
                    pcm.c pcm_params.c pcm_simple.c \
-                   pcm_hw.c pcm_plugin.c pcm_copy.c pcm_linear.c \
+                   pcm_hw.c pcm_generic.c pcm_plugin.c pcm_copy.c pcm_linear.c \
                    pcm_route.c pcm_mulaw.c pcm_alaw.c pcm_adpcm.c \
                    pcm_rate.c pcm_plug.c pcm_misc.c pcm_mmap.c pcm_multi.c \
                    pcm_shm.c pcm_file.c pcm_null.c pcm_share.c \
index 6e7c0e5be7b421f638c95432924a7852f601a550..13af39424f001e368827e49aa67aa922e6f3bd4a 100644 (file)
@@ -1239,15 +1239,11 @@ snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t s
  */ 
 int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
 {
-       int fd1 = _snd_pcm_link_descriptor(pcm1);
-       int fd2 = _snd_pcm_link_descriptor(pcm2);
-       if (fd1 < 0 || fd2 < 0)
-               return -ENOSYS;
-       if (ioctl(fd1, SNDRV_PCM_IOCTL_LINK, fd2) < 0) {
-               SYSMSG("SNDRV_PCM_IOCTL_LINK failed");
-               return -errno;
-       }
-       return 0;
+       assert(pcm1);
+       assert(pcm2);
+       if (pcm1->fast_ops->link)
+               return pcm1->fast_ops->link(pcm1, pcm2);
+       return -ENOSYS;
 }
 
 /**
@@ -1257,13 +1253,10 @@ int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
  */
 int snd_pcm_unlink(snd_pcm_t *pcm)
 {
-       int fd;
-       fd = _snd_pcm_link_descriptor(pcm);
-       if (ioctl(fd, SNDRV_PCM_IOCTL_UNLINK) < 0) {
-               SYSMSG("SNDRV_PCM_IOCTL_UNLINK failed");
-               return -errno;
-       }
-       return 0;
+       assert(pcm);
+       if (pcm->fast_ops->unlink)
+               return pcm->fast_ops->unlink(pcm);
+       return -ENOSYS;
 }
 
 /**
@@ -6147,6 +6140,14 @@ snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm,
 
 #ifndef DOC_HIDDEN
 
+int _snd_pcm_link_descriptor(snd_pcm_t *pcm)
+{
+       assert(pcm);
+       if (pcm->fast_ops->link_fd)
+               return pcm->fast_ops->link_fd(pcm);
+       return -ENOSYS;
+}
+
 int _snd_pcm_poll_descriptor(snd_pcm_t *pcm)
 {
        assert(pcm);
index fa4299729ea44c56b260de3fb0ce4047da739e3b..b9c32005619f3bad4490bcb6b1cd3c38385eb8a9 100644 (file)
@@ -401,7 +401,7 @@ static int snd_pcm_adpcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_adpcm_hw_refine_cchange,
                                       snd_pcm_adpcm_hw_refine_sprepare,
                                       snd_pcm_adpcm_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
@@ -412,7 +412,7 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                                          snd_pcm_adpcm_hw_refine_cchange,
                                          snd_pcm_adpcm_hw_refine_sprepare,
                                          snd_pcm_adpcm_hw_refine_schange,
-                                         snd_pcm_plugin_hw_params_slave);
+                                         snd_pcm_generic_hw_params);
        if (err < 0)
                return err;
 
@@ -438,7 +438,7 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                }
        }
        assert(!adpcm->states);
-       adpcm->states = malloc(adpcm->plug.slave->channels * sizeof(*adpcm->states));
+       adpcm->states = malloc(adpcm->plug.gen.slave->channels * sizeof(*adpcm->states));
        if (adpcm->states == NULL)
                return -ENOMEM;
        return 0;
@@ -451,7 +451,7 @@ static int snd_pcm_adpcm_hw_free(snd_pcm_t *pcm)
                free(adpcm->states);
                adpcm->states = 0;
        }
-       return snd_pcm_hw_free(adpcm->plug.slave);
+       return snd_pcm_hw_free(adpcm->plug.gen.slave);
 }
 
 static int snd_pcm_adpcm_init(snd_pcm_t *pcm)
@@ -515,23 +515,23 @@ static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(adpcm->plug.slave, out);
+       snd_pcm_dump(adpcm->plug.gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_adpcm_ops = {
-       .close = snd_pcm_plugin_close,
-       .info = snd_pcm_plugin_info,
+       .close = snd_pcm_generic_close,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_adpcm_hw_refine,
        .hw_params = snd_pcm_adpcm_hw_params,
        .hw_free = snd_pcm_adpcm_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_adpcm_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 /**
@@ -564,8 +564,8 @@ int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
        adpcm->plug.read = snd_pcm_adpcm_read_areas;
        adpcm->plug.write = snd_pcm_adpcm_write_areas;
        adpcm->plug.init = snd_pcm_adpcm_init;
-       adpcm->plug.slave = slave;
-       adpcm->plug.close_slave = close_slave;
+       adpcm->plug.gen.slave = slave;
+       adpcm->plug.gen.close_slave = close_slave;
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_ADPCM, name, slave->stream, slave->mode);
        if (err < 0) {
index c8c6cc9a56dd32afc76e7b206f8bb280ad966e1a..a76f15acf86326f1e376ed449f7925df6b41bbfc 100644 (file)
@@ -297,7 +297,7 @@ static int snd_pcm_alaw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_alaw_hw_refine_cchange,
                                       snd_pcm_alaw_hw_refine_sprepare,
                                       snd_pcm_alaw_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
@@ -308,7 +308,7 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                                          snd_pcm_alaw_hw_refine_cchange,
                                          snd_pcm_alaw_hw_refine_sprepare,
                                          snd_pcm_alaw_hw_refine_schange,
-                                         snd_pcm_plugin_hw_params_slave);
+                                         snd_pcm_generic_hw_params);
        if (err < 0)
                return err;
 
@@ -386,23 +386,23 @@ static void snd_pcm_alaw_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(alaw->plug.slave, out);
+       snd_pcm_dump(alaw->plug.gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_alaw_ops = {
-       .close = snd_pcm_plugin_close,
-       .info = snd_pcm_plugin_info,
+       .close = snd_pcm_generic_close,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_alaw_hw_refine,
        .hw_params = snd_pcm_alaw_hw_params,
-       .hw_free = snd_pcm_plugin_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .hw_free = snd_pcm_generic_hw_free,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_alaw_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 /**
@@ -436,8 +436,8 @@ int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
        alaw->plug.write = snd_pcm_alaw_write_areas;
        alaw->plug.undo_read = snd_pcm_plugin_undo_read_generic;
        alaw->plug.undo_write = snd_pcm_plugin_undo_write_generic;
-       alaw->plug.slave = slave;
-       alaw->plug.close_slave = close_slave;
+       alaw->plug.gen.slave = slave;
+       alaw->plug.gen.close_slave = close_slave;
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_ALAW, name, slave->stream, slave->mode);
        if (err < 0) {
index 9c4633ba25f127cd167a089bd05b5f514aaf2a4a..64b4557ba4ab42e8a9b9541fb45c41c63c36bd5c 100644 (file)
@@ -92,7 +92,7 @@ static int snd_pcm_copy_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_copy_hw_refine_cchange,
                                       snd_pcm_copy_hw_refine_sprepare,
                                       snd_pcm_copy_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_copy_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
@@ -101,7 +101,7 @@ static int snd_pcm_copy_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_copy_hw_refine_cchange,
                                       snd_pcm_copy_hw_refine_sprepare,
                                       snd_pcm_copy_hw_refine_schange,
-                                      snd_pcm_plugin_hw_params_slave);
+                                      snd_pcm_generic_hw_params);
 }
 
 static snd_pcm_uframes_t
@@ -149,23 +149,23 @@ static void snd_pcm_copy_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(copy->plug.slave, out);
+       snd_pcm_dump(copy->plug.gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_copy_ops = {
-       .close = snd_pcm_plugin_close,
-       .info = snd_pcm_plugin_info,
+       .close = snd_pcm_generic_close,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_copy_hw_refine,
        .hw_params = snd_pcm_copy_hw_params,
-       .hw_free = snd_pcm_plugin_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .hw_free = snd_pcm_generic_hw_free,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_copy_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 /**
@@ -194,8 +194,8 @@ int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
        copy->plug.write = snd_pcm_copy_write_areas;
        copy->plug.undo_read = snd_pcm_plugin_undo_read_generic;
        copy->plug.undo_write = snd_pcm_plugin_undo_write_generic;
-       copy->plug.slave = slave;
-       copy->plug.close_slave = close_slave;
+       copy->plug.gen.slave = slave;
+       copy->plug.gen.close_slave = close_slave;
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_COPY, name, slave->stream, slave->mode);
        if (err < 0) {
index 3fdbf4b212fad9e1297d3b069ecf507ecfbe435f..5375da709c81e4271be97a8ce967579917161dc2 100644 (file)
@@ -767,6 +767,9 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
        .forward = snd_pcm_dmix_forward,
        .resume = snd_pcm_dmix_resume,
        .poll_ask = NULL,
+       .link_fd = NULL,
+       .link = NULL,
+       .unlink = NULL,
        .writei = snd_pcm_mmap_writei,
        .writen = snd_pcm_mmap_writen,
        .readi = snd_pcm_dmix_readi,
index 527840193331ee09d94c46311b53c80508533ba1..87fd245c80edfc636aee9c0e093a8c2f57e32933 100644 (file)
@@ -496,6 +496,9 @@ static snd_pcm_fast_ops_t snd_pcm_dshare_fast_ops = {
        .forward = snd_pcm_dshare_forward,
        .resume = snd_pcm_dshare_resume,
        .poll_ask = NULL,
+       .link_fd = NULL,
+       .link = NULL,
+       .unlink = NULL,
        .writei = snd_pcm_mmap_writei,
        .writen = snd_pcm_mmap_writen,
        .readi = snd_pcm_dshare_readi,
index e6ae1e6a2152b4da1f558162b87b099525a7ff83..176373595194fd052fefff3aa453dc809e832e8b 100644 (file)
@@ -464,6 +464,9 @@ static snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
        .forward = snd_pcm_dsnoop_forward,
        .resume = snd_pcm_dsnoop_resume,
        .poll_ask = NULL,
+       .link_fd = NULL,
+       .link = NULL,
+       .unlink = NULL,
        .writei = snd_pcm_dsnoop_writei,
        .writen = snd_pcm_dsnoop_writen,
        .readi = snd_pcm_mmap_readi,
index 6559545b0b42b440ecd1334d5a3d15308b1298b0..132fb23c9c44cdc0f9e450ec3cb9607a0a584218 100644 (file)
@@ -42,8 +42,7 @@ typedef enum _snd_pcm_file_format {
 } snd_pcm_file_format_t;
 
 typedef struct {
-       snd_pcm_t *slave;
-       int close_slave;
+       snd_pcm_generic_t gen;
        char *fname;
        int fd;
        int format;
@@ -115,81 +114,17 @@ static void snd_pcm_file_add_frames(snd_pcm_t *pcm,
 static int snd_pcm_file_close(snd_pcm_t *pcm)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       int err = 0;
-       if (file->close_slave)
-               err = snd_pcm_close(file->slave);
        if (file->fname) {
                free((void *)file->fname);
                close(file->fd);
        }
-       free(file);
-       return 0;
-}
-
-static int snd_pcm_file_nonblock(snd_pcm_t *pcm, int nonblock)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_nonblock(file->slave, nonblock);
-}
-
-static int snd_pcm_file_async(snd_pcm_t *pcm, int sig, pid_t pid)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_async(file->slave, sig, pid);
-}
-
-static int snd_pcm_file_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_poll_descriptors_revents(file->slave, pfds, nfds, revents);
-}
-
-static int snd_pcm_file_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_info(file->slave, info);
-}
-
-static int snd_pcm_file_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_channel_info(file->slave, info);
-}
-
-static int snd_pcm_file_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_status(file->slave, status);
-}
-
-static snd_pcm_state_t snd_pcm_file_state(snd_pcm_t *pcm)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_state(file->slave);
-}
-
-static int snd_pcm_file_hwsync(snd_pcm_t *pcm)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_hwsync(file->slave);
-}
-
-static int snd_pcm_file_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_delay(file->slave, delayp);
-}
-
-static int snd_pcm_file_prepare(snd_pcm_t *pcm)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_prepare(file->slave);
+       return snd_pcm_generic_close(pcm);
 }
 
 static int snd_pcm_file_reset(snd_pcm_t *pcm)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       int err = snd_pcm_reset(file->slave);
+       int err = snd_pcm_reset(file->gen.slave);
        if (err >= 0) {
                /* FIXME: Questionable here */
                snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
@@ -198,16 +133,10 @@ static int snd_pcm_file_reset(snd_pcm_t *pcm)
        return err;
 }
 
-static int snd_pcm_file_start(snd_pcm_t *pcm)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_start(file->slave);
-}
-
 static int snd_pcm_file_drop(snd_pcm_t *pcm)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       int err = snd_pcm_drop(file->slave);
+       int err = snd_pcm_drop(file->gen.slave);
        if (err >= 0) {
                /* FIXME: Questionable here */
                snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
@@ -219,7 +148,7 @@ static int snd_pcm_file_drop(snd_pcm_t *pcm)
 static int snd_pcm_file_drain(snd_pcm_t *pcm)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       int err = snd_pcm_drain(file->slave);
+       int err = snd_pcm_drain(file->gen.slave);
        if (err >= 0) {
                snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
                assert(file->wbuf_used_bytes == 0);
@@ -227,12 +156,6 @@ static int snd_pcm_file_drain(snd_pcm_t *pcm)
        return err;
 }
 
-static int snd_pcm_file_pause(snd_pcm_t *pcm, int enable)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_pause(file->slave, enable);
-}
-
 static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_file_t *file = pcm->private_data;
@@ -242,7 +165,7 @@ static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
        n = snd_pcm_frames_to_bytes(pcm, frames);
        if (n > file->wbuf_used_bytes)
                frames = snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
-       err = snd_pcm_rewind(file->slave, frames);
+       err = snd_pcm_rewind(file->gen.slave, frames);
        if (err > 0) {
                n = snd_pcm_frames_to_bytes(pcm, err);
                file->wbuf_used_bytes -= n;
@@ -259,7 +182,7 @@ static snd_pcm_sframes_t snd_pcm_file_forward(snd_pcm_t *pcm, snd_pcm_uframes_t
        n = snd_pcm_frames_to_bytes(pcm, frames);
        if (file->wbuf_used_bytes + n > file->wbuf_size_bytes)
                frames = snd_pcm_bytes_to_frames(pcm, file->wbuf_size_bytes - file->wbuf_used_bytes);
-       err = INTERNAL(snd_pcm_forward)(file->slave, frames);
+       err = INTERNAL(snd_pcm_forward)(file->gen.slave, frames);
        if (err > 0) {
                snd_pcm_uframes_t n = snd_pcm_frames_to_bytes(pcm, err);
                file->wbuf_used_bytes += n;
@@ -267,25 +190,11 @@ static snd_pcm_sframes_t snd_pcm_file_forward(snd_pcm_t *pcm, snd_pcm_uframes_t
        return err;
 }
 
-static int snd_pcm_file_resume(snd_pcm_t *pcm)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_resume(file->slave);
-}
-
-static int snd_pcm_file_poll_ask(snd_pcm_t *pcm)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       if (file->slave->fast_ops->poll_ask)
-               return file->slave->fast_ops->poll_ask(file->slave->fast_op_arg);
-       return 0;
-}
-
 static snd_pcm_sframes_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
        snd_pcm_file_t *file = pcm->private_data;
        snd_pcm_channel_area_t areas[pcm->channels];
-       snd_pcm_sframes_t n = snd_pcm_writei(file->slave, buffer, size);
+       snd_pcm_sframes_t n = snd_pcm_writei(file->gen.slave, buffer, size);
        if (n > 0) {
                snd_pcm_areas_from_buf(pcm, areas, (void*) buffer);
                snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -297,7 +206,7 @@ static snd_pcm_sframes_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, snd_pc
 {
        snd_pcm_file_t *file = pcm->private_data;
        snd_pcm_channel_area_t areas[pcm->channels];
-       snd_pcm_sframes_t n = snd_pcm_writen(file->slave, bufs, size);
+       snd_pcm_sframes_t n = snd_pcm_writen(file->gen.slave, bufs, size);
        if (n > 0) {
                snd_pcm_areas_from_bufs(pcm, areas, bufs);
                snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -309,7 +218,7 @@ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pc
 {
        snd_pcm_file_t *file = pcm->private_data;
        snd_pcm_channel_area_t areas[pcm->channels];
-       snd_pcm_sframes_t n = snd_pcm_readi(file->slave, buffer, size);
+       snd_pcm_sframes_t n = snd_pcm_readi(file->gen.slave, buffer, size);
        if (n > 0) {
                snd_pcm_areas_from_buf(pcm, areas, buffer);
                snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -321,7 +230,7 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm
 {
        snd_pcm_file_t *file = pcm->private_data;
        snd_pcm_channel_area_t areas[pcm->channels];
-       snd_pcm_sframes_t n = snd_pcm_writen(file->slave, bufs, size);
+       snd_pcm_sframes_t n = snd_pcm_writen(file->gen.slave, bufs, size);
        if (n > 0) {
                snd_pcm_areas_from_bufs(pcm, areas, bufs);
                snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -339,26 +248,14 @@ static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm,
        const snd_pcm_channel_area_t *areas;
        snd_pcm_sframes_t result;
 
-       snd_pcm_mmap_begin(file->slave, &areas, &ofs, &siz);
+       snd_pcm_mmap_begin(file->gen.slave, &areas, &ofs, &siz);
        assert(ofs == offset && siz == size);
-       result = snd_pcm_mmap_commit(file->slave, ofs, siz);
+       result = snd_pcm_mmap_commit(file->gen.slave, ofs, siz);
        if (result > 0)
                snd_pcm_file_add_frames(pcm, areas, ofs, result);
        return result;
 }
 
-static snd_pcm_sframes_t snd_pcm_file_avail_update(snd_pcm_t *pcm)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_avail_update(file->slave);
-}
-
-static int snd_pcm_file_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_hw_refine(file->slave, params);
-}
-
 static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
 {
        snd_pcm_file_t *file = pcm->private_data;
@@ -369,14 +266,14 @@ static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
                file->wbuf = 0;
                file->wbuf_areas = 0;
        }
-       return snd_pcm_hw_free(file->slave);
+       return snd_pcm_hw_free(file->gen.slave);
 }
 
 static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 {
        snd_pcm_file_t *file = pcm->private_data;
        unsigned int channel;
-       snd_pcm_t *slave = file->slave;
+       snd_pcm_t *slave = file->gen.slave;
        int err = _snd_pcm_hw_params(slave, params);
        if (err < 0)
                return err;
@@ -404,16 +301,10 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        return 0;
 }
 
-static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
-{
-       snd_pcm_file_t *file = pcm->private_data;
-       return snd_pcm_sw_params(file->slave, params);
-}
-
 static int snd_pcm_file_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       snd_pcm_t *slave = file->slave;
+       snd_pcm_t *slave = file->gen.slave;
        pcm->running_areas = slave->running_areas;
        pcm->stopped_areas = slave->stopped_areas;
        pcm->mmap_channels = slave->mmap_channels;
@@ -442,45 +333,48 @@ static void snd_pcm_file_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(file->slave, out);
+       snd_pcm_dump(file->gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_file_ops = {
        .close = snd_pcm_file_close,
-       .info = snd_pcm_file_info,
-       .hw_refine = snd_pcm_file_hw_refine,
-       .hw_params = snd_pcm_file_hw_params,
+       .info = snd_pcm_generic_info,
+       .hw_refine = snd_pcm_generic_hw_refine,
+       .hw_params = snd_pcm_generic_hw_params,
        .hw_free = snd_pcm_file_hw_free,
-       .sw_params = snd_pcm_file_sw_params,
-       .channel_info = snd_pcm_file_channel_info,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_file_dump,
-       .nonblock = snd_pcm_file_nonblock,
-       .async = snd_pcm_file_async,
-       .poll_revents = snd_pcm_file_poll_revents,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
        .mmap = snd_pcm_file_mmap,
        .munmap = snd_pcm_file_munmap,
 };
 
 static snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
-       .status = snd_pcm_file_status,
-       .state = snd_pcm_file_state,
-       .hwsync = snd_pcm_file_hwsync,
-       .delay = snd_pcm_file_delay,
-       .prepare = snd_pcm_file_prepare,
+       .status = snd_pcm_generic_status,
+       .state = snd_pcm_generic_state,
+       .hwsync = snd_pcm_generic_hwsync,
+       .delay = snd_pcm_generic_delay,
+       .prepare = snd_pcm_generic_prepare,
        .reset = snd_pcm_file_reset,
-       .start = snd_pcm_file_start,
+       .start = snd_pcm_generic_start,
        .drop = snd_pcm_file_drop,
        .drain = snd_pcm_file_drain,
-       .pause = snd_pcm_file_pause,
+       .pause = snd_pcm_generic_pause,
        .rewind = snd_pcm_file_rewind,
        .forward = snd_pcm_file_forward,
-       .resume = snd_pcm_file_resume,
-       .poll_ask = snd_pcm_file_poll_ask,
+       .resume = snd_pcm_generic_resume,
+       .poll_ask = snd_pcm_generic_poll_ask,
+       .link_fd = snd_pcm_generic_link_fd,
+       .link = snd_pcm_generic_link,
+       .unlink = snd_pcm_generic_unlink,
        .writei = snd_pcm_file_writei,
        .writen = snd_pcm_file_writen,
        .readi = snd_pcm_file_readi,
        .readn = snd_pcm_file_readn,
-       .avail_update = snd_pcm_file_avail_update,
+       .avail_update = snd_pcm_generic_avail_update,
        .mmap_commit = snd_pcm_file_mmap_commit,
 };
 
@@ -532,8 +426,8 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
                file->fname = strdup(fname);
        file->fd = fd;
        file->format = format;
-       file->slave = slave;
-       file->close_slave = close_slave;
+       file->gen.slave = slave;
+       file->gen.close_slave = close_slave;
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_FILE, name, slave->stream, slave->mode);
        if (err < 0) {
diff --git a/src/pcm/pcm_generic.c b/src/pcm/pcm_generic.c
new file mode 100644 (file)
index 0000000..44aae85
--- /dev/null
@@ -0,0 +1,257 @@
+/**
+ * \file pcm/pcm_generic.c
+ * \ingroup PCM
+ * \brief PCM Interface
+ * \author Jaroslav Kysela <perex@suse.cz>
+ * \date 2004
+ */
+/*
+ *  PCM - Common generic plugin code
+ *  Copyright (c) 2004 by Jaroslav Kysela <perex@suse.cz> 
+ *
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as
+ *   published by the Free Software Foundation; either version 2.1 of
+ *   the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public
+ *   License along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <sys/shm.h>
+#include <limits.h>
+#include "pcm_local.h"
+#include "pcm_generic.h"
+
+#ifndef DOC_HIDDEN
+
+int snd_pcm_generic_close(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       int err = 0;
+       if (generic->close_slave)
+               err = snd_pcm_close(generic->slave);
+       free(generic);
+       return 0;
+}
+
+int snd_pcm_generic_nonblock(snd_pcm_t *pcm, int nonblock)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_nonblock(generic->slave, nonblock);
+}
+
+int snd_pcm_generic_async(snd_pcm_t *pcm, int sig, pid_t pid)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_async(generic->slave, sig, pid);
+}
+
+int snd_pcm_generic_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_poll_descriptors_revents(generic->slave, pfds, nfds, revents);
+}
+
+int snd_pcm_generic_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_info(generic->slave, info);
+}
+
+int snd_pcm_generic_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_hw_free(generic->slave);
+}
+
+int snd_pcm_generic_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_sw_params(generic->slave, params);
+}
+
+int snd_pcm_generic_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_hw_refine(generic->slave, params);
+}
+
+int snd_pcm_generic_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return _snd_pcm_hw_params(generic->slave, params);
+}
+
+int snd_pcm_generic_prepare(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_prepare(generic->slave);
+}
+
+int snd_pcm_generic_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
+{
+       return snd_pcm_channel_info_shm(pcm, info, -1);
+}
+
+int snd_pcm_generic_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
+{ 
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_status(generic->slave, status);
+}
+
+snd_pcm_state_t snd_pcm_generic_state(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_state(generic->slave);
+}
+
+int snd_pcm_generic_hwsync(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_hwsync(generic->slave);
+}
+
+int snd_pcm_generic_reset(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_reset(generic->slave);
+}
+
+int snd_pcm_generic_start(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_start(generic->slave);
+}
+
+int snd_pcm_generic_drop(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_drop(generic->slave);
+}
+
+int snd_pcm_generic_drain(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_drain(generic->slave);
+}
+
+int snd_pcm_generic_pause(snd_pcm_t *pcm, int enable)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_pause(generic->slave, enable);
+}
+
+int snd_pcm_generic_resume(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_resume(generic->slave);
+}
+
+int snd_pcm_generic_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_delay(generic->slave, delayp);
+}
+
+snd_pcm_sframes_t snd_pcm_generic_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return INTERNAL(snd_pcm_forward)(generic->slave, frames);
+}
+
+snd_pcm_sframes_t snd_pcm_generic_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_rewind(generic->slave, frames);
+}
+
+int snd_pcm_generic_poll_ask(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       if (generic->slave->fast_ops->poll_ask)
+               return generic->slave->fast_ops->poll_ask(generic->slave->fast_op_arg);
+       return 0;
+}
+
+int snd_pcm_generic_link_fd(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       if (generic->slave->fast_ops->link_fd)
+               return generic->slave->fast_ops->link_fd(generic->slave->fast_op_arg);
+       return -ENOSYS;
+}
+
+int snd_pcm_generic_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
+{
+       snd_pcm_generic_t *generic = pcm1->private_data;
+       if (generic->slave->fast_ops->link)
+               return generic->slave->fast_ops->link(generic->slave->fast_op_arg, pcm2);
+       return -ENOSYS;
+}
+
+int snd_pcm_generic_unlink(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       if (generic->slave->fast_ops->unlink)
+               return generic->slave->fast_ops->unlink(generic->slave->fast_op_arg);
+       return -ENOSYS;
+}
+
+snd_pcm_sframes_t snd_pcm_generic_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_writei(generic->slave, buffer, size);
+}
+
+snd_pcm_sframes_t snd_pcm_generic_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_writen(generic->slave, bufs, size);
+}
+
+snd_pcm_sframes_t snd_pcm_generic_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_readi(generic->slave, buffer, size);
+}
+
+snd_pcm_sframes_t snd_pcm_generic_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_readn(generic->slave, bufs, size);
+}
+
+snd_pcm_sframes_t snd_pcm_generic_mmap_commit(snd_pcm_t *pcm, 
+                                             snd_pcm_uframes_t offset,
+                                             snd_pcm_uframes_t size)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_mmap_commit(generic->slave, offset, size);
+}
+
+snd_pcm_sframes_t snd_pcm_generic_avail_update(snd_pcm_t *pcm)
+{
+       snd_pcm_generic_t *generic = pcm->private_data;
+       return snd_pcm_avail_update(generic->slave);
+}
+
+int snd_pcm_generic_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+       return 0;
+}
+
+int snd_pcm_generic_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+       return 0;
+}
+
+#endif /* DOC_HIDDEN */
diff --git a/src/pcm/pcm_generic.h b/src/pcm/pcm_generic.h
new file mode 100644 (file)
index 0000000..202a9fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  PCM - Common generic plugin code
+ *  Copyright (c) 2004 by Jaroslav Kysela <perex@suse.cz>
+ *
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as
+ *   published by the Free Software Foundation; either version 2.1 of
+ *   the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public
+ *   License along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+  
+typedef struct {
+       snd_pcm_t *slave;
+       int close_slave;
+} snd_pcm_generic_t;   
+
+int snd_pcm_generic_close(snd_pcm_t *pcm);
+int snd_pcm_generic_nonblock(snd_pcm_t *pcm, int nonblock);
+int snd_pcm_generic_async(snd_pcm_t *pcm, int sig, pid_t pid);
+int snd_pcm_generic_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+int snd_pcm_generic_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
+int snd_pcm_generic_hw_free(snd_pcm_t *pcm);
+int snd_pcm_generic_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
+int snd_pcm_generic_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_generic_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_generic_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
+int snd_pcm_generic_status(snd_pcm_t *pcm, snd_pcm_status_t * status);
+snd_pcm_state_t snd_pcm_generic_state(snd_pcm_t *pcm);
+int snd_pcm_generic_prepare(snd_pcm_t *pcm);
+int snd_pcm_generic_hwsync(snd_pcm_t *pcm);
+int snd_pcm_generic_reset(snd_pcm_t *pcm);
+int snd_pcm_generic_start(snd_pcm_t *pcm);
+int snd_pcm_generic_drop(snd_pcm_t *pcm);
+int snd_pcm_generic_drain(snd_pcm_t *pcm);
+int snd_pcm_generic_pause(snd_pcm_t *pcm, int enable);
+int snd_pcm_generic_resume(snd_pcm_t *pcm);
+int snd_pcm_generic_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
+snd_pcm_sframes_t snd_pcm_generic_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_generic_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+int snd_pcm_generic_poll_ask(snd_pcm_t *pcm);
+int snd_pcm_generic_link_fd(snd_pcm_t *pcm); 
+int snd_pcm_generic_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
+int snd_pcm_generic_unlink(snd_pcm_t *pcm);
+snd_pcm_sframes_t snd_pcm_generic_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_generic_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_generic_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_generic_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_generic_mmap_commit(snd_pcm_t *pcm,
+                                             snd_pcm_uframes_t offset,
+                                             snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_generic_avail_update(snd_pcm_t *pcm);
+int snd_pcm_generic_mmap(snd_pcm_t *pcm);
+int snd_pcm_generic_munmap(snd_pcm_t *pcm);
index 0cf6d563e6dd6809739de9b0a1c5217920d3d572..e2eaaedb9e4c6f7b608e58a0418d44776fa882c3 100644 (file)
@@ -29,6 +29,7 @@
   
 #include <dlfcn.h>
 #include "pcm_local.h"
+#include "pcm_generic.h"
 
 #ifndef PIC
 /* entry for static linking */
@@ -44,8 +45,7 @@ struct _snd_pcm_hook {
 };
 
 typedef struct {
-       snd_pcm_t *slave;
-       int close_slave;
+       snd_pcm_generic_t gen;
        struct list_head hooks[SND_PCM_HOOK_TYPE_LAST + 1];
 } snd_pcm_hooks_t;
 #endif
@@ -56,11 +56,7 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
        struct list_head *pos, *next;
        unsigned int k;
        int err;
-       if (h->close_slave) {
-               err = snd_pcm_close(h->slave);
-               if (err < 0)
-                       return err;
-       }
+
        list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_TYPE_CLOSE]) {
                snd_pcm_hook_t *hook = list_entry(pos, snd_pcm_hook_t, list);
                err = hook->func(hook);
@@ -76,169 +72,14 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
                        snd_pcm_hook_remove(hook);
                }
        }
-       free(h);
-       return 0;
-}
-
-static int snd_pcm_hooks_nonblock(snd_pcm_t *pcm, int nonblock)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_nonblock(h->slave, nonblock);
-}
-
-static int snd_pcm_hooks_async(snd_pcm_t *pcm, int sig, pid_t pid)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_async(h->slave, sig, pid);
-}
-
-static int snd_pcm_hooks_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_info(h->slave, info);
-}
-
-static int snd_pcm_hooks_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_channel_info(h->slave, info);
-}
-
-static int snd_pcm_hooks_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_status(h->slave, status);
-}
-
-static snd_pcm_state_t snd_pcm_hooks_state(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_state(h->slave);
-}
-
-static int snd_pcm_hooks_hwsync(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_hwsync(h->slave);
-}
-
-static int snd_pcm_hooks_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_delay(h->slave, delayp);
-}
-
-static int snd_pcm_hooks_prepare(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_prepare(h->slave);
-}
-
-static int snd_pcm_hooks_reset(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_reset(h->slave);
-}
-
-static int snd_pcm_hooks_start(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_start(h->slave);
-}
-
-static int snd_pcm_hooks_drop(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_drop(h->slave);
-}
-
-static int snd_pcm_hooks_drain(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_drain(h->slave);
-}
-
-static int snd_pcm_hooks_pause(snd_pcm_t *pcm, int enable)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_pause(h->slave, enable);
-}
-
-static snd_pcm_sframes_t snd_pcm_hooks_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_rewind(h->slave, frames);
-}
-
-static snd_pcm_sframes_t snd_pcm_hooks_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return INTERNAL(snd_pcm_forward)(h->slave, frames);
-}
-
-static int snd_pcm_hooks_resume(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_resume(h->slave);
-}
-
-static int snd_pcm_hooks_poll_ask(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       if (h->slave->fast_ops->poll_ask)
-               return h->slave->fast_ops->poll_ask(h->slave->fast_op_arg);
-       return 0;
-}
-
-static snd_pcm_sframes_t snd_pcm_hooks_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_writei(h->slave, buffer, size);
-}
-
-static snd_pcm_sframes_t snd_pcm_hooks_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_writen(h->slave, bufs, size);
-}
-
-static snd_pcm_sframes_t snd_pcm_hooks_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_readi(h->slave, buffer, size);
-}
-
-static snd_pcm_sframes_t snd_pcm_hooks_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_readn(h->slave, bufs, size);
-}
-
-static snd_pcm_sframes_t snd_pcm_hooks_mmap_commit(snd_pcm_t *pcm,
-                                                  snd_pcm_uframes_t offset,
-                                                  snd_pcm_uframes_t size)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_mmap_commit(h->slave, offset, size);
-}
-
-static snd_pcm_sframes_t snd_pcm_hooks_avail_update(snd_pcm_t *pcm)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_avail_update(h->slave);
-}
-
-static int snd_pcm_hooks_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_hw_refine(h->slave, params);
+       return snd_pcm_generic_close(pcm);
 }
 
 static int snd_pcm_hooks_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
        snd_pcm_hooks_t *h = pcm->private_data;
        struct list_head *pos, *next;
-       int err = snd_pcm_hw_params(h->slave, params);
+       int err = snd_pcm_hw_params(h->gen.slave, params);
        if (err < 0)
                return err;
        list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_TYPE_HW_PARAMS]) {
@@ -254,7 +95,7 @@ static int snd_pcm_hooks_hw_free(snd_pcm_t *pcm)
 {
        snd_pcm_hooks_t *h = pcm->private_data;
        struct list_head *pos, *next;
-       int err = snd_pcm_hw_free(h->slave);
+       int err = snd_pcm_hw_free(h->gen.slave);
        if (err < 0)
                return err;
        list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_TYPE_HW_FREE]) {
@@ -266,22 +107,6 @@ static int snd_pcm_hooks_hw_free(snd_pcm_t *pcm)
        return 0;
 }
 
-static int snd_pcm_hooks_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
-{
-       snd_pcm_hooks_t *h = pcm->private_data;
-       return snd_pcm_sw_params(h->slave, params);
-}
-
-static int snd_pcm_hooks_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
-       return 0;
-}
-
-static int snd_pcm_hooks_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
-       return 0;
-}
-
 static void snd_pcm_hooks_dump(snd_pcm_t *pcm, snd_output_t *out)
 {
        snd_pcm_hooks_t *h = pcm->private_data;
@@ -291,45 +116,48 @@ static void snd_pcm_hooks_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(h->slave, out);
+       snd_pcm_dump(h->gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_hooks_ops = {
        .close = snd_pcm_hooks_close,
-       .info = snd_pcm_hooks_info,
-       .hw_refine = snd_pcm_hooks_hw_refine,
+       .info = snd_pcm_generic_info,
+       .hw_refine = snd_pcm_generic_hw_refine,
        .hw_params = snd_pcm_hooks_hw_params,
        .hw_free = snd_pcm_hooks_hw_free,
-       .sw_params = snd_pcm_hooks_sw_params,
-       .channel_info = snd_pcm_hooks_channel_info,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_hooks_dump,
-       .nonblock = snd_pcm_hooks_nonblock,
-       .async = snd_pcm_hooks_async,
-       .mmap = snd_pcm_hooks_mmap,
-       .munmap = snd_pcm_hooks_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 static snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
-       .status = snd_pcm_hooks_status,
-       .state = snd_pcm_hooks_state,
-       .hwsync = snd_pcm_hooks_hwsync,
-       .delay = snd_pcm_hooks_delay,
-       .prepare = snd_pcm_hooks_prepare,
-       .reset = snd_pcm_hooks_reset,
-       .start = snd_pcm_hooks_start,
-       .drop = snd_pcm_hooks_drop,
-       .drain = snd_pcm_hooks_drain,
-       .pause = snd_pcm_hooks_pause,
-       .rewind = snd_pcm_hooks_rewind,
-       .forward = snd_pcm_hooks_forward,
-       .resume = snd_pcm_hooks_resume,
-       .poll_ask = snd_pcm_hooks_poll_ask,
-       .writei = snd_pcm_hooks_writei,
-       .writen = snd_pcm_hooks_writen,
-       .readi = snd_pcm_hooks_readi,
-       .readn = snd_pcm_hooks_readn,
-       .avail_update = snd_pcm_hooks_avail_update,
-       .mmap_commit = snd_pcm_hooks_mmap_commit,
+       .status = snd_pcm_generic_status,
+       .state = snd_pcm_generic_state,
+       .hwsync = snd_pcm_generic_hwsync,
+       .delay = snd_pcm_generic_delay,
+       .prepare = snd_pcm_generic_prepare,
+       .reset = snd_pcm_generic_reset,
+       .start = snd_pcm_generic_start,
+       .drop = snd_pcm_generic_drop,
+       .drain = snd_pcm_generic_drain,
+       .pause = snd_pcm_generic_pause,
+       .rewind = snd_pcm_generic_rewind,
+       .forward = snd_pcm_generic_forward,
+       .resume = snd_pcm_generic_resume,
+       .poll_ask = snd_pcm_generic_poll_ask,
+       .link_fd = snd_pcm_generic_link_fd,
+       .link = snd_pcm_generic_link,
+       .unlink = snd_pcm_generic_unlink,
+       .writei = snd_pcm_generic_writei,
+       .writen = snd_pcm_generic_writen,
+       .readi = snd_pcm_generic_readi,
+       .readn = snd_pcm_generic_readn,
+       .avail_update = snd_pcm_generic_avail_update,
+       .mmap_commit = snd_pcm_generic_mmap_commit,
 };
 
 /**
@@ -353,8 +181,8 @@ int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
        h = calloc(1, sizeof(snd_pcm_hooks_t));
        if (!h)
                return -ENOMEM;
-       h->slave = slave;
-       h->close_slave = close_slave;
+       h->gen.slave = slave;
+       h->gen.close_slave = close_slave;
        for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++k) {
                INIT_LIST_HEAD(&h->hooks[k]);
        }
index cf6abe66ec3e686e9acfbfdd5ed173d3ca919c8d..b3b028004acdd57376eac3637f3e4281119bd48c 100644 (file)
@@ -656,6 +656,38 @@ static int snd_pcm_hw_resume(snd_pcm_t *pcm)
        return 0;
 }
 
+static int snd_pcm_hw_link_fd(snd_pcm_t *pcm)
+{
+       snd_pcm_hw_t *hw = pcm->private_data;
+
+       return hw->fd;
+}
+
+static int snd_pcm_hw_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
+{
+       snd_pcm_hw_t *hw = pcm1->private_data;
+       int fd2 = _snd_pcm_link_descriptor(pcm2);
+
+       if (fd2 < 0)
+               return -ENOSYS;
+       if (ioctl(hw->fd, SNDRV_PCM_IOCTL_LINK, fd2) < 0) {
+               SYSMSG("SNDRV_PCM_IOCTL_LINK failed");
+               return -errno;
+       }
+       return 0;
+}
+
+static int snd_pcm_hw_unlink(snd_pcm_t *pcm)
+{
+       snd_pcm_hw_t *hw = pcm->private_data;
+
+       if (ioctl(hw->fd, SNDRV_PCM_IOCTL_UNLINK) < 0) {
+               SYSMSG("SNDRV_PCM_IOCTL_UNLINK failed");
+               return -errno;
+       }
+       return 0;
+}
+
 static snd_pcm_sframes_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
        int err;
@@ -970,6 +1002,9 @@ static snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
        .forward = snd_pcm_hw_forward,
        .resume = snd_pcm_hw_resume,
        .poll_ask = NULL,
+       .link_fd = snd_pcm_hw_link_fd,
+       .link = snd_pcm_hw_link,
+       .unlink = snd_pcm_hw_unlink,
        .writei = snd_pcm_hw_writei,
        .writen = snd_pcm_hw_writen,
        .readi = snd_pcm_hw_readi,
index a87846c052203ba32fd682bc1fade22dcbbab4fb..04ec48c2ba3e00ee5ddd42649ce5511f0318e349 100644 (file)
@@ -305,7 +305,7 @@ static int snd_pcm_iec958_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_iec958_hw_refine_cchange,
                                       snd_pcm_iec958_hw_refine_sprepare,
                                       snd_pcm_iec958_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_iec958_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
@@ -316,7 +316,7 @@ static int snd_pcm_iec958_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params
                                          snd_pcm_iec958_hw_refine_cchange,
                                          snd_pcm_iec958_hw_refine_sprepare,
                                          snd_pcm_iec958_hw_refine_schange,
-                                         snd_pcm_plugin_hw_params_slave);
+                                         snd_pcm_generic_hw_params);
        if (err < 0)
                return err;
 
@@ -409,23 +409,23 @@ static void snd_pcm_iec958_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(iec->plug.slave, out);
+       snd_pcm_dump(iec->plug.gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_iec958_ops = {
-       .close = snd_pcm_plugin_close,
-       .info = snd_pcm_plugin_info,
+       .close = snd_pcm_generic_close,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_iec958_hw_refine,
        .hw_params = snd_pcm_iec958_hw_params,
-       .hw_free = snd_pcm_plugin_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .hw_free = snd_pcm_generic_hw_free,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_iec958_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 /**
@@ -471,8 +471,8 @@ int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
        iec->plug.init = snd_pcm_iec958_init;
        iec->plug.undo_read = snd_pcm_plugin_undo_read_generic;
        iec->plug.undo_write = snd_pcm_plugin_undo_write_generic;
-       iec->plug.slave = slave;
-       iec->plug.close_slave = close_slave;
+       iec->plug.gen.slave = slave;
+       iec->plug.gen.close_slave = close_slave;
 
        if (status_bits)
                memcpy(iec->status, status_bits, sizeof(iec->status));
index 5ff8236936ef32c329f783df36b8c37b65ff047d..3452a3b7eb37d79de7f98a3632fbad1340013ecc 100644 (file)
@@ -175,7 +175,7 @@ static int snd_pcm_ladspa_close(snd_pcm_t *pcm)
        snd_pcm_ladspa_t *ladspa = pcm->private_data;
 
        snd_pcm_ladspa_free(ladspa);
-       return snd_pcm_plugin_close(pcm);
+       return snd_pcm_generic_close(pcm);
 }
 
 static int snd_pcm_ladspa_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
@@ -252,7 +252,7 @@ static int snd_pcm_ladspa_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_ladspa_hw_refine_cchange,
                                       snd_pcm_ladspa_hw_refine_sprepare,
                                       snd_pcm_ladspa_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_ladspa_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
@@ -262,7 +262,7 @@ static int snd_pcm_ladspa_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params
                                          snd_pcm_ladspa_hw_refine_cchange,
                                          snd_pcm_ladspa_hw_refine_sprepare,
                                          snd_pcm_ladspa_hw_refine_schange,
-                                         snd_pcm_plugin_hw_params_slave);
+                                         snd_pcm_generic_hw_params);
        if (err < 0)
                return err;
        return 0;
@@ -554,7 +554,7 @@ static int snd_pcm_ladspa_hw_free(snd_pcm_t *pcm)
        snd_pcm_ladspa_t *ladspa = pcm->private_data;
 
        snd_pcm_ladspa_free_instances(pcm, ladspa, 1);
-       return snd_pcm_plugin_hw_free(pcm);
+       return snd_pcm_generic_hw_free(pcm);
 }
 
 static snd_pcm_uframes_t
@@ -693,23 +693,23 @@ static void snd_pcm_ladspa_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(ladspa->plug.slave, out);
+       snd_pcm_dump(ladspa->plug.gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_ladspa_ops = {
        .close = snd_pcm_ladspa_close,
-       .info = snd_pcm_plugin_info,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_ladspa_hw_refine,
        .hw_params = snd_pcm_ladspa_hw_params,
        .hw_free = snd_pcm_ladspa_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_ladspa_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 static int snd_pcm_ladspa_check_file(snd_pcm_ladspa_plugin_t * const plugin,
@@ -1149,8 +1149,8 @@ int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
        ladspa->plug.write = snd_pcm_ladspa_write_areas;
        ladspa->plug.undo_read = snd_pcm_plugin_undo_read_generic;
        ladspa->plug.undo_write = snd_pcm_plugin_undo_write_generic;
-       ladspa->plug.slave = slave;
-       ladspa->plug.close_slave = close_slave;
+       ladspa->plug.gen.slave = slave;
+       ladspa->plug.gen.close_slave = close_slave;
 
        INIT_LIST_HEAD(&ladspa->pplugins);
        INIT_LIST_HEAD(&ladspa->cplugins);
index 218d6c4551d32234fe744924df0b62d14246bee5..b394b59b358daca53c229be08db0cdd5a362861b 100644 (file)
@@ -261,19 +261,19 @@ static int snd_pcm_lfloat_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_lfloat_hw_refine_cchange,
                                       snd_pcm_lfloat_hw_refine_sprepare,
                                       snd_pcm_lfloat_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_lfloat_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
        snd_pcm_lfloat_t *lfloat = pcm->private_data;
-       snd_pcm_t *slave = lfloat->plug.slave;
+       snd_pcm_t *slave = lfloat->plug.gen.slave;
        snd_pcm_format_t src_format, dst_format;
        int err = snd_pcm_hw_params_slave(pcm, params,
                                          snd_pcm_lfloat_hw_refine_cchange,
                                          snd_pcm_lfloat_hw_refine_sprepare,
                                          snd_pcm_lfloat_hw_refine_schange,
-                                         snd_pcm_plugin_hw_params_slave);
+                                         snd_pcm_generic_hw_refine);
        if (err < 0)
                return err;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
@@ -345,23 +345,23 @@ static void snd_pcm_lfloat_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(lfloat->plug.slave, out);
+       snd_pcm_dump(lfloat->plug.gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_lfloat_ops = {
-       .close = snd_pcm_plugin_close,
-       .info = snd_pcm_plugin_info,
+       .close = snd_pcm_generic_close,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_lfloat_hw_refine,
        .hw_params = snd_pcm_lfloat_hw_params,
-       .hw_free = snd_pcm_plugin_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .hw_free = snd_pcm_generic_hw_free,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_lfloat_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 /**
@@ -395,8 +395,8 @@ int snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
        lfloat->plug.write = snd_pcm_lfloat_write_areas;
        lfloat->plug.undo_read = snd_pcm_plugin_undo_read_generic;
        lfloat->plug.undo_write = snd_pcm_plugin_undo_write_generic;
-       lfloat->plug.slave = slave;
-       lfloat->plug.close_slave = close_slave;
+       lfloat->plug.gen.slave = slave;
+       lfloat->plug.gen.close_slave = close_slave;
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_LINEAR_FLOAT, name, slave->stream, slave->mode);
        if (err < 0) {
index 27b7bfa10850c6ea67534611435b938708d8ca08..03739238c7f32c2769015dce51d0973a6c2b283f 100644 (file)
@@ -304,7 +304,7 @@ static int snd_pcm_linear_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_linear_hw_refine_cchange,
                                       snd_pcm_linear_hw_refine_sprepare,
                                       snd_pcm_linear_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_linear_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
@@ -315,7 +315,7 @@ static int snd_pcm_linear_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                          snd_pcm_linear_hw_refine_cchange,
                                          snd_pcm_linear_hw_refine_sprepare,
                                          snd_pcm_linear_hw_refine_schange,
-                                         snd_pcm_plugin_hw_params_slave);
+                                         snd_pcm_generic_hw_params);
        if (err < 0)
                return err;
        err = INTERNAL(snd_pcm_hw_params_get_format)(params, &format);
@@ -402,23 +402,23 @@ static void snd_pcm_linear_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(linear->plug.slave, out);
+       snd_pcm_dump(linear->plug.gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_linear_ops = {
-       .close = snd_pcm_plugin_close,
-       .info = snd_pcm_plugin_info,
+       .close = snd_pcm_generic_close,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_linear_hw_refine,
        .hw_params = snd_pcm_linear_hw_params,
-       .hw_free = snd_pcm_plugin_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .hw_free = snd_pcm_generic_hw_free,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_linear_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 
@@ -452,8 +452,8 @@ int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
        linear->plug.write = snd_pcm_linear_write_areas;
        linear->plug.undo_read = snd_pcm_plugin_undo_read_generic;
        linear->plug.undo_write = snd_pcm_plugin_undo_write_generic;
-       linear->plug.slave = slave;
-       linear->plug.close_slave = close_slave;
+       linear->plug.gen.slave = slave;
+       linear->plug.gen.close_slave = close_slave;
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_LINEAR, name, slave->stream, slave->mode);
        if (err < 0) {
index f53dc6726fd8a34d430f5567613fad900af34b16..5b9ef3b21a374950de1962aa6d9e9d14c33c072c 100644 (file)
@@ -152,6 +152,9 @@ typedef struct {
        int (*delay)(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
        int (*resume)(snd_pcm_t *pcm);
        int (*poll_ask)(snd_pcm_t *pcm);
+       int (*link_fd)(snd_pcm_t *pcm);
+       int (*link)(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
+       int (*unlink)(snd_pcm_t *pcm);
        snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
        snd_pcm_sframes_t (*forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
        snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
@@ -218,10 +221,6 @@ struct _snd_pcm {
        struct list_head async_handlers;
 };
 
-/* FIXME */
-#define _snd_pcm_link_descriptor _snd_pcm_poll_descriptor
-#define _snd_pcm_async_descriptor _snd_pcm_poll_descriptor
-
 int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
                snd_pcm_stream_t stream, int mode);
 int snd_pcm_free(snd_pcm_t *pcm);
@@ -266,6 +265,8 @@ snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size);
 int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);
 int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int shmid);
 int _snd_pcm_poll_descriptor(snd_pcm_t *pcm);
+int _snd_pcm_link_descriptor(snd_pcm_t *pcm);
+#define _snd_pcm_async_descriptor _snd_pcm_poll_descriptor /* FIXME */
 
 /* handle special error cases */
 static inline int snd_pcm_check_error(snd_pcm_t *pcm, int err)
@@ -820,4 +821,3 @@ typedef union snd_tmp_double {
        double d;
        int64_t l;
 } snd_tmp_double_t;
-
index 8d9baf73c6fdb7e3c870d9882183176f0b579265..39564a38517666113bbaf5df3504f8f446e61d0a 100644 (file)
@@ -312,7 +312,7 @@ static int snd_pcm_mulaw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_mulaw_hw_refine_cchange,
                                       snd_pcm_mulaw_hw_refine_sprepare,
                                       snd_pcm_mulaw_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
@@ -323,7 +323,7 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                                          snd_pcm_mulaw_hw_refine_cchange,
                                          snd_pcm_mulaw_hw_refine_sprepare,
                                          snd_pcm_mulaw_hw_refine_schange,
-                                         snd_pcm_plugin_hw_params_slave);
+                                         snd_pcm_generic_hw_params);
        if (err < 0)
                return err;
 
@@ -401,23 +401,23 @@ static void snd_pcm_mulaw_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(mulaw->plug.slave, out);
+       snd_pcm_dump(mulaw->plug.gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_mulaw_ops = {
-       .close = snd_pcm_plugin_close,
-       .info = snd_pcm_plugin_info,
+       .close = snd_pcm_generic_close,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_mulaw_hw_refine,
        .hw_params = snd_pcm_mulaw_hw_params,
-       .hw_free = snd_pcm_plugin_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .hw_free = snd_pcm_generic_hw_free,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_mulaw_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 /**
@@ -451,8 +451,8 @@ int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
        mulaw->plug.write = snd_pcm_mulaw_write_areas;
        mulaw->plug.undo_read = snd_pcm_plugin_undo_read_generic;
        mulaw->plug.undo_write = snd_pcm_plugin_undo_write_generic;
-       mulaw->plug.slave = slave;
-       mulaw->plug.close_slave = close_slave;
+       mulaw->plug.gen.slave = slave;
+       mulaw->plug.gen.close_slave = close_slave;
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_MULAW, name, slave->stream, slave->mode);
        if (err < 0) {
index 60eb2df03d8f10742e8f17dbce4d1db5430d0882..0c18e7e23afd4e8451f0634948d42f133f9e6687 100644 (file)
@@ -45,9 +45,8 @@ enum snd_pcm_plug_route_policy {
 };
 
 typedef struct {
+       snd_pcm_generic_t gen;
        snd_pcm_t *req_slave;
-       int close_slave;
-       snd_pcm_t *slave;
        snd_pcm_format_t sformat;
        int schannels;
        int srate;
@@ -65,11 +64,11 @@ static int snd_pcm_plug_close(snd_pcm_t *pcm)
        int err, result = 0;
        if (plug->ttable)
                free(plug->ttable);
-       if (plug->slave != plug->req_slave) {
+       if (plug->gen.slave != plug->req_slave) {
                SNDERR("plug slaves mismatch");
                return -EINVAL;
        }
-       if (plug->close_slave) {
+       if (plug->gen.close_slave) {
                snd_pcm_unlink_hw_ptr(pcm, plug->req_slave);
                snd_pcm_unlink_appl_ptr(pcm, plug->req_slave);
                err = snd_pcm_close(plug->req_slave);
@@ -80,24 +79,6 @@ static int snd_pcm_plug_close(snd_pcm_t *pcm)
        return result;
 }
 
-static int snd_pcm_plug_nonblock(snd_pcm_t *pcm, int nonblock)
-{
-       snd_pcm_plug_t *plug = pcm->private_data;
-       return snd_pcm_nonblock(plug->slave, nonblock);
-}
-
-static int snd_pcm_plug_async(snd_pcm_t *pcm, int sig, pid_t pid)
-{
-       snd_pcm_plug_t *plug = pcm->private_data;
-       return snd_pcm_async(plug->slave, sig, pid);
-}
-
-static int snd_pcm_plug_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
-{
-       snd_pcm_plug_t *plug = pcm->private_data;
-       return snd_pcm_poll_descriptors_revents(plug->slave, pfds, nfds, revents);
-}
-
 static int snd_pcm_plug_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
 {
        snd_pcm_plug_t *plug = pcm->private_data;
@@ -320,11 +301,11 @@ static void snd_pcm_plug_clear(snd_pcm_t *pcm)
        snd_pcm_plug_t *plug = pcm->private_data;
        snd_pcm_t *slave = plug->req_slave;
        /* Clear old plugins */
-       if (plug->slave != slave) {
-               snd_pcm_unlink_hw_ptr(pcm, plug->slave);
-               snd_pcm_unlink_appl_ptr(pcm, plug->slave);
-               snd_pcm_close(plug->slave);
-               plug->slave = slave;
+       if (plug->gen.slave != slave) {
+               snd_pcm_unlink_hw_ptr(pcm, plug->gen.slave);
+               snd_pcm_unlink_appl_ptr(pcm, plug->gen.slave);
+               snd_pcm_close(plug->gen.slave);
+               plug->gen.slave = slave;
                pcm->fast_ops = slave->fast_ops;
                pcm->fast_op_arg = slave->fast_op_arg;
        }
@@ -344,7 +325,7 @@ static int snd_pcm_plug_change_rate(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_plu
        assert(snd_pcm_format_linear(slv->format));
        if (clt->rate == slv->rate)
                return 0;
-       err = snd_pcm_rate_open(new, NULL, slv->format, slv->rate, plug->slave, plug->slave != plug->req_slave);
+       err = snd_pcm_rate_open(new, NULL, slv->format, slv->rate, plug->gen.slave, plug->gen.slave != plug->req_slave);
        if (err < 0)
                return err;
        slv->access = clt->access;
@@ -445,7 +426,7 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm
                        break;
                }
        }
-       err = snd_pcm_route_open(new, NULL, slv->format, (int) slv->channels, ttable, tt_ssize, tt_cused, tt_sused, plug->slave, plug->slave != plug->req_slave);
+       err = snd_pcm_route_open(new, NULL, slv->format, (int) slv->channels, ttable, tt_ssize, tt_cused, tt_sused, plug->gen.slave, plug->gen.slave != plug->req_slave);
        if (err < 0)
                return err;
        slv->channels = clt->channels;
@@ -525,7 +506,7 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
                else
                        cfmt = SND_PCM_FORMAT_S16;
        }
-       err = f(new, NULL, slv->format, plug->slave, plug->slave != plug->req_slave);
+       err = f(new, NULL, slv->format, plug->gen.slave, plug->gen.slave != plug->req_slave);
        if (err < 0)
                return err;
        slv->format = cfmt;
@@ -539,7 +520,7 @@ static int snd_pcm_plug_change_access(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
        int err;
        if (clt->access == slv->access)
                return 0;
-       err = snd_pcm_copy_open(new, NULL, plug->slave, plug->slave != plug->req_slave);
+       err = snd_pcm_copy_open(new, NULL, plug->gen.slave, plug->gen.slave != plug->req_slave);
        if (err < 0)
                return err;
        slv->access = clt->access;
@@ -575,7 +556,7 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm,
                        return err;
                }
                if (err) {
-                       plug->slave = new;
+                       plug->gen.slave = new;
                        pcm->fast_ops = new->fast_ops;
                        pcm->fast_op_arg = new->fast_op_arg;
                }
@@ -593,7 +574,7 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm,
                }
                assert(err);
                assert(plug->ttable_ok);
-               plug->slave = new;
+               plug->gen.slave = new;
                pcm->fast_ops = new->fast_ops;
                pcm->fast_op_arg = new->fast_op_arg;
        }
@@ -908,7 +889,7 @@ static int snd_pcm_plug_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                if (err < 0)
                        return err;
        }
-       slave = plug->slave;
+       slave = plug->gen.slave;
        err = _snd_pcm_hw_params(slave, params);
        if (err < 0) {
                snd_pcm_plug_clear(pcm);
@@ -924,30 +905,18 @@ static int snd_pcm_plug_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 static int snd_pcm_plug_hw_free(snd_pcm_t *pcm)
 {
        snd_pcm_plug_t *plug = pcm->private_data;
-       snd_pcm_t *slave = plug->slave;
+       snd_pcm_t *slave = plug->gen.slave;
        int err = snd_pcm_hw_free(slave);
        snd_pcm_plug_clear(pcm);
        return err;
 }
 
-static int snd_pcm_plug_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
-{
-       snd_pcm_plug_t *plug = pcm->private_data;
-       return snd_pcm_sw_params(plug->slave, params);
-}
-
-static int snd_pcm_plug_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
-{
-       snd_pcm_plug_t *plug = pcm->private_data;
-       return snd_pcm_channel_info(plug->slave, info);
-}
-
 static int snd_pcm_plug_mmap(snd_pcm_t *pcm)
 {
        snd_pcm_plug_t *plug = pcm->private_data;
-       pcm->mmap_channels = plug->slave->mmap_channels;
-       pcm->running_areas = plug->slave->running_areas;
-       pcm->stopped_areas = plug->slave->stopped_areas;
+       pcm->mmap_channels = plug->gen.slave->mmap_channels;
+       pcm->running_areas = plug->gen.slave->running_areas;
+       pcm->stopped_areas = plug->gen.slave->stopped_areas;
        pcm->mmap_shadow = 1;
        return 0;
 }
@@ -966,7 +935,7 @@ static void snd_pcm_plug_dump(snd_pcm_t *pcm, snd_output_t *out)
 {
        snd_pcm_plug_t *plug = pcm->private_data;
        snd_output_printf(out, "Plug PCM: ");
-       snd_pcm_dump(plug->slave, out);
+       snd_pcm_dump(plug->gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_plug_ops = {
@@ -975,12 +944,12 @@ static snd_pcm_ops_t snd_pcm_plug_ops = {
        .hw_refine = snd_pcm_plug_hw_refine,
        .hw_params = snd_pcm_plug_hw_params,
        .hw_free = snd_pcm_plug_hw_free,
-       .sw_params = snd_pcm_plug_sw_params,
-       .channel_info = snd_pcm_plug_channel_info,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_plug_dump,
-       .nonblock = snd_pcm_plug_nonblock,
-       .async = snd_pcm_plug_async,
-       .poll_revents = snd_pcm_plug_poll_revents,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
        .mmap = snd_pcm_plug_mmap,
        .munmap = snd_pcm_plug_munmap,
 };
@@ -1017,8 +986,8 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
        plug->sformat = sformat;
        plug->schannels = schannels;
        plug->srate = srate;
-       plug->slave = plug->req_slave = slave;
-       plug->close_slave = close_slave;
+       plug->gen.slave = plug->req_slave = slave;
+       plug->gen.close_slave = close_slave;
        plug->route_policy = route_policy;
        plug->ttable = ttable;
        plug->tt_ssize = tt_ssize;
index d8a5a0287b8c65919183817c6508af216de4412d..68dd4d460c963e51dbb3f538d3393916544d4d96 100644 (file)
@@ -137,74 +137,11 @@ void snd_pcm_plugin_init(snd_pcm_plugin_t *plugin)
        snd_atomic_write_init(&plugin->watom);
 }
 
-int snd_pcm_plugin_close(snd_pcm_t *pcm)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       int err = 0;
-       if (plugin->close_slave)
-               err = snd_pcm_close(plugin->slave);
-       free(plugin);
-       return 0;
-}
-
-int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_nonblock(plugin->slave, nonblock);
-}
-
-int snd_pcm_plugin_async(snd_pcm_t *pcm, int sig, pid_t pid)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_async(plugin->slave, sig, pid);
-}
-
-int snd_pcm_plugin_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_poll_descriptors_revents(plugin->slave, pfds, nfds, revents);
-}
-
-int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_info(plugin->slave, info);
-}
-
-int snd_pcm_plugin_hw_free(snd_pcm_t *pcm)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_hw_free(plugin->slave);
-}
-
-int snd_pcm_plugin_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_sw_params(plugin->slave, params);
-}
-
-int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
-{
-       return snd_pcm_channel_info_shm(pcm, info, -1);
-}
-
-snd_pcm_state_t snd_pcm_plugin_state(snd_pcm_t *pcm)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_state(plugin->slave);
-}
-
-int snd_pcm_plugin_hwsync(snd_pcm_t *pcm)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_hwsync(plugin->slave);
-}
-
 int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
        snd_pcm_sframes_t sd;
-       int err = snd_pcm_delay(plugin->slave, &sd);
+       int err = snd_pcm_delay(plugin->gen.slave, &sd);
        if (err < 0)
                return err;
        if (plugin->client_frames)
@@ -218,7 +155,7 @@ int snd_pcm_plugin_prepare(snd_pcm_t *pcm)
        snd_pcm_plugin_t *plugin = pcm->private_data;
        int err;
        snd_atomic_write_begin(&plugin->watom);
-       err = snd_pcm_prepare(plugin->slave);
+       err = snd_pcm_prepare(plugin->gen.slave);
        if (err < 0) {
                snd_atomic_write_end(&plugin->watom);
                return err;
@@ -239,7 +176,7 @@ static int snd_pcm_plugin_reset(snd_pcm_t *pcm)
        snd_pcm_plugin_t *plugin = pcm->private_data;
        int err;
        snd_atomic_write_begin(&plugin->watom);
-       err = snd_pcm_reset(plugin->slave);
+       err = snd_pcm_reset(plugin->gen.slave);
        if (err < 0) {
                snd_atomic_write_end(&plugin->watom);
                return err;
@@ -255,30 +192,6 @@ static int snd_pcm_plugin_reset(snd_pcm_t *pcm)
        return 0;
 }
 
-int snd_pcm_plugin_start(snd_pcm_t *pcm)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_start(plugin->slave);
-}
-
-int snd_pcm_plugin_drop(snd_pcm_t *pcm)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_drop(plugin->slave);
-}
-
-int snd_pcm_plugin_drain(snd_pcm_t *pcm)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_drain(plugin->slave);
-}
-
-int snd_pcm_plugin_pause(snd_pcm_t *pcm, int enable)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_pause(plugin->slave, enable);
-}
-
 snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
@@ -296,7 +209,7 @@ snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames
        else
                sframes = frames;
        snd_atomic_write_begin(&plugin->watom);
-       sframes = snd_pcm_rewind(plugin->slave, sframes);
+       sframes = snd_pcm_rewind(plugin->gen.slave, sframes);
        if (sframes < 0) {
                snd_atomic_write_end(&plugin->watom);
                return sframes;
@@ -325,7 +238,7 @@ snd_pcm_sframes_t snd_pcm_plugin_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frame
        else
                sframes = frames;
        snd_atomic_write_begin(&plugin->watom);
-       sframes = INTERNAL(snd_pcm_forward)(plugin->slave, (snd_pcm_uframes_t) sframes);
+       sframes = INTERNAL(snd_pcm_forward)(plugin->gen.slave, (snd_pcm_uframes_t) sframes);
        if ((snd_pcm_sframes_t) sframes < 0) {
                snd_atomic_write_end(&plugin->watom);
                return sframes;
@@ -337,27 +250,13 @@ snd_pcm_sframes_t snd_pcm_plugin_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frame
        return n;
 }
 
-int snd_pcm_plugin_resume(snd_pcm_t *pcm)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_resume(plugin->slave);
-}
-
-int snd_pcm_plugin_poll_ask(snd_pcm_t *pcm)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       if (plugin->slave->fast_ops->poll_ask)
-               return plugin->slave->fast_ops->poll_ask(plugin->slave->fast_op_arg);
-       return 0;
-}
-
 static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
                                                    const snd_pcm_channel_area_t *areas,
                                                    snd_pcm_uframes_t offset,
                                                    snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
-       snd_pcm_t *slave = plugin->slave;
+       snd_pcm_t *slave = plugin->gen.slave;
        snd_pcm_uframes_t xfer = 0;
        snd_pcm_sframes_t result;
        int err;
@@ -404,7 +303,7 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
                                                   snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
-       snd_pcm_t *slave = plugin->slave;
+       snd_pcm_t *slave = plugin->gen.slave;
        snd_pcm_uframes_t xfer = 0;
        snd_pcm_sframes_t result;
        
@@ -483,7 +382,7 @@ snd_pcm_sframes_t snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
                                             snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
-       snd_pcm_t *slave = plugin->slave;
+       snd_pcm_t *slave = plugin->gen.slave;
        const snd_pcm_channel_area_t *areas;
        snd_pcm_uframes_t appl_offset;
        snd_pcm_sframes_t slave_size;
@@ -549,7 +448,7 @@ snd_pcm_sframes_t snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
 snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
-       snd_pcm_t *slave = plugin->slave;
+       snd_pcm_t *slave = plugin->gen.slave;
        snd_pcm_sframes_t slave_size;
 
        slave_size = snd_pcm_avail_update(slave);
@@ -617,16 +516,6 @@ snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
        }
 }
 
-int snd_pcm_plugin_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
-       return 0;
-}
-
-int snd_pcm_plugin_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
-       return 0;
-}
-
 int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
 {
        snd_pcm_plugin_t *plugin = pcm->private_data;
@@ -635,7 +524,7 @@ int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
        snd_atomic_read_init(&ratom, &plugin->watom);
  _again:
        snd_atomic_read_begin(&ratom);
-       err = snd_pcm_status(plugin->slave, status);
+       err = snd_pcm_status(plugin->gen.slave, status);
        if (err < 0) {
                snd_atomic_read_ok(&ratom);
                return err;
@@ -655,33 +544,24 @@ int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
        return 0;
 }
 
-int snd_pcm_plugin_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return snd_pcm_hw_refine(plugin->slave, params);
-}
-
-int snd_pcm_plugin_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
-       snd_pcm_plugin_t *plugin = pcm->private_data;
-       return _snd_pcm_hw_params(plugin->slave, params);
-}
-
 snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
-       .status = snd_pcm_plugin_status,
-       .state = snd_pcm_plugin_state,
-       .hwsync = snd_pcm_plugin_hwsync,
+       .status = snd_pcm_generic_status,
+       .state = snd_pcm_generic_state,
+       .hwsync = snd_pcm_generic_hwsync,
        .delay = snd_pcm_plugin_delay,
        .prepare = snd_pcm_plugin_prepare,
        .reset = snd_pcm_plugin_reset,
-       .start = snd_pcm_plugin_start,
-       .drop = snd_pcm_plugin_drop,
-       .drain = snd_pcm_plugin_drain,
-       .pause = snd_pcm_plugin_pause,
+       .start = snd_pcm_generic_start,
+       .drop = snd_pcm_generic_drop,
+       .drain = snd_pcm_generic_drain,
+       .pause = snd_pcm_generic_pause,
        .rewind = snd_pcm_plugin_rewind,
        .forward = snd_pcm_plugin_forward,
-       .resume = snd_pcm_plugin_resume,
-       .poll_ask = snd_pcm_plugin_poll_ask,
+       .resume = snd_pcm_generic_resume,
+       .poll_ask = snd_pcm_generic_poll_ask,
+       .link_fd = snd_pcm_generic_link_fd,
+       .link = snd_pcm_generic_link,
+       .unlink = snd_pcm_generic_unlink,
        .writei = snd_pcm_plugin_writei,
        .writen = snd_pcm_plugin_writen,
        .readi = snd_pcm_plugin_readi,
@@ -690,5 +570,4 @@ snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
        .mmap_commit = snd_pcm_plugin_mmap_commit,
 };
 
-
 #endif
index a4353c51104f9a340b7912b28a9b32d72242f739..045d4dbd4642c54da6906c8d9e2583d24a4a38e0 100644 (file)
@@ -20,6 +20,7 @@
  */
   
 #include "iatomic.h"
+#include "pcm_generic.h"
 
 typedef snd_pcm_uframes_t (*snd_pcm_slave_xfer_areas_func_t)
      (snd_pcm_t *pcm, 
@@ -38,8 +39,7 @@ typedef snd_pcm_sframes_t (*snd_pcm_slave_xfer_areas_undo_func_t)
       snd_pcm_uframes_t slave_undo_size);
 
 typedef struct {
-       snd_pcm_t *slave;
-       int close_slave;
+       snd_pcm_generic_t gen;
        snd_pcm_slave_xfer_areas_func_t read;
        snd_pcm_slave_xfer_areas_func_t write;
        snd_pcm_slave_xfer_areas_undo_func_t undo_read;
@@ -52,24 +52,9 @@ typedef struct {
 } snd_pcm_plugin_t;    
 
 void snd_pcm_plugin_init(snd_pcm_plugin_t *plugin);
-int snd_pcm_plugin_close(snd_pcm_t *pcm);
-int snd_pcm_plugin_card(snd_pcm_t *pcm);
-int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock);
-int snd_pcm_plugin_async(snd_pcm_t *pcm, int sig, pid_t pid);
-int snd_pcm_plugin_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
-int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
-int snd_pcm_plugin_hw_free(snd_pcm_t *pcm);
-int snd_pcm_plugin_sw_refine(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
-int snd_pcm_plugin_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
-int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
 int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status);
-snd_pcm_state_t snd_pcm_plugin_state(snd_pcm_t *pcm);
 int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
 int snd_pcm_plugin_prepare(snd_pcm_t *pcm);
-int snd_pcm_plugin_start(snd_pcm_t *pcm);
-int snd_pcm_plugin_drop(snd_pcm_t *pcm);
-int snd_pcm_plugin_drain(snd_pcm_t *pcm);
-int snd_pcm_plugin_pause(snd_pcm_t *pcm, int enable);
 snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
 snd_pcm_sframes_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
@@ -77,15 +62,6 @@ snd_pcm_sframes_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_ufr
 snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size);
 snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm);
-int snd_pcm_plugin_mmap_status(snd_pcm_t *pcm);
-int snd_pcm_plugin_mmap_control(snd_pcm_t *pcm);
-int snd_pcm_plugin_mmap(snd_pcm_t *pcm);
-int snd_pcm_plugin_munmap_status(snd_pcm_t *pcm);
-int snd_pcm_plugin_munmap_control(snd_pcm_t *pcm);
-int snd_pcm_plugin_munmap(snd_pcm_t *pcm);
-int snd_pcm_plugin_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
-int snd_pcm_plugin_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
-int snd_pcm_plugin_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
 
 extern snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops;
 
index b802bc2057952187828455dea5b83162eeb303c0..b24f077c3aa2dfb97e549465caaf2699d160c788 100644 (file)
@@ -66,8 +66,7 @@ typedef void (*rate_f)(const snd_pcm_channel_area_t *dst_areas,
                       snd_pcm_rate_t *rate);
 
 struct _snd_pcm_rate {
-       snd_pcm_t *slave;
-       int close_slave;
+       snd_pcm_generic_t gen;
        snd_atomic_write_t watom;
        snd_pcm_uframes_t appl_ptr, hw_ptr;
        snd_pcm_uframes_t orig_avail_min;
@@ -497,18 +496,6 @@ static int snd_pcm_rate_hw_refine_cchange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
        return 0;
 }
 
-static int snd_pcm_rate_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_hw_refine(rate->slave, params);
-}
-
-static int snd_pcm_rate_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return _snd_pcm_hw_params(rate->slave, params);
-}
-
 static int snd_pcm_rate_hw_refine(snd_pcm_t *pcm, 
                                  snd_pcm_hw_params_t *params)
 {
@@ -517,13 +504,13 @@ static int snd_pcm_rate_hw_refine(snd_pcm_t *pcm,
                                       snd_pcm_rate_hw_refine_cchange,
                                       snd_pcm_rate_hw_refine_sprepare,
                                       snd_pcm_rate_hw_refine_schange,
-                                      snd_pcm_rate_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       snd_pcm_t *slave = rate->slave;
+       snd_pcm_t *slave = rate->gen.slave;
        snd_pcm_format_t src_format, dst_format, pformat, sformat;
        unsigned int src_rate, dst_rate, channels, pwidth, swidth, chn;
        snd_pcm_uframes_t period_size, buffer_size;
@@ -531,7 +518,7 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                                          snd_pcm_rate_hw_refine_cchange,
                                          snd_pcm_rate_hw_refine_sprepare,
                                          snd_pcm_rate_hw_refine_schange,
-                                         snd_pcm_rate_hw_params_slave);
+                                         snd_pcm_generic_hw_params);
        if (err < 0)
                return err;
 
@@ -620,13 +607,13 @@ static int snd_pcm_rate_hw_free(snd_pcm_t *pcm)
                rate->pareas = NULL;
                rate->sareas = NULL;
        }
-       return snd_pcm_hw_free(rate->slave);
+       return snd_pcm_hw_free(rate->gen.slave);
 }
 
 static void recalc(snd_pcm_t *pcm, snd_pcm_uframes_t *val)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       snd_pcm_t *slave = rate->slave;
+       snd_pcm_t *slave = rate->gen.slave;
        unsigned long div;
 
        if (*val == pcm->buffer_size) {
@@ -643,7 +630,7 @@ static void recalc(snd_pcm_t *pcm, snd_pcm_uframes_t *val)
 static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       snd_pcm_t *slave = rate->slave;
+       snd_pcm_t *slave = rate->gen.slave;
        snd_pcm_sw_params_t *sparams;
        snd_pcm_uframes_t boundary1, boundary2;
 
@@ -771,7 +758,7 @@ snd_pcm_rate_write_areas1(snd_pcm_t *pcm,
                         snd_pcm_uframes_t slave_offset)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       rate->func(slave_areas, slave_offset, rate->slave->period_size,
+       rate->func(slave_areas, slave_offset, rate->gen.slave->period_size,
                   areas, offset, pcm->period_size,
                   pcm->channels, rate);
        return 0;
@@ -786,7 +773,7 @@ snd_pcm_rate_read_areas1(snd_pcm_t *pcm,
 {
        snd_pcm_rate_t *rate = pcm->private_data;
        rate->func(areas, offset, pcm->period_size,
-                  slave_areas, slave_offset, rate->slave->period_size,
+                  slave_areas, slave_offset, rate->gen.slave->period_size,
                   pcm->channels, rate);
        return 0;
 }
@@ -796,7 +783,7 @@ static inline snd_pcm_sframes_t snd_pcm_rate_move_applptr(snd_pcm_t *pcm, snd_pc
        snd_pcm_rate_t *rate = pcm->private_data;
        snd_pcm_uframes_t orig_appl_ptr, appl_ptr = rate->appl_ptr, slave_appl_ptr;
        snd_pcm_sframes_t diff, ndiff;
-       snd_pcm_t *slave = rate->slave;
+       snd_pcm_t *slave = rate->gen.slave;
 
        orig_appl_ptr = rate->appl_ptr;
        if (frames > 0)
@@ -804,7 +791,7 @@ static inline snd_pcm_sframes_t snd_pcm_rate_move_applptr(snd_pcm_t *pcm, snd_pc
        else
                snd_pcm_mmap_appl_backward(pcm, -frames);
        slave_appl_ptr =
-               (appl_ptr / pcm->period_size) * rate->slave->period_size;
+               (appl_ptr / pcm->period_size) * rate->gen.slave->period_size;
        diff = slave_appl_ptr - *slave->appl.ptr;
        if (diff < -(snd_pcm_sframes_t)(slave->boundary / 2)) {
                diff = (slave->boundary - *slave->appl.ptr) + slave_appl_ptr;
@@ -814,16 +801,16 @@ static inline snd_pcm_sframes_t snd_pcm_rate_move_applptr(snd_pcm_t *pcm, snd_pc
        if (diff == 0)
                return frames;
        if (diff > 0) {
-               ndiff = snd_pcm_forward(rate->slave, diff);
+               ndiff = snd_pcm_forward(rate->gen.slave, diff);
        } else {
-               ndiff = snd_pcm_rewind(rate->slave, diff);
+               ndiff = snd_pcm_rewind(rate->gen.slave, diff);
        }
        if (ndiff < 0)
                return diff;
        slave_appl_ptr = *slave->appl.ptr;
        rate->appl_ptr =
-               (slave_appl_ptr / rate->slave->period_size) * pcm->period_size +
-               snd_pcm_rate_client_frames(pcm, slave_appl_ptr % rate->slave->period_size) +
+               (slave_appl_ptr / rate->gen.slave->period_size) * pcm->period_size +
+               snd_pcm_rate_client_frames(pcm, slave_appl_ptr % rate->gen.slave->period_size) +
                orig_appl_ptr % pcm->period_size;
        diff = orig_appl_ptr - rate->appl_ptr;
        if (diff < -(snd_pcm_sframes_t)(slave->boundary / 2)) {
@@ -839,64 +826,19 @@ static inline snd_pcm_sframes_t snd_pcm_rate_move_applptr(snd_pcm_t *pcm, snd_pc
 static inline void snd_pcm_rate_sync_hwptr(snd_pcm_t *pcm)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       snd_pcm_uframes_t slave_hw_ptr = *rate->slave->hw.ptr;
+       snd_pcm_uframes_t slave_hw_ptr = *rate->gen.slave->hw.ptr;
 
        if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
                return;
        rate->hw_ptr =
-               (slave_hw_ptr / rate->slave->period_size) * pcm->period_size +
-               snd_pcm_rate_client_frames(pcm, slave_hw_ptr % rate->slave->period_size);
-}
-
-static int snd_pcm_rate_close(snd_pcm_t *pcm)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       int err = 0;
-       if (rate->close_slave)
-               err = snd_pcm_close(rate->slave);
-       free(rate);
-       return 0;
-}
-
-static int snd_pcm_rate_nonblock(snd_pcm_t *pcm, int nonblock)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_nonblock(rate->slave, nonblock);
-}
-
-static int snd_pcm_rate_async(snd_pcm_t *pcm, int sig, pid_t pid)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_async(rate->slave, sig, pid);
-}
-
-static int snd_pcm_rate_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_poll_descriptors_revents(rate->slave, pfds, nfds, revents);
-}
-
-static int snd_pcm_rate_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_info(rate->slave, info);
-}
-
-static int snd_pcm_rate_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
-{
-       return snd_pcm_channel_info_shm(pcm, info, -1);
-}
-
-static snd_pcm_state_t snd_pcm_rate_state(snd_pcm_t *pcm)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_state(rate->slave);
+               (slave_hw_ptr / rate->gen.slave->period_size) * pcm->period_size +
+               snd_pcm_rate_client_frames(pcm, slave_hw_ptr % rate->gen.slave->period_size);
 }
 
 static int snd_pcm_rate_hwsync(snd_pcm_t *pcm)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       int err = snd_pcm_hwsync(rate->slave);
+       int err = snd_pcm_hwsync(rate->gen.slave);
        if (err < 0)
                return err;
        snd_atomic_write_begin(&rate->watom);
@@ -921,7 +863,7 @@ static int snd_pcm_rate_prepare(snd_pcm_t *pcm)
        int err;
 
        snd_atomic_write_begin(&rate->watom);
-       err = snd_pcm_prepare(rate->slave);
+       err = snd_pcm_prepare(rate->gen.slave);
        if (err < 0) {
                snd_atomic_write_end(&rate->watom);
                return err;
@@ -940,7 +882,7 @@ static int snd_pcm_rate_reset(snd_pcm_t *pcm)
        snd_pcm_rate_t *rate = pcm->private_data;
        int err;
        snd_atomic_write_begin(&rate->watom);
-       err = snd_pcm_reset(rate->slave);
+       err = snd_pcm_reset(rate->gen.slave);
        if (err < 0) {
                snd_atomic_write_end(&rate->watom);
                return err;
@@ -954,30 +896,6 @@ static int snd_pcm_rate_reset(snd_pcm_t *pcm)
        return 0;
 }
 
-static int snd_pcm_rate_start(snd_pcm_t *pcm)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_start(rate->slave);
-}
-
-static int snd_pcm_rate_drop(snd_pcm_t *pcm)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_drop(rate->slave);
-}
-
-static int snd_pcm_rate_drain(snd_pcm_t *pcm)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_drain(rate->slave);
-}
-
-static int snd_pcm_rate_pause(snd_pcm_t *pcm, int enable)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_pause(rate->slave, enable);
-}
-
 static snd_pcm_sframes_t snd_pcm_rate_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
@@ -1010,31 +928,25 @@ static snd_pcm_sframes_t snd_pcm_rate_forward(snd_pcm_t *pcm, snd_pcm_uframes_t
        return n;
 }
 
-static int snd_pcm_rate_resume(snd_pcm_t *pcm)
-{
-       snd_pcm_rate_t *rate = pcm->private_data;
-       return snd_pcm_resume(rate->slave);
-}
-
 static int snd_pcm_rate_poll_ask(snd_pcm_t *pcm)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
        snd_pcm_uframes_t avail_min;
        int err;
 
-       if (rate->slave->fast_ops->poll_ask) {
-               err = rate->slave->fast_ops->poll_ask(rate->slave->fast_op_arg);
+       if (rate->gen.slave->fast_ops->poll_ask) {
+               err = rate->gen.slave->fast_ops->poll_ask(rate->gen.slave->fast_op_arg);
                if (err < 0)
                        return err;
        }
        avail_min = rate->appl_ptr % pcm->period_size;
        if (avail_min > 0) {
                recalc(pcm, &avail_min);
-               if (avail_min < rate->slave->buffer_size &&
-                   avail_min != rate->slave->period_size)
+               if (avail_min < rate->gen.slave->buffer_size &&
+                   avail_min != rate->gen.slave->period_size)
                        avail_min++;    /* 1st small little rounding correction */
-               if (avail_min < rate->slave->buffer_size &&
-                   avail_min != rate->slave->period_size)
+               if (avail_min < rate->gen.slave->buffer_size &&
+                   avail_min != rate->gen.slave->period_size)
                        avail_min++;    /* 2nd small little rounding correction */
                avail_min += rate->orig_avail_min;
        } else {
@@ -1043,7 +955,7 @@ static int snd_pcm_rate_poll_ask(snd_pcm_t *pcm)
        if (rate->sw_params.avail_min == avail_min)
                return 0;
        rate->sw_params.avail_min = avail_min;
-       return snd_pcm_sw_params(rate->slave, &rate->sw_params);
+       return snd_pcm_sw_params(rate->gen.slave, &rate->sw_params);
 }
 
 static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t appl_offset)
@@ -1058,20 +970,20 @@ static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t app
 
        areas = snd_pcm_mmap_areas(pcm);
        if (cont >= pcm->period_size) {
-               result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames);
+               result = snd_pcm_mmap_begin(rate->gen.slave, &slave_areas, &slave_offset, &slave_frames);
                if (result < 0)
                        return result;
-               if (slave_frames < rate->slave->period_size) {
+               if (slave_frames < rate->gen.slave->period_size) {
                        snd_pcm_rate_write_areas1(pcm, areas, appl_offset, rate->sareas, 0);
                        goto __partial;
                }
                snd_pcm_rate_write_areas1(pcm, areas, appl_offset,
                                          slave_areas, slave_offset);
-               result = snd_pcm_mmap_commit(rate->slave, slave_offset, rate->slave->period_size);
-               if (result < (snd_pcm_sframes_t)rate->slave->period_size) {
+               result = snd_pcm_mmap_commit(rate->gen.slave, slave_offset, rate->gen.slave->period_size);
+               if (result < (snd_pcm_sframes_t)rate->gen.slave->period_size) {
                        if (result < 0)
                                return result;
-                       result = snd_pcm_rewind(rate->slave, result);
+                       result = snd_pcm_rewind(rate->gen.slave, result);
                        if (result < 0)
                                return result;
                        return 0;
@@ -1089,36 +1001,36 @@ static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t app
                snd_pcm_rate_write_areas1(pcm, rate->pareas, 0, rate->sareas, 0);
 
                /* ok, commit first fragment */
-               result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames);
+               result = snd_pcm_mmap_begin(rate->gen.slave, &slave_areas, &slave_offset, &slave_frames);
                if (result < 0)
                        return result;
              __partial:
                xfer = 0;
-               cont = rate->slave->buffer_size - slave_offset;
-               if (cont > rate->slave->period_size)
-                       cont = rate->slave->period_size;
+               cont = rate->gen.slave->buffer_size - slave_offset;
+               if (cont > rate->gen.slave->period_size)
+                       cont = rate->gen.slave->period_size;
                snd_pcm_areas_copy(slave_areas, slave_offset,
                                   rate->sareas, 0,
                                   pcm->channels, cont,
-                                  rate->slave->format);
-               result = snd_pcm_mmap_commit(rate->slave, slave_offset, cont);
+                                  rate->gen.slave->format);
+               result = snd_pcm_mmap_commit(rate->gen.slave, slave_offset, cont);
                if (result < (snd_pcm_sframes_t)cont) {
                        if (result < 0)
                                return result;
-                       result = snd_pcm_rewind(rate->slave, result);
+                       result = snd_pcm_rewind(rate->gen.slave, result);
                        if (result < 0)
                                return result;
                        return 0;
                }
                xfer = cont;
 
-               if (xfer == rate->slave->period_size)
+               if (xfer == rate->gen.slave->period_size)
                        return 1;
                
                /* commit second fragment */
-               cont = rate->slave->period_size - cont;
+               cont = rate->gen.slave->period_size - cont;
                slave_frames = cont;
-               result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames);
+               result = snd_pcm_mmap_begin(rate->gen.slave, &slave_areas, &slave_offset, &slave_frames);
                if (result < 0)
                        return result;
                if (slave_offset) {
@@ -1128,12 +1040,12 @@ static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t app
                snd_pcm_areas_copy(slave_areas, slave_offset,
                                   rate->sareas, xfer,
                                   pcm->channels, cont,
-                                  rate->slave->format);
-               result = snd_pcm_mmap_commit(rate->slave, slave_offset, cont);
+                                  rate->gen.slave->format);
+               result = snd_pcm_mmap_commit(rate->gen.slave, slave_offset, cont);
                if (result < (snd_pcm_sframes_t)cont) {
                        if (result < 0)
                                return result;
-                       result = snd_pcm_rewind(rate->slave, result + xfer);
+                       result = snd_pcm_rewind(rate->gen.slave, result + xfer);
                        if (result < 0)
                                return result;
                        return 0;
@@ -1154,54 +1066,54 @@ static int snd_pcm_rate_grab_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t hw_of
 
        areas = snd_pcm_mmap_areas(pcm);
        if (cont >= pcm->period_size) {
-               result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames);
+               result = snd_pcm_mmap_begin(rate->gen.slave, &slave_areas, &slave_offset, &slave_frames);
                if (result < 0)
                        return result;
-               if (slave_frames < rate->slave->period_size)
+               if (slave_frames < rate->gen.slave->period_size)
                        goto __partial;
                snd_pcm_rate_read_areas1(pcm, areas, hw_offset,
                                         slave_areas, slave_offset);
-               result = snd_pcm_mmap_commit(rate->slave, slave_offset, rate->slave->period_size);
-               if (result < (snd_pcm_sframes_t)rate->slave->period_size) {
+               result = snd_pcm_mmap_commit(rate->gen.slave, slave_offset, rate->gen.slave->period_size);
+               if (result < (snd_pcm_sframes_t)rate->gen.slave->period_size) {
                        if (result < 0)
                                return result;
-                       result = snd_pcm_rewind(rate->slave, result);
+                       result = snd_pcm_rewind(rate->gen.slave, result);
                        if (result < 0)
                                return result;
                        return 0;
                }
        } else {
                /* ok, grab first fragment */
-               result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames);
+               result = snd_pcm_mmap_begin(rate->gen.slave, &slave_areas, &slave_offset, &slave_frames);
                if (result < 0)
                        return result;
              __partial:
                xfer = 0;
-               cont = rate->slave->buffer_size - slave_offset;
-               if (cont > rate->slave->period_size)
-                       cont = rate->slave->period_size;
+               cont = rate->gen.slave->buffer_size - slave_offset;
+               if (cont > rate->gen.slave->period_size)
+                       cont = rate->gen.slave->period_size;
                snd_pcm_areas_copy(rate->sareas, 0,
                                   slave_areas, slave_offset,
                                   pcm->channels, cont,
-                                  rate->slave->format);
-               result = snd_pcm_mmap_commit(rate->slave, slave_offset, cont);
+                                  rate->gen.slave->format);
+               result = snd_pcm_mmap_commit(rate->gen.slave, slave_offset, cont);
                if (result < (snd_pcm_sframes_t)cont) {
                        if (result < 0)
                                return result;
-                       result = snd_pcm_rewind(rate->slave, result);
+                       result = snd_pcm_rewind(rate->gen.slave, result);
                        if (result < 0)
                                return result;
                        return 0;
                }
                xfer = cont;
 
-               if (xfer == rate->slave->period_size)
+               if (xfer == rate->gen.slave->period_size)
                        goto __transfer;
 
                /* grab second fragment */
-               cont = rate->slave->period_size - cont;
+               cont = rate->gen.slave->period_size - cont;
                slave_frames = cont;
-               result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames);
+               result = snd_pcm_mmap_begin(rate->gen.slave, &slave_areas, &slave_offset, &slave_frames);
                if (result < 0)
                        return result;
                if (slave_offset) {
@@ -1211,12 +1123,12 @@ static int snd_pcm_rate_grab_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t hw_of
                snd_pcm_areas_copy(rate->sareas, xfer,
                                   slave_areas, slave_offset,
                                   pcm->channels, cont,
-                                  rate->slave->format);
-               result = snd_pcm_mmap_commit(rate->slave, slave_offset, cont);
+                                  rate->gen.slave->format);
+               result = snd_pcm_mmap_commit(rate->gen.slave, slave_offset, cont);
                if (result < (snd_pcm_sframes_t)cont) {
                        if (result < 0)
                                return result;
-                       result = snd_pcm_rewind(rate->slave, result + xfer);
+                       result = snd_pcm_rewind(rate->gen.slave, result + xfer);
                        if (result < 0)
                                return result;
                        return 0;
@@ -1249,7 +1161,7 @@ static snd_pcm_sframes_t snd_pcm_rate_mmap_commit(snd_pcm_t *pcm,
                                                  snd_pcm_uframes_t size)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       snd_pcm_t *slave = rate->slave;
+       snd_pcm_t *slave = rate->gen.slave;
        snd_pcm_uframes_t appl_offset, xfer;
        snd_pcm_sframes_t slave_size;
        int err;
@@ -1269,7 +1181,7 @@ static snd_pcm_sframes_t snd_pcm_rate_mmap_commit(snd_pcm_t *pcm,
        appl_offset = (rate->appl_ptr - xfer) % pcm->buffer_size;
        xfer = pcm->period_size - xfer;
        if (xfer >= size) {
-               if (xfer == size && (snd_pcm_uframes_t)slave_size >= rate->slave->period_size) {
+               if (xfer == size && (snd_pcm_uframes_t)slave_size >= rate->gen.slave->period_size) {
                        err = snd_pcm_rate_commit_next_period(pcm, appl_offset);
                        if (err < 0)
                                return err;
@@ -1281,7 +1193,7 @@ static snd_pcm_sframes_t snd_pcm_rate_mmap_commit(snd_pcm_t *pcm,
                snd_atomic_write_end(&rate->watom);
                return size;
        } else {
-               if ((snd_pcm_uframes_t)slave_size >= rate->slave->period_size) {
+               if ((snd_pcm_uframes_t)slave_size >= rate->gen.slave->period_size) {
                        err = snd_pcm_rate_commit_next_period(pcm, appl_offset);
                        if (err < 0)
                                return err;
@@ -1294,10 +1206,10 @@ static snd_pcm_sframes_t snd_pcm_rate_mmap_commit(snd_pcm_t *pcm,
                appl_offset += pcm->period_size;
                appl_offset %= pcm->buffer_size;
                size -= xfer;
-               slave_size -= rate->slave->period_size;
+               slave_size -= rate->gen.slave->period_size;
        }
        while ((snd_pcm_uframes_t)size >= pcm->period_size &&
-              (snd_pcm_uframes_t)slave_size >= rate->slave->period_size) {
+              (snd_pcm_uframes_t)slave_size >= rate->gen.slave->period_size) {
                err = snd_pcm_rate_commit_next_period(pcm, appl_offset);
                if (err == 0)
                        return xfer;
@@ -1305,7 +1217,7 @@ static snd_pcm_sframes_t snd_pcm_rate_mmap_commit(snd_pcm_t *pcm,
                        return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
                xfer += pcm->period_size;
                size -= pcm->period_size;
-               slave_size -= rate->slave->period_size;
+               slave_size -= rate->gen.slave->period_size;
                appl_offset += pcm->period_size;
                appl_offset %= pcm->buffer_size;
                snd_atomic_write_begin(&rate->watom);
@@ -1325,7 +1237,7 @@ static snd_pcm_sframes_t snd_pcm_rate_mmap_commit(snd_pcm_t *pcm,
 static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
-       snd_pcm_t *slave = rate->slave;
+       snd_pcm_t *slave = rate->gen.slave;
        snd_pcm_uframes_t slave_size;
 
        slave_size = snd_pcm_avail_update(slave);
@@ -1342,7 +1254,7 @@ static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm)
        size = pcm->buffer_size - xfer;
        hw_offset = snd_pcm_mmap_hw_offset(pcm);
        while (size >= pcm->period_size &&
-              slave_size >= rate->slave->period_size) {
+              slave_size >= rate->gen.slave->period_size) {
                int err = snd_pcm_rate_grab_next_period(pcm, hw_offset);
                if (err < 0)
                        return err;
@@ -1350,7 +1262,7 @@ static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm)
                        return (snd_pcm_sframes_t)xfer;
                xfer += pcm->period_size;
                size -= pcm->period_size;
-               slave_size -= rate->slave->period_size;
+               slave_size -= rate->gen.slave->period_size;
                hw_offset += pcm->period_size;
                hw_offset %= pcm->buffer_size;
                snd_pcm_mmap_hw_forward(pcm, pcm->period_size);
@@ -1359,16 +1271,6 @@ static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm)
  }
 }
 
-static int snd_pcm_rate_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
-       return 0;
-}
-
-static int snd_pcm_rate_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
-       return 0;
-}
-
 static int snd_pcm_rate_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
 {
        snd_pcm_rate_t *rate = pcm->private_data;
@@ -1377,7 +1279,7 @@ static int snd_pcm_rate_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
        snd_atomic_read_init(&ratom, &rate->watom);
  _again:
        snd_atomic_read_begin(&ratom);
-       err = snd_pcm_status(rate->slave, status);
+       err = snd_pcm_status(rate->gen.slave, status);
        if (err < 0) {
                snd_atomic_read_ok(&ratom);
                return err;
@@ -1415,23 +1317,23 @@ static void snd_pcm_rate_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(rate->slave, out);
+       snd_pcm_dump(rate->gen.slave, out);
 }
 
 static snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = {
        .status = snd_pcm_rate_status,
-       .state = snd_pcm_rate_state,
+       .state = snd_pcm_generic_state,
        .hwsync = snd_pcm_rate_hwsync,
        .delay = snd_pcm_rate_delay,
        .prepare = snd_pcm_rate_prepare,
        .reset = snd_pcm_rate_reset,
-       .start = snd_pcm_rate_start,
-       .drop = snd_pcm_rate_drop,
-       .drain = snd_pcm_rate_drain,
-       .pause = snd_pcm_rate_pause,
+       .start = snd_pcm_generic_start,
+       .drop = snd_pcm_generic_drop,
+       .drain = snd_pcm_generic_drain,
+       .pause = snd_pcm_generic_pause,
        .rewind = snd_pcm_rate_rewind,
        .forward = snd_pcm_rate_forward,
-       .resume = snd_pcm_rate_resume,
+       .resume = snd_pcm_generic_resume,
        .poll_ask = snd_pcm_rate_poll_ask,
        .writei = snd_pcm_mmap_writei,
        .writen = snd_pcm_mmap_writen,
@@ -1442,19 +1344,19 @@ static snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = {
 };
 
 static snd_pcm_ops_t snd_pcm_rate_ops = {
-       .close = snd_pcm_rate_close,
-       .info = snd_pcm_rate_info,
+       .close = snd_pcm_generic_close,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_rate_hw_refine,
        .hw_params = snd_pcm_rate_hw_params,
        .hw_free = snd_pcm_rate_hw_free,
        .sw_params = snd_pcm_rate_sw_params,
-       .channel_info = snd_pcm_rate_channel_info,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_rate_dump,
-       .nonblock = snd_pcm_rate_nonblock,
-       .async = snd_pcm_rate_async,
-       .poll_revents = snd_pcm_rate_poll_revents,
-       .mmap = snd_pcm_rate_mmap,
-       .munmap = snd_pcm_rate_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 
@@ -1484,8 +1386,8 @@ int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
        if (!rate) {
                return -ENOMEM;
        }
-       rate->slave = slave;
-       rate->close_slave = close_slave;
+       rate->gen.slave = slave;
+       rate->gen.close_slave = close_slave;
        rate->type = RATE_TYPE_LINEAR;
        rate->srate = srate;
        rate->sformat = sformat;
index ea37abbe996aeb5c0162813cb5879f76ed99576f..be612dfc483f87083548394f45a8af790295ca2c 100644 (file)
@@ -507,10 +507,8 @@ static int snd_pcm_route_close(snd_pcm_t *pcm)
 {
        snd_pcm_route_t *route = pcm->private_data;
        snd_pcm_route_params_t *params = &route->params;
-       int err = 0;
        unsigned int dst_channel;
-       if (route->plug.close_slave)
-               err = snd_pcm_close(route->plug.slave);
+
        if (params->dsts) {
                for (dst_channel = 0; dst_channel < params->ndsts; ++dst_channel) {
                        if (params->dsts[dst_channel].srcs != NULL)
@@ -518,8 +516,7 @@ static int snd_pcm_route_close(snd_pcm_t *pcm)
                }
                free(params->dsts);
        }
-       free(route);
-       return 0;
+       return snd_pcm_generic_close(pcm);
 }
 
 static int snd_pcm_route_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
@@ -618,19 +615,19 @@ static int snd_pcm_route_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                                       snd_pcm_route_hw_refine_cchange,
                                       snd_pcm_route_hw_refine_sprepare,
                                       snd_pcm_route_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 {
        snd_pcm_route_t *route = pcm->private_data;
-       snd_pcm_t *slave = route->plug.slave;
+       snd_pcm_t *slave = route->plug.gen.slave;
        snd_pcm_format_t src_format, dst_format;
        int err = snd_pcm_hw_params_slave(pcm, params,
                                          snd_pcm_route_hw_refine_cchange,
                                          snd_pcm_route_hw_refine_sprepare,
                                          snd_pcm_route_hw_refine_schange,
-                                         snd_pcm_plugin_hw_params_slave);
+                                         snd_pcm_generic_hw_params);
        if (err < 0)
                return err;
 
@@ -671,7 +668,7 @@ snd_pcm_route_write_areas(snd_pcm_t *pcm,
                          snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_route_t *route = pcm->private_data;
-       snd_pcm_t *slave = route->plug.slave;
+       snd_pcm_t *slave = route->plug.gen.slave;
        if (size > *slave_sizep)
                size = *slave_sizep;
        snd_pcm_route_convert(slave_areas, slave_offset,
@@ -693,7 +690,7 @@ snd_pcm_route_read_areas(snd_pcm_t *pcm,
                         snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_route_t *route = pcm->private_data;
-       snd_pcm_t *slave = route->plug.slave;
+       snd_pcm_t *slave = route->plug.gen.slave;
        if (size > *slave_sizep)
                size = *slave_sizep;
        snd_pcm_route_convert(areas, offset, 
@@ -746,23 +743,23 @@ static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(route->plug.slave, out);
+       snd_pcm_dump(route->plug.gen.slave, out);
 }
 
 static snd_pcm_ops_t snd_pcm_route_ops = {
        .close = snd_pcm_route_close,
-       .info = snd_pcm_plugin_info,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_route_hw_refine,
        .hw_params = snd_pcm_route_hw_params,
-       .hw_free = snd_pcm_plugin_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .hw_free = snd_pcm_generic_hw_free,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_route_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 static int route_load_ttable(snd_pcm_route_params_t *params, snd_pcm_stream_t stream,
@@ -876,8 +873,8 @@ int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
        route->plug.write = snd_pcm_route_write_areas;
        route->plug.undo_read = snd_pcm_plugin_undo_read_generic;
        route->plug.undo_write = snd_pcm_plugin_undo_write_generic;
-       route->plug.slave = slave;
-       route->plug.close_slave = close_slave;
+       route->plug.gen.slave = slave;
+       route->plug.gen.close_slave = close_slave;
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_ROUTE, name, slave->stream, slave->mode);
        if (err < 0) {
index b8f50b35ad79de8339c0011b12132dfd7932b4ad..73b411d0258b5da0c5d57d36dc0740182203118d 100644 (file)
@@ -269,8 +269,8 @@ static void get_current_volume(snd_pcm_softvol_t *svol)
 
 static void softvol_free(snd_pcm_softvol_t *svol)
 {
-       if (svol->plug.close_slave)
-               snd_pcm_close(svol->plug.slave);
+       if (svol->plug.gen.close_slave)
+               snd_pcm_close(svol->plug.gen.slave);
        if (svol->ctl)
                snd_ctl_close(svol->ctl);
        if (svol->dB_value && svol->dB_value != preset_dB_value)
@@ -378,18 +378,18 @@ static int snd_pcm_softvol_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params
                                       snd_pcm_softvol_hw_refine_cchange,
                                       snd_pcm_softvol_hw_refine_sprepare,
                                       snd_pcm_softvol_hw_refine_schange,
-                                      snd_pcm_plugin_hw_refine_slave);
+                                      snd_pcm_generic_hw_refine);
 }
 
 static int snd_pcm_softvol_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 {
        snd_pcm_softvol_t *svol = pcm->private_data;
-       snd_pcm_t *slave = svol->plug.slave;
+       snd_pcm_t *slave = svol->plug.gen.slave;
        int err = snd_pcm_hw_params_slave(pcm, params,
                                          snd_pcm_softvol_hw_refine_cchange,
                                          snd_pcm_softvol_hw_refine_sprepare,
                                          snd_pcm_softvol_hw_refine_schange,
-                                         snd_pcm_plugin_hw_params_slave);
+                                         snd_pcm_generic_hw_params);
        if (err < 0)
                return err;
        if (slave->format != SND_PCM_FORMAT_S16 &&
@@ -459,7 +459,7 @@ static void snd_pcm_softvol_dump(snd_pcm_t *pcm, snd_output_t *out)
                snd_pcm_dump_setup(pcm, out);
        }
        snd_output_printf(out, "Slave: ");
-       snd_pcm_dump(svol->plug.slave, out);
+       snd_pcm_dump(svol->plug.gen.slave, out);
 }
 
 static int add_user_ctl(snd_pcm_softvol_t *svol, snd_ctl_elem_info_t *cinfo, int count)
@@ -573,18 +573,18 @@ static int softvol_load_control(snd_pcm_t *pcm, snd_pcm_softvol_t *svol,
 
 static snd_pcm_ops_t snd_pcm_softvol_ops = {
        .close = snd_pcm_softvol_close,
-       .info = snd_pcm_plugin_info,
+       .info = snd_pcm_generic_info,
        .hw_refine = snd_pcm_softvol_hw_refine,
        .hw_params = snd_pcm_softvol_hw_params,
-       .hw_free = snd_pcm_plugin_hw_free,
-       .sw_params = snd_pcm_plugin_sw_params,
-       .channel_info = snd_pcm_plugin_channel_info,
+       .hw_free = snd_pcm_generic_hw_free,
+       .sw_params = snd_pcm_generic_sw_params,
+       .channel_info = snd_pcm_generic_channel_info,
        .dump = snd_pcm_softvol_dump,
-       .nonblock = snd_pcm_plugin_nonblock,
-       .async = snd_pcm_plugin_async,
-       .poll_revents = snd_pcm_plugin_poll_revents,
-       .mmap = snd_pcm_plugin_mmap,
-       .munmap = snd_pcm_plugin_munmap,
+       .nonblock = snd_pcm_generic_nonblock,
+       .async = snd_pcm_generic_async,
+       .poll_revents = snd_pcm_generic_poll_revents,
+       .mmap = snd_pcm_generic_mmap,
+       .munmap = snd_pcm_generic_munmap,
 };
 
 /**
@@ -640,8 +640,8 @@ int snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
        svol->plug.write = snd_pcm_softvol_write_areas;
        svol->plug.undo_read = snd_pcm_plugin_undo_read_generic;
        svol->plug.undo_write = snd_pcm_plugin_undo_write_generic;
-       svol->plug.slave = slave;
-       svol->plug.close_slave = close_slave;
+       svol->plug.gen.slave = slave;
+       svol->plug.gen.close_slave = close_slave;
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_SOFTVOL, name, slave->stream, slave->mode);
        if (err < 0) {