From 836987aa99af92cf28da00683de95acb87054f0a Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 20 Jan 2005 15:07:51 +0000 Subject: [PATCH] improved stream linking and plugin code cleanups - 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 --- src/pcm/Makefile.am | 2 +- src/pcm/pcm.c | 33 ++--- src/pcm/pcm_adpcm.c | 32 ++--- src/pcm/pcm_alaw.c | 30 ++--- src/pcm/pcm_copy.c | 30 ++--- src/pcm/pcm_dmix.c | 3 + src/pcm/pcm_dshare.c | 3 + src/pcm/pcm_dsnoop.c | 3 + src/pcm/pcm_file.c | 186 ++++++---------------------- src/pcm/pcm_generic.c | 257 ++++++++++++++++++++++++++++++++++++++ src/pcm/pcm_generic.h | 63 ++++++++++ src/pcm/pcm_hooks.c | 252 ++++++------------------------------- src/pcm/pcm_hw.c | 35 ++++++ src/pcm/pcm_iec958.c | 30 ++--- src/pcm/pcm_ladspa.c | 30 ++--- src/pcm/pcm_lfloat.c | 32 ++--- src/pcm/pcm_linear.c | 30 ++--- src/pcm/pcm_local.h | 10 +- src/pcm/pcm_mulaw.c | 30 ++--- src/pcm/pcm_plug.c | 85 ++++--------- src/pcm/pcm_plugin.c | 165 ++++--------------------- src/pcm/pcm_plugin.h | 28 +---- src/pcm/pcm_rate.c | 280 ++++++++++++++---------------------------- src/pcm/pcm_route.c | 41 +++---- src/pcm/pcm_softvol.c | 34 ++--- 25 files changed, 767 insertions(+), 957 deletions(-) create mode 100644 src/pcm/pcm_generic.c create mode 100644 src/pcm/pcm_generic.h diff --git a/src/pcm/Makefile.am b/src/pcm/Makefile.am index 5a11ef62..4d9a8a64 100644 --- a/src/pcm/Makefile.am +++ b/src/pcm/Makefile.am @@ -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 \ diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 6e7c0e5b..13af3942 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -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); diff --git a/src/pcm/pcm_adpcm.c b/src/pcm/pcm_adpcm.c index fa429972..b9c32005 100644 --- a/src/pcm/pcm_adpcm.c +++ b/src/pcm/pcm_adpcm.c @@ -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) { diff --git a/src/pcm/pcm_alaw.c b/src/pcm/pcm_alaw.c index c8c6cc9a..a76f15ac 100644 --- a/src/pcm/pcm_alaw.c +++ b/src/pcm/pcm_alaw.c @@ -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) { diff --git a/src/pcm/pcm_copy.c b/src/pcm/pcm_copy.c index 9c4633ba..64b4557b 100644 --- a/src/pcm/pcm_copy.c +++ b/src/pcm/pcm_copy.c @@ -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) { diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index 3fdbf4b2..5375da70 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -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, diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c index 52784019..87fd245c 100644 --- a/src/pcm/pcm_dshare.c +++ b/src/pcm/pcm_dshare.c @@ -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, diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c index e6ae1e6a..17637359 100644 --- a/src/pcm/pcm_dsnoop.c +++ b/src/pcm/pcm_dsnoop.c @@ -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, diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c index 6559545b..132fb23c 100644 --- a/src/pcm/pcm_file.c +++ b/src/pcm/pcm_file.c @@ -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 index 00000000..44aae856 --- /dev/null +++ b/src/pcm/pcm_generic.c @@ -0,0 +1,257 @@ +/** + * \file pcm/pcm_generic.c + * \ingroup PCM + * \brief PCM Interface + * \author Jaroslav Kysela + * \date 2004 + */ +/* + * PCM - Common generic plugin code + * Copyright (c) 2004 by Jaroslav Kysela + * + * + * 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 +#include +#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 index 00000000..202a9fb5 --- /dev/null +++ b/src/pcm/pcm_generic.h @@ -0,0 +1,63 @@ +/* + * PCM - Common generic plugin code + * Copyright (c) 2004 by Jaroslav Kysela + * + * + * 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); diff --git a/src/pcm/pcm_hooks.c b/src/pcm/pcm_hooks.c index 0cf6d563..e2eaaedb 100644 --- a/src/pcm/pcm_hooks.c +++ b/src/pcm/pcm_hooks.c @@ -29,6 +29,7 @@ #include #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]); } diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index cf6abe66..b3b02800 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -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, diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c index a87846c0..04ec48c2 100644 --- a/src/pcm/pcm_iec958.c +++ b/src/pcm/pcm_iec958.c @@ -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)); diff --git a/src/pcm/pcm_ladspa.c b/src/pcm/pcm_ladspa.c index 5ff82369..3452a3b7 100644 --- a/src/pcm/pcm_ladspa.c +++ b/src/pcm/pcm_ladspa.c @@ -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); diff --git a/src/pcm/pcm_lfloat.c b/src/pcm/pcm_lfloat.c index 218d6c45..b394b59b 100644 --- a/src/pcm/pcm_lfloat.c +++ b/src/pcm/pcm_lfloat.c @@ -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) { diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c index 27b7bfa1..03739238 100644 --- a/src/pcm/pcm_linear.c +++ b/src/pcm/pcm_linear.c @@ -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) { diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index f53dc672..5b9ef3b2 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -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; - diff --git a/src/pcm/pcm_mulaw.c b/src/pcm/pcm_mulaw.c index 8d9baf73..39564a38 100644 --- a/src/pcm/pcm_mulaw.c +++ b/src/pcm/pcm_mulaw.c @@ -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) { diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index 60eb2df0..0c18e7e2 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -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; diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c index d8a5a028..68dd4d46 100644 --- a/src/pcm/pcm_plugin.c +++ b/src/pcm/pcm_plugin.c @@ -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 diff --git a/src/pcm/pcm_plugin.h b/src/pcm/pcm_plugin.h index a4353c51..045d4dbd 100644 --- a/src/pcm/pcm_plugin.h +++ b/src/pcm/pcm_plugin.h @@ -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; diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index b802bc20..b24f077c 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c @@ -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; diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c index ea37abbe..be612dfc 100644 --- a/src/pcm/pcm_route.c +++ b/src/pcm/pcm_route.c @@ -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) { diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c index b8f50b35..73b411d0 100644 --- a/src/pcm/pcm_softvol.c +++ b/src/pcm/pcm_softvol.c @@ -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) { -- 2.47.1