typedef struct snd_pcm snd_pcm_t;
typedef struct snd_pcm_loopback snd_pcm_loopback_t;
-typedef enum { SND_PCM_TYPE_HW, SND_PCM_TYPE_PLUG } snd_pcm_type_t;
+typedef enum { SND_PCM_TYPE_HW, SND_PCM_TYPE_PLUG, SND_PCM_TYPE_MULTI } snd_pcm_type_t;
int snd_pcm_open(snd_pcm_t **handle, int card, int device, int mode);
int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int mode);
int snd_pcm_stream_setup(snd_pcm_t *handle, snd_pcm_stream_setup_t *setup);
int snd_pcm_channel_setup(snd_pcm_t *handle, int stream, snd_pcm_channel_setup_t *setup);
int snd_pcm_stream_status(snd_pcm_t *handle, snd_pcm_stream_status_t *status);
-int snd_pcm_stream_update(snd_pcm_t *handle, int stream);
int snd_pcm_playback_prepare(snd_pcm_t *handle);
int snd_pcm_capture_prepare(snd_pcm_t *handle);
int snd_pcm_stream_prepare(snd_pcm_t *handle, int stream);
int snd_pcm_playback_pause(snd_pcm_t *handle, int enable);
int snd_pcm_stream_pause(snd_pcm_t *handle, int stream, int enable);
ssize_t snd_pcm_transfer_size(snd_pcm_t *handle, int stream);
+int snd_pcm_stream_state(snd_pcm_t *handle, int stream);
+ssize_t snd_pcm_stream_byte_io(snd_pcm_t *handle, int stream, int update);
ssize_t snd_pcm_stream_seek(snd_pcm_t *pcm, int stream, off_t offset);
ssize_t snd_pcm_write(snd_pcm_t *handle, const void *buffer, size_t size);
ssize_t snd_pcm_read(snd_pcm_t *handle, void *buffer, size_t size);
EXTRA_LTLIBRARIES = libpcm.la
-libpcm_la_SOURCES = pcm.c pcm_hw.c pcm_plug.c pcm_common.c pcm_misc.c \
- pcm_mmap.c
+libpcm_la_SOURCES = pcm.c pcm_hw.c pcm_plug.c pcm_common.c \
+ pcm_misc.c pcm_mmap.c
libpcm_la_LIBADD = plugin/libpcmplugin.la
noinst_HEADERS = pcm_local.h
if (pcm == NULL)
return -ENOMEM;
if (mode & SND_PCM_OPEN_PLAYBACK) {
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
str->open = 1;
str->mode = (mode & SND_PCM_NONBLOCK_PLAYBACK) ? SND_PCM_NONBLOCK : 0;
}
if (mode & SND_PCM_OPEN_CAPTURE) {
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
str->open = 1;
str->mode = (mode & SND_PCM_NONBLOCK_CAPTURE) ? SND_PCM_NONBLOCK : 0;
}
{
int ret = 0;
int err;
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
{
+ int stream;
if (!pcm || !info)
return -EFAULT;
- return pcm->ops->info(pcm, info);
+ for (stream = 0; stream < 2; ++stream) {
+ if (pcm->stream[stream].open)
+ return pcm->ops->info(pcm, stream, info);
+ }
+ return -EBADFD;
}
int snd_pcm_stream_info(snd_pcm_t *pcm, snd_pcm_stream_info_t *info)
{
int err;
snd_pcm_stream_setup_t setup;
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm || !params)
return -EFAULT;
if (params->stream < 0 || params->stream > 1)
int snd_pcm_stream_setup(snd_pcm_t *pcm, snd_pcm_stream_setup_t *setup)
{
int err;
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm || !setup)
return -EFAULT;
if (setup->stream < 0 || setup->stream > 1)
const snd_pcm_stream_setup_t* snd_pcm_stream_cached_setup(snd_pcm_t *pcm, int stream)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return 0;
if (stream < 0 || stream > 1)
int snd_pcm_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channel_setup_t *setup)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm || !setup)
return -EFAULT;
if (stream < 0 || stream > 1)
return pcm->ops->stream_status(pcm, status);
}
-int snd_pcm_stream_update(snd_pcm_t *pcm, int stream)
+int snd_pcm_stream_state(snd_pcm_t *pcm, int stream)
{
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
return -EINVAL;
- if (!pcm->stream[stream].open)
+ str = &pcm->stream[stream];
+ if (!str->open)
+ return -EBADFD;
+ if (str->mmap_control)
+ return str->mmap_control->status;
+ return pcm->ops->stream_state(pcm, stream);
+}
+
+int snd_pcm_stream_byte_io(snd_pcm_t *pcm, int stream, int update)
+{
+ snd_pcm_stream_t *str;
+ if (!pcm)
+ return -EFAULT;
+ if (stream < 0 || stream > 1)
+ return -EINVAL;
+ str = &pcm->stream[stream];
+ if (!str->open)
return -EBADFD;
- return pcm->ops->stream_update(pcm, stream);
+ if (str->mmap_control && !update)
+ return str->mmap_control->byte_io;
+ return pcm->ops->stream_byte_io(pcm, stream, update);
}
int snd_pcm_stream_prepare(snd_pcm_t *pcm, int stream)
int snd_pcm_stream_go(snd_pcm_t *pcm, int stream)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
int snd_pcm_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
{
+ int stream;
if (!pcm || !sync)
return -EFAULT;
- if (!pcm->stream[SND_PCM_STREAM_PLAYBACK].open &&
- !pcm->stream[SND_PCM_STREAM_CAPTURE].open)
- return -EBADFD;
- return pcm->ops->sync_go(pcm, sync);
+ for (stream = 0; stream < 2; ++stream) {
+ if (pcm->stream[stream].open)
+ return pcm->ops->sync_go(pcm, stream, sync);
+ }
+ return -EBADFD;
}
int snd_pcm_stream_drain(snd_pcm_t *pcm, int stream)
ssize_t snd_pcm_transfer_size(snd_pcm_t *pcm, int stream)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
ssize_t snd_pcm_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
size_t bytes_per_frame;
if (!pcm)
return -EFAULT;
return -EBADFD;
if (!str->valid_setup)
return -EBADFD;
- bytes_per_frame = str->bits_per_frame / 8;
- if (bytes_per_frame > 0)
- offset -= offset % bytes_per_frame;
- return pcm->ops->stream_seek(pcm, stream, offset);
+#if 0
+ /* TODO */
+ if (str->mmap_control) {
+ } else
+#endif
+ return pcm->ops->stream_seek(pcm, stream, offset);
}
ssize_t snd_pcm_write(snd_pcm_t *pcm, const void *buffer, size_t size)
ssize_t snd_pcm_bytes_per_second(snd_pcm_t *pcm, int stream)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
int snd_pcm_dump_setup(snd_pcm_t *pcm, int stream, FILE *fp)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
snd_pcm_stream_setup_t *setup;
if (!pcm)
return -EFAULT;
}
ssize_t snd_pcm_plug_client_channels_buf(snd_pcm_plugin_handle_t *handle,
- int stream,
- char *buf,
- size_t count,
- snd_pcm_plugin_channel_t **channels)
+ int stream,
+ char *buf,
+ size_t count,
+ snd_pcm_plugin_channel_t **channels)
{
snd_pcm_plugin_t *plugin;
snd_pcm_plugin_channel_t *v;
}
ssize_t snd_pcm_plug_client_channels_iovec(snd_pcm_plugin_handle_t *handle,
- int stream,
- const struct iovec *vector,
- unsigned long count,
- snd_pcm_plugin_channel_t **channels)
+ int stream,
+ const struct iovec *vector,
+ unsigned long count,
+ snd_pcm_plugin_channel_t **channels)
{
snd_pcm_plugin_t *plugin;
snd_pcm_plugin_channel_t *v;
}
int snd_pcm_plug_playback_channels_mask(snd_pcm_plugin_handle_t *handle,
- bitset_t *client_vmask)
+ bitset_t *client_vmask)
{
#ifndef __KERNEL__
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &handle->private;
}
int snd_pcm_plug_capture_channels_mask(snd_pcm_plugin_handle_t *handle,
- bitset_t *client_vmask)
+ bitset_t *client_vmask)
{
#ifndef __KERNEL__
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &handle->private;
}
static int snd_pcm_plug_playback_disable_useless_channels(snd_pcm_plugin_handle_t *handle,
- snd_pcm_plugin_channel_t *src_channels)
+ snd_pcm_plugin_channel_t *src_channels)
{
snd_pcm_plugin_t *plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_PLAYBACK);
unsigned int nchannels = plugin->src_format.channels;
}
static int snd_pcm_plug_capture_disable_useless_channels(snd_pcm_plugin_handle_t *handle,
- snd_pcm_plugin_channel_t *src_channels,
- snd_pcm_plugin_channel_t *client_channels)
+ snd_pcm_plugin_channel_t *src_channels,
+ snd_pcm_plugin_channel_t *client_channels)
{
#ifndef __KERNEL__
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &handle->private;
}
int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offset,
- size_t samples, int format)
+ size_t samples, int format)
{
/* FIXME: sub byte resolution and odd dst_offset */
char *dst;
#include <sys/mman.h>
#include "pcm_local.h"
+typedef struct {
+ int fd;
+} snd_pcm_hw_stream_t;
+
+typedef struct snd_pcm_hw {
+ int card;
+ int device;
+ int ver;
+ snd_pcm_hw_stream_t stream[2];
+} snd_pcm_hw_t;
+
#define SND_FILE_PCM_PLAYBACK "/dev/snd/pcmC%iD%ip"
#define SND_FILE_PCM_CAPTURE "/dev/snd/pcmC%iD%ic"
#define SND_PCM_VERSION_MAX SND_PROTOCOL_VERSION(2, 0, 0)
return 0;
}
-static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
+static int snd_pcm_hw_info(snd_pcm_t *pcm, int stream, snd_pcm_info_t * info)
{
- int fd, stream;
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
- for (stream = 0; stream < 2; ++stream) {
- fd = hw->stream[stream].fd;
- if (fd >= 0)
- break;
- }
- if (fd < 0)
- return -EBADFD;
+ int fd = hw->stream[stream].fd;
if (ioctl(fd, SND_PCM_IOCTL_INFO, info) < 0)
return -errno;
return 0;
{
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
int fd = hw->stream[info->stream].fd;
- if (fd < 0)
- return -EINVAL;
if (ioctl(fd, SND_PCM_IOCTL_STREAM_INFO, info) < 0)
return -errno;
return 0;
return 0;
}
-static int snd_pcm_hw_stream_update(snd_pcm_t *pcm, int stream)
+static ssize_t snd_pcm_hw_stream_state(snd_pcm_t *pcm, int stream)
{
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
int fd = hw->stream[stream].fd;
- if (ioctl(fd, SND_PCM_IOCTL_STREAM_UPDATE) < 0)
+ snd_pcm_stream_status_t status;
+ status.stream = stream;
+ if (ioctl(fd, SND_PCM_IOCTL_STREAM_STATUS, status) < 0)
return -errno;
- return 0;
+ return status.status;
+}
+
+static ssize_t snd_pcm_hw_stream_byte_io(snd_pcm_t *pcm, int stream, int update UNUSED)
+{
+ snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
+ int fd = hw->stream[stream].fd;
+ ssize_t pos = ioctl(fd, SND_PCM_IOCTL_STREAM_BYTE_IO);
+ if (pos < 0)
+ return -errno;
+ return pos;
}
static int snd_pcm_hw_stream_prepare(snd_pcm_t *pcm, int stream)
return 0;
}
-static int snd_pcm_hw_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
+static int snd_pcm_hw_sync_go(snd_pcm_t *pcm, int stream, snd_pcm_sync_t *sync)
{
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
- int fd;
- if (pcm->stream[SND_PCM_STREAM_PLAYBACK].open)
- fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
- else
- fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
+ int fd = hw->stream[stream].fd;
if (ioctl(fd, SND_PCM_IOCTL_SYNC_GO, sync) < 0)
return -errno;
return 0;
stream_setup: snd_pcm_hw_stream_setup,
channel_setup: snd_pcm_hw_channel_setup,
stream_status: snd_pcm_hw_stream_status,
- stream_update: snd_pcm_hw_stream_update,
+ stream_byte_io: snd_pcm_hw_stream_byte_io,
+ stream_state: snd_pcm_hw_stream_state,
stream_prepare: snd_pcm_hw_stream_prepare,
stream_go: snd_pcm_hw_stream_go,
sync_go: snd_pcm_hw_sync_go,
#include <pthread.h>
#include "asoundlib.h"
-
struct snd_pcm_ops {
int (*stream_close)(snd_pcm_t *pcm, int stream);
int (*stream_nonblock)(snd_pcm_t *pcm, int stream, int nonblock);
- int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
+ int (*info)(snd_pcm_t *pcm, int stream, snd_pcm_info_t *info);
int (*stream_info)(snd_pcm_t *pcm, snd_pcm_stream_info_t *info);
int (*stream_params)(snd_pcm_t *pcm, snd_pcm_stream_params_t *params);
int (*stream_setup)(snd_pcm_t *pcm, snd_pcm_stream_setup_t *setup);
int (*channel_setup)(snd_pcm_t *pcm, int stream, snd_pcm_channel_setup_t *setup);
int (*stream_status)(snd_pcm_t *pcm, snd_pcm_stream_status_t *status);
int (*stream_prepare)(snd_pcm_t *pcm, int stream);
- int (*stream_update)(snd_pcm_t *pcm, int stream);
int (*stream_go)(snd_pcm_t *pcm, int stream);
- int (*sync_go)(snd_pcm_t *pcm, snd_pcm_sync_t *sync);
+ int (*sync_go)(snd_pcm_t *pcm, int stream, snd_pcm_sync_t *sync);
int (*stream_drain)(snd_pcm_t *pcm, int stream);
int (*stream_flush)(snd_pcm_t *pcm, int stream);
int (*stream_pause)(snd_pcm_t *pcm, int stream, int enable);
+ int (*stream_state)(snd_pcm_t *pcm, int stream);
+ ssize_t (*stream_byte_io)(snd_pcm_t *pcm, int stream, int update);
ssize_t (*stream_seek)(snd_pcm_t *pcm, int stream, off_t offset);
ssize_t (*write)(snd_pcm_t *pcm, const void *buffer, size_t size);
ssize_t (*writev)(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
int (*channels_mask)(snd_pcm_t *pcm, int stream, bitset_t *client_vmask);
};
-
-struct snd_pcm_plug_stream {
+typedef struct {
snd_pcm_plugin_t *first;
snd_pcm_plugin_t *last;
void *alloc_ptr[2];
size_t alloc_size[2];
int alloc_lock[2];
-};
+} snd_pcm_plug_stream_t;
-typedef struct snd_pcm_plug {
+typedef struct {
int close_slave;
snd_pcm_t *slave;
- struct snd_pcm_plug_stream stream[2];
+ snd_pcm_plug_stream_t stream[2];
} snd_pcm_plug_t;
-struct snd_pcm_hw_stream {
- int fd;
-};
-
-typedef struct snd_pcm_hw {
- int card;
- int device;
- int ver;
- struct snd_pcm_hw_stream stream[2];
-} snd_pcm_hw_t;
-
-struct snd_pcm_stream {
+typedef struct {
int open;
int mode;
int valid_setup;
size_t mmap_control_size;
char *mmap_data;
size_t mmap_data_size;
-};
+} snd_pcm_stream_t;
struct snd_pcm {
snd_pcm_type_t type;
int mode;
struct snd_pcm_ops *ops;
- struct snd_pcm_stream stream[2];
+ snd_pcm_stream_t stream[2];
int private[0];
};
#else
#define pdprintf( args... ) { ; }
#endif
+
+static inline ssize_t snd_pcm_mmap_playback_bytes_used(snd_pcm_stream_t *str)
+{
+ ssize_t bytes_used;
+ bytes_used = str->mmap_control->byte_data - str->mmap_control->byte_io;
+ if (bytes_used < (ssize_t)(str->setup.buffer_size - str->setup.byte_boundary))
+ bytes_used += str->setup.byte_boundary;
+ return bytes_used;
+}
+
+static inline size_t snd_pcm_mmap_capture_bytes_used(snd_pcm_stream_t *str)
+{
+ ssize_t bytes_used;
+ bytes_used = str->mmap_control->byte_io - str->mmap_control->byte_data;
+ if (bytes_used < 0)
+ bytes_used += str->setup.byte_boundary;
+ return bytes_used;
+}
+
#include <sys/uio.h>
#include "pcm_local.h"
-static inline ssize_t snd_pcm_mmap_playback_bytes_used(struct snd_pcm_stream *str)
-{
- ssize_t bytes_used;
- bytes_used = str->mmap_control->byte_data - str->mmap_control->byte_io;
- if (bytes_used < (ssize_t)(str->setup.buffer_size - str->setup.byte_boundary))
- bytes_used += str->setup.byte_boundary;
- return bytes_used;
-}
-
static ssize_t snd_pcm_mmap_playback_frames_used(snd_pcm_t *pcm)
{
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
ssize_t bytes = snd_pcm_mmap_playback_bytes_used(str);
return bytes * 8 / str->bits_per_frame;
}
-static inline size_t snd_pcm_mmap_capture_bytes_used(struct snd_pcm_stream *str)
-{
- ssize_t bytes_used;
- bytes_used = str->mmap_control->byte_io - str->mmap_control->byte_data;
- if (bytes_used < 0)
- bytes_used += str->setup.byte_boundary;
- return bytes_used;
-}
-
static size_t snd_pcm_mmap_capture_frames_used(snd_pcm_t *pcm)
{
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
size_t bytes = snd_pcm_mmap_capture_bytes_used(str);
return bytes * 8 / str->bits_per_frame;
}
int snd_pcm_mmap_frames_used(snd_pcm_t *pcm, int stream, ssize_t *frames)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
return 0;
}
-static inline size_t snd_pcm_mmap_playback_bytes_free(struct snd_pcm_stream *str)
+static inline size_t snd_pcm_mmap_playback_bytes_free(snd_pcm_stream_t *str)
{
return str->setup.buffer_size - snd_pcm_mmap_playback_bytes_used(str);
}
static size_t snd_pcm_mmap_playback_frames_free(snd_pcm_t *pcm)
{
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
size_t bytes = snd_pcm_mmap_playback_bytes_free(str);
return bytes * 8 / str->bits_per_frame;
}
-static inline ssize_t snd_pcm_mmap_capture_bytes_free(struct snd_pcm_stream *str)
+static inline ssize_t snd_pcm_mmap_capture_bytes_free(snd_pcm_stream_t *str)
{
return str->setup.buffer_size - snd_pcm_mmap_capture_bytes_used(str);
}
static ssize_t snd_pcm_mmap_capture_frames_free(snd_pcm_t *pcm)
{
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
ssize_t bytes = snd_pcm_mmap_capture_bytes_free(str);
return bytes * 8 / str->bits_per_frame;
}
int snd_pcm_mmap_frames_free(snd_pcm_t *pcm, int stream, ssize_t *frames)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
static int snd_pcm_mmap_playback_ready(snd_pcm_t *pcm)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
if (str->mmap_control->status == SND_PCM_STATUS_XRUN)
return -EPIPE;
static int snd_pcm_mmap_capture_ready(snd_pcm_t *pcm)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
int ret = 0;
str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
if (str->mmap_control->status == SND_PCM_STATUS_XRUN) {
int snd_pcm_mmap_ready(snd_pcm_t *pcm, int stream)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
snd_pcm_mmap_control_t *ctrl;
if (!pcm)
return -EFAULT;
static size_t snd_pcm_mmap_playback_bytes_xfer(snd_pcm_t *pcm, size_t bytes)
{
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
snd_pcm_mmap_control_t *ctrl = str->mmap_control;
size_t bytes_cont;
size_t byte_data = ctrl->byte_data;
static size_t snd_pcm_mmap_capture_bytes_xfer(snd_pcm_t *pcm, size_t bytes)
{
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
snd_pcm_mmap_control_t *ctrl = str->mmap_control;
size_t bytes_cont;
size_t byte_data = ctrl->byte_data;
static ssize_t snd_pcm_mmap_playback_frames_xfer(snd_pcm_t *pcm, size_t frames)
{
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
size_t bytes = frames * str->bits_per_frame / 8;
bytes = snd_pcm_mmap_playback_bytes_xfer(pcm, bytes);
return bytes * 8 / str->bits_per_frame;
static ssize_t snd_pcm_mmap_capture_frames_xfer(snd_pcm_t *pcm, size_t frames)
{
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
size_t bytes = frames * str->bits_per_frame / 8;
bytes = snd_pcm_mmap_capture_bytes_xfer(pcm, bytes);
return bytes * 8 / str->bits_per_frame;
ssize_t snd_pcm_mmap_frames_xfer(snd_pcm_t *pcm, int stream, size_t frames)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
ssize_t snd_pcm_mmap_frames_offset(snd_pcm_t *pcm, int stream)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
snd_pcm_mmap_control_t *ctrl;
if (!pcm)
return -EFAULT;
int snd_pcm_mmap_commit_frames(snd_pcm_t *pcm, int stream, int frames)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
snd_pcm_mmap_control_t *ctrl;
size_t byte_data, bytes;
if (!pcm)
ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels, size_t frames)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
snd_pcm_mmap_control_t *ctrl;
size_t offset = 0;
size_t result = 0;
} else {
if (ctrl->status == SND_PCM_STATUS_RUNNING &&
str->mode & SND_PCM_NONBLOCK)
- snd_pcm_stream_update(pcm, SND_PCM_STREAM_PLAYBACK);
+ snd_pcm_stream_byte_io(pcm, SND_PCM_STREAM_PLAYBACK, 1);
}
while (frames > 0) {
ssize_t mmap_offset;
ssize_t snd_pcm_mmap_write_frames(snd_pcm_t *pcm, const void *buffer, size_t frames)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
unsigned int nchannels;
if (!pcm)
return -EFAULT;
ssize_t snd_pcm_mmap_write(snd_pcm_t *pcm, const void *buffer, size_t bytes)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
unsigned int nchannels;
ssize_t frames;
if (!pcm)
ssize_t snd_pcm_mmap_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long vcount)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
size_t result = 0;
unsigned int nchannels;
if (!pcm)
ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels, size_t frames)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
snd_pcm_mmap_control_t *ctrl;
size_t offset = 0;
size_t result = 0;
} else {
if (ctrl->status == SND_PCM_STATUS_RUNNING &&
str->mode & SND_PCM_NONBLOCK)
- snd_pcm_stream_update(pcm, SND_PCM_STREAM_CAPTURE);
+ snd_pcm_stream_byte_io(pcm, SND_PCM_STREAM_CAPTURE, 1);
}
if (ctrl->status == SND_PCM_STATUS_PREPARED &&
str->setup.start_mode == SND_PCM_START_DATA) {
ssize_t snd_pcm_mmap_read_frames(snd_pcm_t *pcm, const void *buffer, size_t frames)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
unsigned int nchannels;
if (!pcm)
return -EFAULT;
ssize_t snd_pcm_mmap_read(snd_pcm_t *pcm, void *buffer, size_t bytes)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
unsigned int nchannels;
ssize_t frames;
if (!pcm)
ssize_t snd_pcm_mmap_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long vcount)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
size_t result = 0;
unsigned int nchannels;
if (!pcm)
return result * str->bits_per_frame / 8;
}
-static ssize_t mmap_playback_bytes_xfer(struct snd_pcm_stream *str)
+static ssize_t mmap_playback_bytes_xfer(snd_pcm_stream_t *str)
{
snd_pcm_mmap_control_t *ctrl = str->mmap_control;
size_t bytes_cont;
return bytes;
}
-static ssize_t mmap_capture_bytes_xfer(struct snd_pcm_stream *str)
+static ssize_t mmap_capture_bytes_xfer(snd_pcm_stream_t *str)
{
snd_pcm_mmap_control_t *ctrl = str->mmap_control;
size_t bytes_cont;
int snd_pcm_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
snd_pcm_stream_info_t info;
size_t csize;
int err;
int snd_pcm_mmap_get_areas(snd_pcm_t *pcm, int stream, snd_pcm_channel_area_t *areas)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
snd_pcm_channel_setup_t s;
snd_pcm_channel_area_t *a, *ap;
unsigned int channel;
int snd_pcm_mmap_data(snd_pcm_t *pcm, int stream, void **data)
{
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
snd_pcm_stream_info_t info;
size_t bsize;
int err;
int snd_pcm_munmap_control(snd_pcm_t *pcm, int stream)
{
int err;
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
int snd_pcm_munmap_data(snd_pcm_t *pcm, int stream)
{
int err;
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
{
int idx;
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- struct snd_pcm_plug_stream *plugstr = &plug->stream[stream];
+ snd_pcm_plug_stream_t *plugstr = &plug->stream[stream];
for (idx = 0; idx < 2; idx++) {
if (plugstr->alloc_lock[idx])
int idx;
snd_pcm_plug_t *plug;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
if (!ptr)
return;
int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin)
{
snd_pcm_plug_t *plug;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
snd_pcm_t *pcm;
if (!plugin)
return -EFAULT;
int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin)
{
snd_pcm_plug_t *plug;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
snd_pcm_t *pcm;
if (!plugin)
return -EFAULT;
snd_pcm_plugin_t *plugin1, *plugin1_prev;
snd_pcm_plug_t *plug;
snd_pcm_t *pcm;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
if (!plugin)
return -EFAULT;
pcm = plugin->handle;
{
snd_pcm_plugin_t *plugin;
snd_pcm_plug_t *plug;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
if (!pcm)
return -EFAULT;
if (stream < 0 || stream > 1)
{
snd_pcm_plugin_t *plugin, *plugin_next;
snd_pcm_plug_t *plug;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
int idx;
if (!pcm)
snd_pcm_plugin_t *snd_pcm_plug_first(snd_pcm_t *pcm, int stream)
{
snd_pcm_plug_t *plug;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
if (!pcm)
return NULL;
if (stream < 0 || stream > 1)
snd_pcm_plugin_t *snd_pcm_plug_last(snd_pcm_t *pcm, int stream)
{
snd_pcm_plug_t *plug;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
if (!pcm)
return NULL;
if (stream < 0 || stream > 1)
return snd_pcm_stream_nonblock(plug->slave, stream, nonblock);
}
-static int snd_pcm_plug_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
+static int snd_pcm_plug_info(snd_pcm_t *pcm, int stream, snd_pcm_info_t * info)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
return snd_pcm_info(plug->slave, info);
{
int err;
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- struct snd_pcm_stream *str;
+ snd_pcm_stream_t *str;
if ((err = snd_pcm_stream_info(plug->slave, info)) < 0)
return err;
snd_pcm_plugin_t *plugin;
int err;
snd_pcm_plug_t *plug;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
plug = (snd_pcm_plug_t*) &pcm->private;
plugstr = &plug->stream[stream];
if (snd_pcm_plug_direct(pcm, stream))
return snd_pcm_stream_params(plug->slave, params);
+ /* compute right sizes */
+ slave_params.frag_size = snd_pcm_plug_slave_size(pcm, stream, params->frag_size);
+ slave_params.buffer_size = snd_pcm_plug_slave_size(pcm, stream, params->buffer_size);
+ slave_params.bytes_fill_max = snd_pcm_plug_slave_size(pcm, stream, params->bytes_fill_max);
+ slave_params.bytes_min = snd_pcm_plug_slave_size(pcm, stream, params->bytes_min);
+ slave_params.bytes_xrun_max = snd_pcm_plug_slave_size(pcm, stream, params->bytes_xrun_max);
+ slave_params.bytes_align = snd_pcm_plug_slave_size(pcm, stream, params->bytes_align);
+ if (slave_params.byte_boundary == 0 || slave_params.byte_boundary > INT_MAX)
+ slave_params.byte_boundary = INT_MAX;
+ slave_params.byte_boundary /= params->buffer_size;
+ if (slave_params.byte_boundary > INT_MAX / slave_params.buffer_size)
+ slave_params.byte_boundary = INT_MAX;
+ else
+ slave_params.byte_boundary *= slave_params.buffer_size;
+
/*
* I/O plugins
*/
return err;
}
- /* compute right sizes */
- slave_params.buffer_size = snd_pcm_plug_slave_size(pcm, stream, slave_params.buffer_size);
- slave_params.frag_size = snd_pcm_plug_slave_size(pcm, stream, slave_params.frag_size);
- slave_params.bytes_fill_max = snd_pcm_plug_slave_size(pcm, stream, slave_params.bytes_fill_max);
- slave_params.bytes_min = snd_pcm_plug_slave_size(pcm, stream, slave_params.bytes_min);
- slave_params.bytes_xrun_max = snd_pcm_plug_slave_size(pcm, stream, slave_params.bytes_xrun_max);
- slave_params.bytes_align = snd_pcm_plug_slave_size(pcm, stream, slave_params.bytes_align);
-
pdprintf("params requested params: format = %i, rate = %i, channels = %i\n", slave_params.format.format, slave_params.format.rate, slave_params.format.channels);
err = snd_pcm_stream_params(plug->slave, &slave_params);
if (err < 0)
{
int err;
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- struct snd_pcm_plug_stream *plugstr;
+ snd_pcm_plug_stream_t *plugstr;
err = snd_pcm_stream_setup(plug->slave, setup);
if (err < 0)
if (snd_pcm_plug_direct(pcm, status->stream))
return 0;
- /* FIXME: may overflow */
status->byte_io = snd_pcm_plug_client_size(pcm, status->stream, status->byte_io);
status->byte_data = snd_pcm_plug_client_size(pcm, status->stream, status->byte_data);
- status->bytes_used = snd_pcm_plug_client_size(pcm, status->stream, status->bytes_used);
+ status->bytes_avail = snd_pcm_plug_client_size(pcm, status->stream, status->bytes_avail);
+ status->bytes_avail_max = snd_pcm_plug_client_size(pcm, status->stream, status->bytes_avail_max);
return 0;
}
-static int snd_pcm_plug_stream_update(snd_pcm_t *pcm, int stream)
+static int snd_pcm_plug_stream_state(snd_pcm_t *pcm, int stream)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- int err;
- err = snd_pcm_stream_update(plug->slave, stream);
- if (err < 0)
- return err;
- if (snd_pcm_plug_direct(pcm, stream))
- return 0;
-#if 0
- /* To think more about that */
- if ((err = snd_pcm_plug_action(pcm, stream, UPDATE, 0))<0)
- return err;
-#endif
- return 0;
+ return snd_pcm_stream_state(plug->slave, stream);
+}
+
+static int snd_pcm_plug_stream_byte_io(snd_pcm_t *pcm, int stream, int update)
+{
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+ return snd_pcm_stream_byte_io(plug->slave, stream, update);
}
static int snd_pcm_plug_stream_prepare(snd_pcm_t *pcm, int stream)
return snd_pcm_stream_go(plug->slave, stream);
}
-static int snd_pcm_plug_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
+static int snd_pcm_plug_sync_go(snd_pcm_t *pcm, int stream, snd_pcm_sync_t *sync)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
return snd_pcm_sync_go(plug->slave, sync);
static int snd_pcm_plug_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channel_setup_t *setup)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- struct snd_pcm_stream *str;
- unsigned int channel;
- int width;
if (snd_pcm_plug_direct(pcm, stream))
return snd_pcm_channel_setup(plug->slave, stream, setup);
-
- channel = setup->channel;
- memset(setup, 0, sizeof(*setup));
- setup->channel = channel;
- str = &pcm->stream[stream];
- if (!str->mmap_data) {
- setup->area.addr = 0;
- return 0;
- }
- if (channel >= str->setup.format.channels)
- return -EINVAL;
-
- if (str->setup.format.interleave) {
- setup->area.addr = str->mmap_data;
- setup->area.first = setup->channel * str->sample_width;
- setup->area.step = str->bits_per_frame;
- } else {
- size_t size = str->mmap_data_size / str->setup.format.channels;
- setup->area.addr = str->mmap_data + setup->channel * size;
- setup->area.first = 0;
- setup->area.step = str->sample_width;
- }
- return 0;
+ /* FIXME: non mmap setups */
+ return -ENXIO;
}
static ssize_t snd_pcm_plug_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
ssize_t snd_pcm_plug_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
unsigned int k, step, channels;
int size = 0;
if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_PLAYBACK))
ssize_t snd_pcm_plug_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
+ snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
unsigned int k, step, channels;
int size = 0;
if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_CAPTURE))
stream_setup: snd_pcm_plug_stream_setup,
channel_setup: snd_pcm_plug_channel_setup,
stream_status: snd_pcm_plug_stream_status,
- stream_update: snd_pcm_plug_stream_update,
+ stream_byte_io: snd_pcm_plug_stream_byte_io,
+ stream_state: snd_pcm_plug_stream_state,
stream_prepare: snd_pcm_plug_stream_prepare,
stream_go: snd_pcm_plug_stream_go,
sync_go: snd_pcm_plug_sync_go,
mmap_t *data;
snd_pcm_plugin_channel_t *sv;
snd_pcm_channel_area_t *dv;
- struct snd_pcm_stream *stream;
+ snd_pcm_stream_t *stream;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
size_t pos;
unsigned int channel;
snd_pcm_plugin_channel_t *dv;
snd_pcm_channel_area_t *sv;
- struct snd_pcm_stream *stream;
+ snd_pcm_stream_t *stream;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
size_t pos;
mmap_t *data;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
- struct snd_pcm_stream *stream;
+ snd_pcm_stream_t *stream;
int err;
if (plugin == NULL)