mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-28 05:40:23 -04:00
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
This commit is contained in:
parent
9501520606
commit
836987aa99
25 changed files with 767 additions and 957 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
257
src/pcm/pcm_generic.c
Normal file
257
src/pcm/pcm_generic.c
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
/**
|
||||
* \file pcm/pcm_generic.c
|
||||
* \ingroup PCM
|
||||
* \brief PCM Interface
|
||||
* \author Jaroslav Kysela <perex@suse.cz>
|
||||
* \date 2004
|
||||
*/
|
||||
/*
|
||||
* PCM - Common generic plugin code
|
||||
* Copyright (c) 2004 by Jaroslav Kysela <perex@suse.cz>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/shm.h>
|
||||
#include <limits.h>
|
||||
#include "pcm_local.h"
|
||||
#include "pcm_generic.h"
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
|
||||
int snd_pcm_generic_close(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
int err = 0;
|
||||
if (generic->close_slave)
|
||||
err = snd_pcm_close(generic->slave);
|
||||
free(generic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_pcm_generic_nonblock(snd_pcm_t *pcm, int nonblock)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_nonblock(generic->slave, nonblock);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_async(generic->slave, sig, pid);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_poll_descriptors_revents(generic->slave, pfds, nfds, revents);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_info(generic->slave, info);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_hw_free(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_hw_free(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_sw_params(generic->slave, params);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_hw_refine(generic->slave, params);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return _snd_pcm_hw_params(generic->slave, params);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_prepare(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_prepare(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
|
||||
{
|
||||
return snd_pcm_channel_info_shm(pcm, info, -1);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_status(generic->slave, status);
|
||||
}
|
||||
|
||||
snd_pcm_state_t snd_pcm_generic_state(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_state(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_hwsync(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_hwsync(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_reset(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_reset(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_start(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_start(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_drop(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_drop(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_drain(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_drain(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_pause(snd_pcm_t *pcm, int enable)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_pause(generic->slave, enable);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_resume(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_resume(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_delay(generic->slave, delayp);
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_generic_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return INTERNAL(snd_pcm_forward)(generic->slave, frames);
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_generic_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_rewind(generic->slave, frames);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_poll_ask(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
if (generic->slave->fast_ops->poll_ask)
|
||||
return generic->slave->fast_ops->poll_ask(generic->slave->fast_op_arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_pcm_generic_link_fd(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
if (generic->slave->fast_ops->link_fd)
|
||||
return generic->slave->fast_ops->link_fd(generic->slave->fast_op_arg);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int snd_pcm_generic_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm1->private_data;
|
||||
if (generic->slave->fast_ops->link)
|
||||
return generic->slave->fast_ops->link(generic->slave->fast_op_arg, pcm2);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int snd_pcm_generic_unlink(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
if (generic->slave->fast_ops->unlink)
|
||||
return generic->slave->fast_ops->unlink(generic->slave->fast_op_arg);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_generic_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_writei(generic->slave, buffer, size);
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_generic_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_writen(generic->slave, bufs, size);
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_generic_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_readi(generic->slave, buffer, size);
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_generic_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_readn(generic->slave, bufs, size);
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_generic_mmap_commit(snd_pcm_t *pcm,
|
||||
snd_pcm_uframes_t offset,
|
||||
snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_mmap_commit(generic->slave, offset, size);
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_generic_avail_update(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_generic_t *generic = pcm->private_data;
|
||||
return snd_pcm_avail_update(generic->slave);
|
||||
}
|
||||
|
||||
int snd_pcm_generic_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_pcm_generic_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* DOC_HIDDEN */
|
||||
63
src/pcm/pcm_generic.h
Normal file
63
src/pcm/pcm_generic.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* PCM - Common generic plugin code
|
||||
* Copyright (c) 2004 by Jaroslav Kysela <perex@suse.cz>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
snd_pcm_t *slave;
|
||||
int close_slave;
|
||||
} snd_pcm_generic_t;
|
||||
|
||||
int snd_pcm_generic_close(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_nonblock(snd_pcm_t *pcm, int nonblock);
|
||||
int snd_pcm_generic_async(snd_pcm_t *pcm, int sig, pid_t pid);
|
||||
int snd_pcm_generic_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
|
||||
int snd_pcm_generic_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
|
||||
int snd_pcm_generic_hw_free(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
|
||||
int snd_pcm_generic_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
|
||||
int snd_pcm_generic_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
|
||||
int snd_pcm_generic_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
|
||||
int snd_pcm_generic_status(snd_pcm_t *pcm, snd_pcm_status_t * status);
|
||||
snd_pcm_state_t snd_pcm_generic_state(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_prepare(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_hwsync(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_reset(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_start(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_drop(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_drain(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_pause(snd_pcm_t *pcm, int enable);
|
||||
int snd_pcm_generic_resume(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
|
||||
snd_pcm_sframes_t snd_pcm_generic_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
|
||||
snd_pcm_sframes_t snd_pcm_generic_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
|
||||
int snd_pcm_generic_poll_ask(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_link_fd(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
|
||||
int snd_pcm_generic_unlink(snd_pcm_t *pcm);
|
||||
snd_pcm_sframes_t snd_pcm_generic_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_generic_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_generic_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_generic_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_generic_mmap_commit(snd_pcm_t *pcm,
|
||||
snd_pcm_uframes_t offset,
|
||||
snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_generic_avail_update(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_mmap(snd_pcm_t *pcm);
|
||||
int snd_pcm_generic_munmap(snd_pcm_t *pcm);
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <dlfcn.h>
|
||||
#include "pcm_local.h"
|
||||
#include "pcm_generic.h"
|
||||
|
||||
#ifndef PIC
|
||||
/* entry for static linking */
|
||||
|
|
@ -44,8 +45,7 @@ struct _snd_pcm_hook {
|
|||
};
|
||||
|
||||
typedef struct {
|
||||
snd_pcm_t *slave;
|
||||
int close_slave;
|
||||
snd_pcm_generic_t gen;
|
||||
struct list_head hooks[SND_PCM_HOOK_TYPE_LAST + 1];
|
||||
} snd_pcm_hooks_t;
|
||||
#endif
|
||||
|
|
@ -56,11 +56,7 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
|
|||
struct list_head *pos, *next;
|
||||
unsigned int k;
|
||||
int err;
|
||||
if (h->close_slave) {
|
||||
err = snd_pcm_close(h->slave);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_TYPE_CLOSE]) {
|
||||
snd_pcm_hook_t *hook = list_entry(pos, snd_pcm_hook_t, list);
|
||||
err = hook->func(hook);
|
||||
|
|
@ -76,169 +72,14 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
|
|||
snd_pcm_hook_remove(hook);
|
||||
}
|
||||
}
|
||||
free(h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_nonblock(snd_pcm_t *pcm, int nonblock)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_nonblock(h->slave, nonblock);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_async(h->slave, sig, pid);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_info(h->slave, info);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_channel_info(h->slave, info);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_status(h->slave, status);
|
||||
}
|
||||
|
||||
static snd_pcm_state_t snd_pcm_hooks_state(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_state(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_hwsync(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_hwsync(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_delay(h->slave, delayp);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_prepare(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_prepare(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_reset(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_reset(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_start(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_start(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_drop(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_drop(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_drain(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_drain(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_pause(snd_pcm_t *pcm, int enable)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_pause(h->slave, enable);
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hooks_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_rewind(h->slave, frames);
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hooks_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return INTERNAL(snd_pcm_forward)(h->slave, frames);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_resume(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_resume(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_poll_ask(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
if (h->slave->fast_ops->poll_ask)
|
||||
return h->slave->fast_ops->poll_ask(h->slave->fast_op_arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hooks_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_writei(h->slave, buffer, size);
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hooks_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_writen(h->slave, bufs, size);
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hooks_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_readi(h->slave, buffer, size);
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hooks_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_readn(h->slave, bufs, size);
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hooks_mmap_commit(snd_pcm_t *pcm,
|
||||
snd_pcm_uframes_t offset,
|
||||
snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_mmap_commit(h->slave, offset, size);
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hooks_avail_update(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_avail_update(h->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_hw_refine(h->slave, params);
|
||||
return snd_pcm_generic_close(pcm);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
struct list_head *pos, *next;
|
||||
int err = snd_pcm_hw_params(h->slave, params);
|
||||
int err = snd_pcm_hw_params(h->gen.slave, params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_TYPE_HW_PARAMS]) {
|
||||
|
|
@ -254,7 +95,7 @@ static int snd_pcm_hooks_hw_free(snd_pcm_t *pcm)
|
|||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
struct list_head *pos, *next;
|
||||
int err = snd_pcm_hw_free(h->slave);
|
||||
int err = snd_pcm_hw_free(h->gen.slave);
|
||||
if (err < 0)
|
||||
return err;
|
||||
list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_TYPE_HW_FREE]) {
|
||||
|
|
@ -266,22 +107,6 @@ static int snd_pcm_hooks_hw_free(snd_pcm_t *pcm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
return snd_pcm_sw_params(h->slave, params);
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_pcm_hooks_dump(snd_pcm_t *pcm, snd_output_t *out)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
|
|
@ -291,45 +116,48 @@ static void snd_pcm_hooks_dump(snd_pcm_t *pcm, snd_output_t *out)
|
|||
snd_pcm_dump_setup(pcm, out);
|
||||
}
|
||||
snd_output_printf(out, "Slave: ");
|
||||
snd_pcm_dump(h->slave, out);
|
||||
snd_pcm_dump(h->gen.slave, out);
|
||||
}
|
||||
|
||||
static snd_pcm_ops_t snd_pcm_hooks_ops = {
|
||||
.close = snd_pcm_hooks_close,
|
||||
.info = snd_pcm_hooks_info,
|
||||
.hw_refine = snd_pcm_hooks_hw_refine,
|
||||
.info = snd_pcm_generic_info,
|
||||
.hw_refine = snd_pcm_generic_hw_refine,
|
||||
.hw_params = snd_pcm_hooks_hw_params,
|
||||
.hw_free = snd_pcm_hooks_hw_free,
|
||||
.sw_params = snd_pcm_hooks_sw_params,
|
||||
.channel_info = snd_pcm_hooks_channel_info,
|
||||
.sw_params = snd_pcm_generic_sw_params,
|
||||
.channel_info = snd_pcm_generic_channel_info,
|
||||
.dump = snd_pcm_hooks_dump,
|
||||
.nonblock = snd_pcm_hooks_nonblock,
|
||||
.async = snd_pcm_hooks_async,
|
||||
.mmap = snd_pcm_hooks_mmap,
|
||||
.munmap = snd_pcm_hooks_munmap,
|
||||
.nonblock = snd_pcm_generic_nonblock,
|
||||
.async = snd_pcm_generic_async,
|
||||
.mmap = snd_pcm_generic_mmap,
|
||||
.munmap = snd_pcm_generic_munmap,
|
||||
};
|
||||
|
||||
static snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
|
||||
.status = snd_pcm_hooks_status,
|
||||
.state = snd_pcm_hooks_state,
|
||||
.hwsync = snd_pcm_hooks_hwsync,
|
||||
.delay = snd_pcm_hooks_delay,
|
||||
.prepare = snd_pcm_hooks_prepare,
|
||||
.reset = snd_pcm_hooks_reset,
|
||||
.start = snd_pcm_hooks_start,
|
||||
.drop = snd_pcm_hooks_drop,
|
||||
.drain = snd_pcm_hooks_drain,
|
||||
.pause = snd_pcm_hooks_pause,
|
||||
.rewind = snd_pcm_hooks_rewind,
|
||||
.forward = snd_pcm_hooks_forward,
|
||||
.resume = snd_pcm_hooks_resume,
|
||||
.poll_ask = snd_pcm_hooks_poll_ask,
|
||||
.writei = snd_pcm_hooks_writei,
|
||||
.writen = snd_pcm_hooks_writen,
|
||||
.readi = snd_pcm_hooks_readi,
|
||||
.readn = snd_pcm_hooks_readn,
|
||||
.avail_update = snd_pcm_hooks_avail_update,
|
||||
.mmap_commit = snd_pcm_hooks_mmap_commit,
|
||||
.status = snd_pcm_generic_status,
|
||||
.state = snd_pcm_generic_state,
|
||||
.hwsync = snd_pcm_generic_hwsync,
|
||||
.delay = snd_pcm_generic_delay,
|
||||
.prepare = snd_pcm_generic_prepare,
|
||||
.reset = snd_pcm_generic_reset,
|
||||
.start = snd_pcm_generic_start,
|
||||
.drop = snd_pcm_generic_drop,
|
||||
.drain = snd_pcm_generic_drain,
|
||||
.pause = snd_pcm_generic_pause,
|
||||
.rewind = snd_pcm_generic_rewind,
|
||||
.forward = snd_pcm_generic_forward,
|
||||
.resume = snd_pcm_generic_resume,
|
||||
.poll_ask = snd_pcm_generic_poll_ask,
|
||||
.link_fd = snd_pcm_generic_link_fd,
|
||||
.link = snd_pcm_generic_link,
|
||||
.unlink = snd_pcm_generic_unlink,
|
||||
.writei = snd_pcm_generic_writei,
|
||||
.writen = snd_pcm_generic_writen,
|
||||
.readi = snd_pcm_generic_readi,
|
||||
.readn = snd_pcm_generic_readn,
|
||||
.avail_update = snd_pcm_generic_avail_update,
|
||||
.mmap_commit = snd_pcm_generic_mmap_commit,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -353,8 +181,8 @@ int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
|
|||
h = calloc(1, sizeof(snd_pcm_hooks_t));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
h->slave = slave;
|
||||
h->close_slave = close_slave;
|
||||
h->gen.slave = slave;
|
||||
h->gen.close_slave = close_slave;
|
||||
for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++k) {
|
||||
INIT_LIST_HEAD(&h->hooks[k]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue