mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Better pcm_plug bypass. timestamp is struct timeval now
This commit is contained in:
parent
eee70747eb
commit
bd532fd398
6 changed files with 98 additions and 82 deletions
|
|
@ -68,7 +68,7 @@ int snd_pcm_nonblock(snd_pcm_t *handle, int nonblock)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
assert(handle);
|
assert(handle);
|
||||||
if ((err = handle->ops->nonblock(handle->op_arg, nonblock)) < 0)
|
if ((err = handle->fast_ops->nonblock(handle->fast_op_arg, nonblock)) < 0)
|
||||||
return err;
|
return err;
|
||||||
if (nonblock)
|
if (nonblock)
|
||||||
handle->mode |= SND_PCM_NONBLOCK;
|
handle->mode |= SND_PCM_NONBLOCK;
|
||||||
|
|
@ -80,17 +80,13 @@ int snd_pcm_nonblock(snd_pcm_t *handle, int nonblock)
|
||||||
int snd_pcm_info(snd_pcm_t *handle, snd_pcm_info_t *info)
|
int snd_pcm_info(snd_pcm_t *handle, snd_pcm_info_t *info)
|
||||||
{
|
{
|
||||||
assert(handle && info);
|
assert(handle && info);
|
||||||
/* Here we pass private and not op_arg.
|
return handle->ops->info(handle->op_arg, info);
|
||||||
FIXME: find a better solution */
|
|
||||||
return handle->ops->info(handle->private, info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_params_info(snd_pcm_t *handle, snd_pcm_params_info_t *info)
|
int snd_pcm_params_info(snd_pcm_t *handle, snd_pcm_params_info_t *info)
|
||||||
{
|
{
|
||||||
assert(handle && info);
|
assert(handle && info);
|
||||||
/* Here we pass private and not op_arg.
|
return handle->ops->params_info(handle->op_arg, info);
|
||||||
FIXME: find a better solution */
|
|
||||||
return handle->ops->params_info(handle->private, info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_setup(snd_pcm_t *handle, snd_pcm_setup_t *setup)
|
int snd_pcm_setup(snd_pcm_t *handle, snd_pcm_setup_t *setup)
|
||||||
|
|
@ -101,9 +97,7 @@ int snd_pcm_setup(snd_pcm_t *handle, snd_pcm_setup_t *setup)
|
||||||
*setup = handle->setup;
|
*setup = handle->setup;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Here we pass private and not op_arg.
|
if ((err = handle->ops->setup(handle->op_arg, &handle->setup)) < 0)
|
||||||
FIXME: find a better solution */
|
|
||||||
if ((err = handle->ops->setup(handle->private, &handle->setup)) < 0)
|
|
||||||
return err;
|
return err;
|
||||||
*setup = handle->setup;
|
*setup = handle->setup;
|
||||||
handle->bits_per_sample = snd_pcm_format_physical_width(setup->format.format);
|
handle->bits_per_sample = snd_pcm_format_physical_width(setup->format.format);
|
||||||
|
|
@ -116,7 +110,7 @@ int snd_pcm_channel_setup(snd_pcm_t *handle, snd_pcm_channel_setup_t *setup)
|
||||||
{
|
{
|
||||||
assert(handle && setup);
|
assert(handle && setup);
|
||||||
assert(handle->valid_setup);
|
assert(handle->valid_setup);
|
||||||
return handle->ops->channel_setup(handle->op_arg, setup);
|
return handle->fast_ops->channel_setup(handle->fast_op_arg, setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_params(snd_pcm_t *handle, snd_pcm_params_t *params)
|
int snd_pcm_params(snd_pcm_t *handle, snd_pcm_params_t *params)
|
||||||
|
|
@ -125,9 +119,7 @@ int snd_pcm_params(snd_pcm_t *handle, snd_pcm_params_t *params)
|
||||||
snd_pcm_setup_t setup;
|
snd_pcm_setup_t setup;
|
||||||
assert(handle && params);
|
assert(handle && params);
|
||||||
assert(!handle->mmap_data);
|
assert(!handle->mmap_data);
|
||||||
/* Here we pass private and not op_arg.
|
if ((err = handle->ops->params(handle->op_arg, params)) < 0)
|
||||||
FIXME: find a better solution */
|
|
||||||
if ((err = handle->ops->params(handle->private, params)) < 0)
|
|
||||||
return err;
|
return err;
|
||||||
handle->valid_setup = 0;
|
handle->valid_setup = 0;
|
||||||
return snd_pcm_setup(handle, &setup);
|
return snd_pcm_setup(handle, &setup);
|
||||||
|
|
@ -136,7 +128,7 @@ int snd_pcm_params(snd_pcm_t *handle, snd_pcm_params_t *params)
|
||||||
int snd_pcm_status(snd_pcm_t *handle, snd_pcm_status_t *status)
|
int snd_pcm_status(snd_pcm_t *handle, snd_pcm_status_t *status)
|
||||||
{
|
{
|
||||||
assert(handle && status);
|
assert(handle && status);
|
||||||
return handle->ops->status(handle->op_arg, status);
|
return handle->fast_ops->status(handle->fast_op_arg, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_state(snd_pcm_t *handle)
|
int snd_pcm_state(snd_pcm_t *handle)
|
||||||
|
|
@ -144,7 +136,7 @@ int snd_pcm_state(snd_pcm_t *handle)
|
||||||
assert(handle);
|
assert(handle);
|
||||||
if (handle->mmap_status)
|
if (handle->mmap_status)
|
||||||
return handle->mmap_status->state;
|
return handle->mmap_status->state;
|
||||||
return handle->ops->state(handle->op_arg);
|
return handle->fast_ops->state(handle->fast_op_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_frame_io(snd_pcm_t *handle, int update)
|
int snd_pcm_frame_io(snd_pcm_t *handle, int update)
|
||||||
|
|
@ -153,19 +145,19 @@ int snd_pcm_frame_io(snd_pcm_t *handle, int update)
|
||||||
assert(handle->valid_setup);
|
assert(handle->valid_setup);
|
||||||
if (handle->mmap_status && !update)
|
if (handle->mmap_status && !update)
|
||||||
return handle->mmap_status->frame_io;
|
return handle->mmap_status->frame_io;
|
||||||
return handle->ops->frame_io(handle->op_arg, update);
|
return handle->fast_ops->frame_io(handle->fast_op_arg, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_prepare(snd_pcm_t *handle)
|
int snd_pcm_prepare(snd_pcm_t *handle)
|
||||||
{
|
{
|
||||||
assert(handle);
|
assert(handle);
|
||||||
return handle->ops->prepare(handle->op_arg);
|
return handle->fast_ops->prepare(handle->fast_op_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_go(snd_pcm_t *handle)
|
int snd_pcm_go(snd_pcm_t *handle)
|
||||||
{
|
{
|
||||||
assert(handle);
|
assert(handle);
|
||||||
return handle->ops->go(handle->op_arg);
|
return handle->fast_ops->go(handle->fast_op_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_synchro(snd_pcm_synchro_cmd_t cmd,
|
int snd_pcm_synchro(snd_pcm_synchro_cmd_t cmd,
|
||||||
|
|
@ -216,19 +208,19 @@ int snd_pcm_synchro(snd_pcm_synchro_cmd_t cmd,
|
||||||
int snd_pcm_drain(snd_pcm_t *handle)
|
int snd_pcm_drain(snd_pcm_t *handle)
|
||||||
{
|
{
|
||||||
assert(handle);
|
assert(handle);
|
||||||
return handle->ops->drain(handle->op_arg);
|
return handle->fast_ops->drain(handle->fast_op_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_flush(snd_pcm_t *handle)
|
int snd_pcm_flush(snd_pcm_t *handle)
|
||||||
{
|
{
|
||||||
assert(handle);
|
assert(handle);
|
||||||
return handle->ops->flush(handle->op_arg);
|
return handle->fast_ops->flush(handle->fast_op_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_pause(snd_pcm_t *handle, int enable)
|
int snd_pcm_pause(snd_pcm_t *handle, int enable)
|
||||||
{
|
{
|
||||||
assert(handle);
|
assert(handle);
|
||||||
return handle->ops->pause(handle->op_arg, enable);
|
return handle->fast_ops->pause(handle->fast_op_arg, enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -240,7 +232,7 @@ ssize_t snd_pcm_frame_data(snd_pcm_t *handle, off_t offset)
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
return handle->mmap_control->frame_data;
|
return handle->mmap_control->frame_data;
|
||||||
}
|
}
|
||||||
return handle->ops->frame_data(handle->op_arg, offset);
|
return handle->fast_ops->frame_data(handle->fast_op_arg, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_write(snd_pcm_t *handle, const void *buffer, size_t size)
|
ssize_t snd_pcm_write(snd_pcm_t *handle, const void *buffer, size_t size)
|
||||||
|
|
@ -249,7 +241,7 @@ ssize_t snd_pcm_write(snd_pcm_t *handle, const void *buffer, size_t size)
|
||||||
assert(size == 0 || buffer);
|
assert(size == 0 || buffer);
|
||||||
assert(handle->valid_setup);
|
assert(handle->valid_setup);
|
||||||
assert(size % handle->setup.frames_align == 0);
|
assert(size % handle->setup.frames_align == 0);
|
||||||
return handle->ops->write(handle->op_arg, 0, buffer, size);
|
return handle->fast_ops->write(handle->fast_op_arg, 0, buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_writev(snd_pcm_t *handle, const struct iovec *vector, unsigned long count)
|
ssize_t snd_pcm_writev(snd_pcm_t *handle, const struct iovec *vector, unsigned long count)
|
||||||
|
|
@ -259,7 +251,7 @@ ssize_t snd_pcm_writev(snd_pcm_t *handle, const struct iovec *vector, unsigned l
|
||||||
assert(handle->valid_setup);
|
assert(handle->valid_setup);
|
||||||
assert(handle->setup.format.interleave ||
|
assert(handle->setup.format.interleave ||
|
||||||
count % handle->setup.format.channels == 0);
|
count % handle->setup.format.channels == 0);
|
||||||
return handle->ops->writev(handle->op_arg, 0, vector, count);
|
return handle->fast_ops->writev(handle->fast_op_arg, 0, vector, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_read(snd_pcm_t *handle, void *buffer, size_t size)
|
ssize_t snd_pcm_read(snd_pcm_t *handle, void *buffer, size_t size)
|
||||||
|
|
@ -268,7 +260,7 @@ ssize_t snd_pcm_read(snd_pcm_t *handle, void *buffer, size_t size)
|
||||||
assert(size == 0 || buffer);
|
assert(size == 0 || buffer);
|
||||||
assert(handle->valid_setup);
|
assert(handle->valid_setup);
|
||||||
assert(size % handle->setup.frames_align == 0);
|
assert(size % handle->setup.frames_align == 0);
|
||||||
return handle->ops->read(handle->op_arg, 0, buffer, size);
|
return handle->fast_ops->read(handle->fast_op_arg, 0, buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_readv(snd_pcm_t *handle, const struct iovec *vector, unsigned long count)
|
ssize_t snd_pcm_readv(snd_pcm_t *handle, const struct iovec *vector, unsigned long count)
|
||||||
|
|
@ -276,20 +268,20 @@ ssize_t snd_pcm_readv(snd_pcm_t *handle, const struct iovec *vector, unsigned lo
|
||||||
assert(handle);
|
assert(handle);
|
||||||
assert(count == 0 || vector);
|
assert(count == 0 || vector);
|
||||||
assert(handle->valid_setup);
|
assert(handle->valid_setup);
|
||||||
return handle->ops->readv(handle->op_arg, 0, vector, count);
|
return handle->fast_ops->readv(handle->fast_op_arg, 0, vector, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_file_descriptor(snd_pcm_t *handle)
|
int snd_pcm_file_descriptor(snd_pcm_t *handle)
|
||||||
{
|
{
|
||||||
assert(handle);
|
assert(handle);
|
||||||
return handle->ops->file_descriptor(handle->op_arg);
|
return handle->fast_ops->file_descriptor(handle->fast_op_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channels_mask(snd_pcm_t *handle, bitset_t *client_vmask)
|
int snd_pcm_channels_mask(snd_pcm_t *handle, bitset_t *client_vmask)
|
||||||
{
|
{
|
||||||
assert(handle);
|
assert(handle);
|
||||||
assert(handle->valid_setup);
|
assert(handle->valid_setup);
|
||||||
return handle->ops->channels_mask(handle->op_arg, client_vmask);
|
return handle->fast_ops->channels_mask(handle->fast_op_arg, client_vmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
|
|
@ -200,13 +200,16 @@ static ssize_t snd_pcm_hw_frame_data(void *private, off_t offset)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t snd_pcm_hw_write(void *private, snd_timestamp_t tstamp, const void *buffer, size_t size)
|
static ssize_t snd_pcm_hw_write(void *private, snd_timestamp_t *tstamp, const void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
snd_xfer_t xfer;
|
snd_xfer_t xfer;
|
||||||
xfer.tstamp = tstamp;
|
if (tstamp)
|
||||||
|
xfer.tstamp = *tstamp;
|
||||||
|
else
|
||||||
|
xfer.tstamp.tv_sec = xfer.tstamp.tv_usec = 0;
|
||||||
xfer.buf = (char*) buffer;
|
xfer.buf = (char*) buffer;
|
||||||
xfer.count = size;
|
xfer.count = size;
|
||||||
result = ioctl(fd, SND_PCM_IOCTL_WRITE_FRAMES, &xfer);
|
result = ioctl(fd, SND_PCM_IOCTL_WRITE_FRAMES, &xfer);
|
||||||
|
|
@ -215,13 +218,16 @@ static ssize_t snd_pcm_hw_write(void *private, snd_timestamp_t tstamp, const voi
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t snd_pcm_hw_writev(void *private, snd_timestamp_t tstamp, const struct iovec *vector, unsigned long count)
|
static ssize_t snd_pcm_hw_writev(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
|
||||||
{
|
{
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
snd_xferv_t xferv;
|
snd_xferv_t xferv;
|
||||||
xferv.tstamp = tstamp;
|
if (tstamp)
|
||||||
|
xferv.tstamp = *tstamp;
|
||||||
|
else
|
||||||
|
xferv.tstamp.tv_sec = xferv.tstamp.tv_usec = 0;
|
||||||
xferv.vector = vector;
|
xferv.vector = vector;
|
||||||
xferv.count = count;
|
xferv.count = count;
|
||||||
result = ioctl(fd, SND_PCM_IOCTL_WRITEV_FRAMES, &xferv);
|
result = ioctl(fd, SND_PCM_IOCTL_WRITEV_FRAMES, &xferv);
|
||||||
|
|
@ -230,13 +236,16 @@ static ssize_t snd_pcm_hw_writev(void *private, snd_timestamp_t tstamp, const st
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t snd_pcm_hw_read(void *private, snd_timestamp_t tstamp, void *buffer, size_t size)
|
static ssize_t snd_pcm_hw_read(void *private, snd_timestamp_t *tstamp, void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
snd_xfer_t xfer;
|
snd_xfer_t xfer;
|
||||||
xfer.tstamp = tstamp;
|
if (tstamp)
|
||||||
|
xfer.tstamp = *tstamp;
|
||||||
|
else
|
||||||
|
xfer.tstamp.tv_sec = xfer.tstamp.tv_usec = 0;
|
||||||
xfer.buf = buffer;
|
xfer.buf = buffer;
|
||||||
xfer.count = size;
|
xfer.count = size;
|
||||||
result = ioctl(fd, SND_PCM_IOCTL_READ_FRAMES, &xfer);
|
result = ioctl(fd, SND_PCM_IOCTL_READ_FRAMES, &xfer);
|
||||||
|
|
@ -245,13 +254,16 @@ static ssize_t snd_pcm_hw_read(void *private, snd_timestamp_t tstamp, void *buff
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_hw_readv(void *private, snd_timestamp_t tstamp, const struct iovec *vector, unsigned long count)
|
ssize_t snd_pcm_hw_readv(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count)
|
||||||
{
|
{
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
|
||||||
int fd = hw->fd;
|
int fd = hw->fd;
|
||||||
snd_xferv_t xferv;
|
snd_xferv_t xferv;
|
||||||
xferv.tstamp = tstamp;
|
if (tstamp)
|
||||||
|
xferv.tstamp = *tstamp;
|
||||||
|
else
|
||||||
|
xferv.tstamp.tv_sec = xferv.tstamp.tv_usec = 0;
|
||||||
xferv.vector = vector;
|
xferv.vector = vector;
|
||||||
xferv.count = count;
|
xferv.count = count;
|
||||||
result = ioctl(fd, SND_PCM_IOCTL_READV_FRAMES, &xferv);
|
result = ioctl(fd, SND_PCM_IOCTL_READV_FRAMES, &xferv);
|
||||||
|
|
@ -348,11 +360,15 @@ static void snd_pcm_hw_dump(void *private, FILE *fp)
|
||||||
|
|
||||||
struct snd_pcm_ops snd_pcm_hw_ops = {
|
struct snd_pcm_ops snd_pcm_hw_ops = {
|
||||||
close: snd_pcm_hw_close,
|
close: snd_pcm_hw_close,
|
||||||
nonblock: snd_pcm_hw_nonblock,
|
|
||||||
info: snd_pcm_hw_info,
|
info: snd_pcm_hw_info,
|
||||||
params_info: snd_pcm_hw_params_info,
|
params_info: snd_pcm_hw_params_info,
|
||||||
params: snd_pcm_hw_params,
|
params: snd_pcm_hw_params,
|
||||||
setup: snd_pcm_hw_setup,
|
setup: snd_pcm_hw_setup,
|
||||||
|
dump: snd_pcm_hw_dump,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snd_pcm_fast_ops snd_pcm_hw_fast_ops = {
|
||||||
|
nonblock: snd_pcm_hw_nonblock,
|
||||||
channel_setup: snd_pcm_hw_channel_setup,
|
channel_setup: snd_pcm_hw_channel_setup,
|
||||||
status: snd_pcm_hw_status,
|
status: snd_pcm_hw_status,
|
||||||
frame_io: snd_pcm_hw_frame_io,
|
frame_io: snd_pcm_hw_frame_io,
|
||||||
|
|
@ -375,7 +391,6 @@ struct snd_pcm_ops snd_pcm_hw_ops = {
|
||||||
munmap_data: snd_pcm_hw_munmap_data,
|
munmap_data: snd_pcm_hw_munmap_data,
|
||||||
file_descriptor: snd_pcm_hw_file_descriptor,
|
file_descriptor: snd_pcm_hw_file_descriptor,
|
||||||
channels_mask: snd_pcm_hw_channels_mask,
|
channels_mask: snd_pcm_hw_channels_mask,
|
||||||
dump: snd_pcm_hw_dump,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int subdevice, int stream, int mode)
|
int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int subdevice, int stream, int mode)
|
||||||
|
|
@ -461,6 +476,8 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int sub
|
||||||
handle->stream = stream;
|
handle->stream = stream;
|
||||||
handle->ops = &snd_pcm_hw_ops;
|
handle->ops = &snd_pcm_hw_ops;
|
||||||
handle->op_arg = hw;
|
handle->op_arg = hw;
|
||||||
|
handle->fast_ops = &snd_pcm_hw_fast_ops;
|
||||||
|
handle->fast_op_arg = hw;
|
||||||
handle->mode = mode;
|
handle->mode = mode;
|
||||||
handle->private = hw;
|
handle->private = hw;
|
||||||
*handlep = handle;
|
*handlep = handle;
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,17 @@
|
||||||
|
|
||||||
struct snd_pcm_ops {
|
struct snd_pcm_ops {
|
||||||
int (*close)(void *private);
|
int (*close)(void *private);
|
||||||
int (*nonblock)(void *private, int nonblock);
|
|
||||||
int (*info)(void *private, snd_pcm_info_t *info);
|
int (*info)(void *private, snd_pcm_info_t *info);
|
||||||
int (*params_info)(void *private, snd_pcm_params_info_t *info);
|
int (*params_info)(void *private, snd_pcm_params_info_t *info);
|
||||||
int (*params)(void *private, snd_pcm_params_t *params);
|
int (*params)(void *private, snd_pcm_params_t *params);
|
||||||
int (*setup)(void *private, snd_pcm_setup_t *setup);
|
int (*setup)(void *private, snd_pcm_setup_t *setup);
|
||||||
int (*channel_setup)(void *private, snd_pcm_channel_setup_t *setup);
|
void (*dump)(void *private, FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snd_pcm_fast_ops {
|
||||||
|
int (*nonblock)(void *private, int nonblock);
|
||||||
int (*status)(void *private, snd_pcm_status_t *status);
|
int (*status)(void *private, snd_pcm_status_t *status);
|
||||||
|
int (*channel_setup)(void *private, snd_pcm_channel_setup_t *setup);
|
||||||
int (*prepare)(void *private);
|
int (*prepare)(void *private);
|
||||||
int (*go)(void *private);
|
int (*go)(void *private);
|
||||||
int (*drain)(void *private);
|
int (*drain)(void *private);
|
||||||
|
|
@ -39,19 +43,18 @@ struct snd_pcm_ops {
|
||||||
int (*state)(void *private);
|
int (*state)(void *private);
|
||||||
ssize_t (*frame_io)(void *private, int update);
|
ssize_t (*frame_io)(void *private, int update);
|
||||||
ssize_t (*frame_data)(void *private, off_t offset);
|
ssize_t (*frame_data)(void *private, off_t offset);
|
||||||
ssize_t (*write)(void *private, snd_timestamp_t tstamp, const void *buffer, size_t size);
|
ssize_t (*write)(void *private, snd_timestamp_t *tstamp, const void *buffer, size_t size);
|
||||||
ssize_t (*writev)(void *private, snd_timestamp_t tstamp, const struct iovec *vector, unsigned long count);
|
ssize_t (*writev)(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count);
|
||||||
ssize_t (*read)(void *private, snd_timestamp_t tstamp, void *buffer, size_t size);
|
ssize_t (*read)(void *private, snd_timestamp_t *tstamp, void *buffer, size_t size);
|
||||||
ssize_t (*readv)(void *private, snd_timestamp_t tstamp, const struct iovec *vector, unsigned long count);
|
ssize_t (*readv)(void *private, snd_timestamp_t *tstamp, const struct iovec *vector, unsigned long count);
|
||||||
|
int (*file_descriptor)(void *private);
|
||||||
|
int (*channels_mask)(void *private, bitset_t *client_vmask);
|
||||||
int (*mmap_status)(void *private, snd_pcm_mmap_status_t **status);
|
int (*mmap_status)(void *private, snd_pcm_mmap_status_t **status);
|
||||||
int (*mmap_control)(void *private, snd_pcm_mmap_control_t **control);
|
int (*mmap_control)(void *private, snd_pcm_mmap_control_t **control);
|
||||||
int (*mmap_data)(void *private, void **buffer, size_t bsize);
|
int (*mmap_data)(void *private, void **buffer, size_t bsize);
|
||||||
int (*munmap_status)(void *private, snd_pcm_mmap_status_t *status);
|
int (*munmap_status)(void *private, snd_pcm_mmap_status_t *status);
|
||||||
int (*munmap_control)(void *private, snd_pcm_mmap_control_t *control);
|
int (*munmap_control)(void *private, snd_pcm_mmap_control_t *control);
|
||||||
int (*munmap_data)(void *private, void *buffer, size_t bsize);
|
int (*munmap_data)(void *private, void *buffer, size_t bsize);
|
||||||
int (*file_descriptor)(void *private);
|
|
||||||
int (*channels_mask)(void *private, bitset_t *client_vmask);
|
|
||||||
void (*dump)(void *private, FILE *fp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct snd_pcm {
|
struct snd_pcm {
|
||||||
|
|
@ -69,6 +72,8 @@ struct snd_pcm {
|
||||||
enum { _INTERLEAVED, _NONINTERLEAVED, _COMPLEX } mmap_type;
|
enum { _INTERLEAVED, _NONINTERLEAVED, _COMPLEX } mmap_type;
|
||||||
struct snd_pcm_ops *ops;
|
struct snd_pcm_ops *ops;
|
||||||
void *op_arg;
|
void *op_arg;
|
||||||
|
struct snd_pcm_fast_ops *fast_ops;
|
||||||
|
void *fast_op_arg;
|
||||||
void *private;
|
void *private;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -442,7 +442,7 @@ int snd_pcm_mmap_status(snd_pcm_t *handle, snd_pcm_mmap_status_t **status)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = handle->ops->mmap_status(handle->op_arg, &handle->mmap_status)) < 0)
|
if ((err = handle->fast_ops->mmap_status(handle->fast_op_arg, &handle->mmap_status)) < 0)
|
||||||
return err;
|
return err;
|
||||||
if (status)
|
if (status)
|
||||||
*status = handle->mmap_status;
|
*status = handle->mmap_status;
|
||||||
|
|
@ -460,7 +460,7 @@ int snd_pcm_mmap_control(snd_pcm_t *handle, snd_pcm_mmap_control_t **control)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = handle->ops->mmap_control(handle->op_arg, &handle->mmap_control)) < 0)
|
if ((err = handle->fast_ops->mmap_control(handle->fast_op_arg, &handle->mmap_control)) < 0)
|
||||||
return err;
|
return err;
|
||||||
if (control)
|
if (control)
|
||||||
*control = handle->mmap_control;
|
*control = handle->mmap_control;
|
||||||
|
|
@ -517,7 +517,7 @@ int snd_pcm_mmap_data(snd_pcm_t *handle, void **data)
|
||||||
|
|
||||||
if (handle->setup.mmap_bytes == 0)
|
if (handle->setup.mmap_bytes == 0)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
if ((err = handle->ops->mmap_data(handle->op_arg, (void**)&handle->mmap_data, handle->setup.mmap_bytes)) < 0)
|
if ((err = handle->fast_ops->mmap_data(handle->fast_op_arg, (void**)&handle->mmap_data, handle->setup.mmap_bytes)) < 0)
|
||||||
return err;
|
return err;
|
||||||
if (data)
|
if (data)
|
||||||
*data = handle->mmap_data;
|
*data = handle->mmap_data;
|
||||||
|
|
@ -552,7 +552,7 @@ int snd_pcm_munmap_status(snd_pcm_t *handle)
|
||||||
int err;
|
int err;
|
||||||
assert(handle);
|
assert(handle);
|
||||||
assert(handle->mmap_status);
|
assert(handle->mmap_status);
|
||||||
if ((err = handle->ops->munmap_status(handle->op_arg, handle->mmap_status)) < 0)
|
if ((err = handle->fast_ops->munmap_status(handle->fast_op_arg, handle->mmap_status)) < 0)
|
||||||
return err;
|
return err;
|
||||||
handle->mmap_status = 0;
|
handle->mmap_status = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -563,7 +563,7 @@ int snd_pcm_munmap_control(snd_pcm_t *handle)
|
||||||
int err;
|
int err;
|
||||||
assert(handle);
|
assert(handle);
|
||||||
assert(handle->mmap_control);
|
assert(handle->mmap_control);
|
||||||
if ((err = handle->ops->munmap_control(handle->op_arg, handle->mmap_control)) < 0)
|
if ((err = handle->fast_ops->munmap_control(handle->fast_op_arg, handle->mmap_control)) < 0)
|
||||||
return err;
|
return err;
|
||||||
handle->mmap_control = 0;
|
handle->mmap_control = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -574,7 +574,7 @@ int snd_pcm_munmap_data(snd_pcm_t *handle)
|
||||||
int err;
|
int err;
|
||||||
assert(handle);
|
assert(handle);
|
||||||
assert(handle->mmap_data);
|
assert(handle->mmap_data);
|
||||||
if ((err = handle->ops->munmap_data(handle->op_arg, handle->mmap_data, handle->setup.mmap_bytes)) < 0)
|
if ((err = handle->fast_ops->munmap_data(handle->fast_op_arg, handle->mmap_data, handle->setup.mmap_bytes)) < 0)
|
||||||
return err;
|
return err;
|
||||||
free(handle->channels);
|
free(handle->channels);
|
||||||
handle->channels = 0;
|
handle->channels = 0;
|
||||||
|
|
|
||||||
|
|
@ -465,7 +465,7 @@ static ssize_t snd_pcm_multi_write_io(snd_pcm_multi_t *multi, size_t count)
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t snd_pcm_multi_write(void *private, snd_timestamp_t timestamp UNUSED, const void *buf, size_t count)
|
static ssize_t snd_pcm_multi_write(void *private, snd_timestamp_t *timestamp UNUSED, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
|
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
|
|
@ -516,7 +516,7 @@ static ssize_t snd_pcm_multi_writev1(snd_pcm_multi_t *multi, const struct iovec
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t snd_pcm_multi_writev(void *private, snd_timestamp_t timestamp UNUSED, const struct iovec *vector, unsigned long count)
|
static ssize_t snd_pcm_multi_writev(void *private, snd_timestamp_t *timestamp UNUSED, const struct iovec *vector, unsigned long count)
|
||||||
{
|
{
|
||||||
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
|
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
|
||||||
snd_pcm_t *handle = multi->handle;
|
snd_pcm_t *handle = multi->handle;
|
||||||
|
|
@ -544,13 +544,13 @@ static ssize_t snd_pcm_multi_writev(void *private, snd_timestamp_t timestamp UNU
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t snd_pcm_multi_read(void *private, snd_timestamp_t timestamp UNUSED, void *buf, size_t count)
|
static ssize_t snd_pcm_multi_read(void *private, snd_timestamp_t *timestamp UNUSED, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
|
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t snd_pcm_multi_readv(void *private, snd_timestamp_t timestamp UNUSED, const struct iovec *vector, unsigned long count)
|
static ssize_t snd_pcm_multi_readv(void *private, snd_timestamp_t *timestamp UNUSED, const struct iovec *vector, unsigned long count)
|
||||||
{
|
{
|
||||||
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
|
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
@ -724,11 +724,15 @@ static void snd_pcm_multi_dump(void *private, FILE *fp)
|
||||||
|
|
||||||
struct snd_pcm_ops snd_pcm_multi_ops = {
|
struct snd_pcm_ops snd_pcm_multi_ops = {
|
||||||
close: snd_pcm_multi_close,
|
close: snd_pcm_multi_close,
|
||||||
nonblock: snd_pcm_multi_nonblock,
|
|
||||||
info: snd_pcm_multi_info,
|
info: snd_pcm_multi_info,
|
||||||
params_info: snd_pcm_multi_params_info,
|
params_info: snd_pcm_multi_params_info,
|
||||||
params: snd_pcm_multi_params,
|
params: snd_pcm_multi_params,
|
||||||
setup: snd_pcm_multi_setup,
|
setup: snd_pcm_multi_setup,
|
||||||
|
dump: snd_pcm_multi_dump,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snd_pcm_fast_ops snd_pcm_multi_fast_ops = {
|
||||||
|
nonblock: snd_pcm_multi_nonblock,
|
||||||
channel_setup: snd_pcm_multi_channel_setup,
|
channel_setup: snd_pcm_multi_channel_setup,
|
||||||
status: snd_pcm_multi_status,
|
status: snd_pcm_multi_status,
|
||||||
frame_io: snd_pcm_multi_frame_io,
|
frame_io: snd_pcm_multi_frame_io,
|
||||||
|
|
@ -751,7 +755,6 @@ struct snd_pcm_ops snd_pcm_multi_ops = {
|
||||||
munmap_data: snd_pcm_multi_munmap_data,
|
munmap_data: snd_pcm_multi_munmap_data,
|
||||||
file_descriptor: snd_pcm_multi_file_descriptor,
|
file_descriptor: snd_pcm_multi_file_descriptor,
|
||||||
channels_mask: snd_pcm_multi_channels_mask,
|
channels_mask: snd_pcm_multi_channels_mask,
|
||||||
dump: snd_pcm_multi_dump,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int snd_pcm_multi_create(snd_pcm_t **handlep, size_t slaves_count,
|
int snd_pcm_multi_create(snd_pcm_t **handlep, size_t slaves_count,
|
||||||
|
|
@ -821,6 +824,8 @@ int snd_pcm_multi_create(snd_pcm_t **handlep, size_t slaves_count,
|
||||||
handle->mode = multi->slaves[0].handle->mode;
|
handle->mode = multi->slaves[0].handle->mode;
|
||||||
handle->ops = &snd_pcm_multi_ops;
|
handle->ops = &snd_pcm_multi_ops;
|
||||||
handle->op_arg = multi;
|
handle->op_arg = multi;
|
||||||
|
handle->fast_ops = &snd_pcm_multi_fast_ops;
|
||||||
|
handle->fast_op_arg = multi;
|
||||||
handle->private = multi;
|
handle->private = multi;
|
||||||
*handlep = handle;
|
*handlep = handle;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ static int snd_pcm_plug_close(void *private)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
||||||
snd_pcm_plug_clear(plug);
|
snd_pcm_plug_clear(plug);
|
||||||
free(plug->handle->ops);
|
free(plug->handle->fast_ops);
|
||||||
if (plug->close_slave)
|
if (plug->close_slave)
|
||||||
return snd_pcm_close(plug->slave);
|
return snd_pcm_close(plug->slave);
|
||||||
free(private);
|
free(private);
|
||||||
|
|
@ -403,7 +403,7 @@ static ssize_t snd_pcm_plug_frame_data(void *private, off_t offset)
|
||||||
return snd_pcm_plug_client_size(plug, ret);
|
return snd_pcm_plug_client_size(plug, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_plug_writev(void *private, snd_timestamp_t tstamp UNUSED, const struct iovec *vector, unsigned long count)
|
ssize_t snd_pcm_plug_writev(void *private, snd_timestamp_t *tstamp UNUSED, const struct iovec *vector, unsigned long count)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
||||||
snd_pcm_t *handle = plug->handle;
|
snd_pcm_t *handle = plug->handle;
|
||||||
|
|
@ -447,7 +447,7 @@ ssize_t snd_pcm_plug_writev(void *private, snd_timestamp_t tstamp UNUSED, const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_plug_readv(void *private, snd_timestamp_t tstamp UNUSED, const struct iovec *vector, unsigned long count)
|
ssize_t snd_pcm_plug_readv(void *private, snd_timestamp_t *tstamp UNUSED, const struct iovec *vector, unsigned long count)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
||||||
snd_pcm_t *handle = plug->handle;
|
snd_pcm_t *handle = plug->handle;
|
||||||
|
|
@ -491,7 +491,7 @@ ssize_t snd_pcm_plug_readv(void *private, snd_timestamp_t tstamp UNUSED, const s
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_plug_write(void *private, snd_timestamp_t tstamp UNUSED, const void *buf, size_t count)
|
ssize_t snd_pcm_plug_write(void *private, snd_timestamp_t *tstamp UNUSED, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
||||||
snd_pcm_t *handle = plug->handle;
|
snd_pcm_t *handle = plug->handle;
|
||||||
|
|
@ -525,7 +525,7 @@ ssize_t snd_pcm_plug_write(void *private, snd_timestamp_t tstamp UNUSED, const v
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_plug_read(void *private, snd_timestamp_t tstamp UNUSED, void *buf, size_t count)
|
ssize_t snd_pcm_plug_read(void *private, snd_timestamp_t *tstamp UNUSED, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
|
||||||
snd_pcm_t *handle = plug->handle;
|
snd_pcm_t *handle = plug->handle;
|
||||||
|
|
@ -628,11 +628,15 @@ static int snd_pcm_plug_params(void *private, snd_pcm_params_t *params);
|
||||||
|
|
||||||
struct snd_pcm_ops snd_pcm_plug_ops = {
|
struct snd_pcm_ops snd_pcm_plug_ops = {
|
||||||
close: snd_pcm_plug_close,
|
close: snd_pcm_plug_close,
|
||||||
nonblock: snd_pcm_plug_nonblock,
|
|
||||||
info: snd_pcm_plug_info,
|
info: snd_pcm_plug_info,
|
||||||
params_info: snd_pcm_plug_params_info,
|
params_info: snd_pcm_plug_params_info,
|
||||||
params: snd_pcm_plug_params,
|
params: snd_pcm_plug_params,
|
||||||
setup: snd_pcm_plug_setup,
|
setup: snd_pcm_plug_setup,
|
||||||
|
dump: snd_pcm_plug_dump,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snd_pcm_fast_ops snd_pcm_plug_fast_ops = {
|
||||||
|
nonblock: snd_pcm_plug_nonblock,
|
||||||
channel_setup: snd_pcm_plug_channel_setup,
|
channel_setup: snd_pcm_plug_channel_setup,
|
||||||
status: snd_pcm_plug_status,
|
status: snd_pcm_plug_status,
|
||||||
frame_io: snd_pcm_plug_frame_io,
|
frame_io: snd_pcm_plug_frame_io,
|
||||||
|
|
@ -655,7 +659,6 @@ struct snd_pcm_ops snd_pcm_plug_ops = {
|
||||||
munmap_data: snd_pcm_plug_munmap_data,
|
munmap_data: snd_pcm_plug_munmap_data,
|
||||||
file_descriptor: snd_pcm_plug_file_descriptor,
|
file_descriptor: snd_pcm_plug_file_descriptor,
|
||||||
channels_mask: snd_pcm_plug_channels_mask,
|
channels_mask: snd_pcm_plug_channels_mask,
|
||||||
dump: snd_pcm_plug_dump,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void snd_pcm_plug_slave_params(snd_pcm_plug_t *plug,
|
static void snd_pcm_plug_slave_params(snd_pcm_plug_t *plug,
|
||||||
|
|
@ -745,17 +748,13 @@ static int snd_pcm_plug_params(void *private, snd_pcm_params_t *params)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!plug->first) {
|
if (!plug->first) {
|
||||||
*plug->handle->ops = *plug->slave->ops;
|
*plug->handle->fast_ops = *plug->slave->fast_ops;
|
||||||
plug->handle->ops->params = snd_pcm_plug_params;
|
plug->handle->fast_op_arg = plug->slave->fast_op_arg;
|
||||||
plug->handle->ops->setup = snd_pcm_plug_setup;
|
|
||||||
plug->handle->ops->info = snd_pcm_plug_info;
|
|
||||||
plug->handle->ops->params_info = snd_pcm_plug_params_info;
|
|
||||||
plug->handle->op_arg = plug->slave->op_arg;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*plug->handle->ops = snd_pcm_plug_ops;
|
*plug->handle->fast_ops = snd_pcm_plug_fast_ops;
|
||||||
plug->handle->op_arg = plug;
|
plug->handle->fast_op_arg = plug;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I/O plugins
|
* I/O plugins
|
||||||
|
|
@ -803,13 +802,11 @@ int snd_pcm_plug_create(snd_pcm_t **handlep, snd_pcm_t *slave, int close_slave)
|
||||||
plug->close_slave = close_slave;
|
plug->close_slave = close_slave;
|
||||||
handle->type = SND_PCM_TYPE_PLUG;
|
handle->type = SND_PCM_TYPE_PLUG;
|
||||||
handle->stream = slave->stream;
|
handle->stream = slave->stream;
|
||||||
handle->ops = malloc(sizeof(*handle->ops));
|
handle->ops = &snd_pcm_plug_ops;
|
||||||
*handle->ops = *slave->ops;
|
handle->op_arg = plug;
|
||||||
handle->ops->params = snd_pcm_plug_params;
|
handle->fast_ops = malloc(sizeof(*handle->fast_ops));
|
||||||
handle->ops->setup = snd_pcm_plug_setup;
|
*handle->fast_ops = snd_pcm_plug_fast_ops;
|
||||||
handle->ops->info = snd_pcm_plug_info;
|
handle->fast_op_arg = plug;
|
||||||
handle->ops->params_info = snd_pcm_plug_params_info;
|
|
||||||
handle->op_arg = slave->op_arg;
|
|
||||||
handle->mode = slave->mode;
|
handle->mode = slave->mode;
|
||||||
handle->private = plug;
|
handle->private = plug;
|
||||||
*handlep = handle;
|
*handlep = handle;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue