-M convert all static checks in asserts
M plug sync and pos problems
M Loopback implementation?
L add hsearch_r code from glibc (for compatibility with older distributions)
#if !defined(SND_PROTOCOL_VERSION) || !defined(SND_PROTOCOL_INCOMPATIBLE)
#error not found
#else
-#if !defined(SND_PCM_IOCTL_STREAM_BYTE_IO)
+#if !defined(SND_PCM_IOCTL_STREAM_FRAME_IO)
#error wrong version
#endif
exit(0);
int snd_pcm_stream_pause(snd_pcm_t *handle, int stream, int enable);
int snd_pcm_stream_state(snd_pcm_t *handle, int stream);
int snd_pcm_mmap_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_mmap_stream_byte_io(snd_pcm_t *handle, int stream);
-ssize_t snd_pcm_stream_byte_data(snd_pcm_t *handle, int stream);
-ssize_t snd_pcm_mmap_stream_byte_data(snd_pcm_t *handle, int stream);
-ssize_t snd_pcm_stream_seek(snd_pcm_t *pcm, int stream, off_t offset);
-ssize_t snd_pcm_mmap_stream_seek(snd_pcm_t *pcm, int stream, off_t offset);
+ssize_t snd_pcm_stream_frame_io(snd_pcm_t *handle, int stream, int update);
+ssize_t snd_pcm_mmap_stream_frame_io(snd_pcm_t *handle, int stream);
+ssize_t snd_pcm_stream_frame_data(snd_pcm_t *handle, int stream, off_t offset);
+ssize_t snd_pcm_mmap_stream_frame_data(snd_pcm_t *handle, 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);
ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
int snd_pcm_get_format_value(const char* name);
int snd_pcm_dump_setup(snd_pcm_t *pcm, int stream, FILE *fp);
-int snd_pcm_mmap(snd_pcm_t *handle, int stream, snd_pcm_mmap_control_t **control, void **buffer);
+int snd_pcm_mmap(snd_pcm_t *handle, int stream, snd_pcm_mmap_status_t **status, snd_pcm_mmap_control_t **control, void **buffer);
int snd_pcm_munmap(snd_pcm_t *handle, int stream);
+int snd_pcm_mmap_status(snd_pcm_t *handle, int stream, snd_pcm_mmap_status_t **status);
int snd_pcm_mmap_control(snd_pcm_t *handle, int stream, snd_pcm_mmap_control_t **control);
int snd_pcm_mmap_data(snd_pcm_t *handle, int stream, void **buffer);
+int snd_pcm_munmap_status(snd_pcm_t *handle, int stream);
int snd_pcm_munmap_control(snd_pcm_t *handle, int stream);
int snd_pcm_munmap_data(snd_pcm_t *handle, int stream);
int snd_pcm_channels_mask(snd_pcm_t *pcm, int stream, bitset_t *client_vmask);
ssize_t snd_pcm_mmap_read_frames(snd_pcm_t *pcm, const void *buffer, size_t frames);
int snd_pcm_mmap_get_areas(snd_pcm_t *pcm, int stream, snd_pcm_channel_area_t *areas);
-ssize_t snd_pcm_bytes_per_second(snd_pcm_t *pcm, int stream);
-
int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
size_t samples, int format);
int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, size_t dst_offset,
const snd_pcm_channel_area_t *dst_channels, size_t dst_offset,
size_t vcount, size_t frames, int format);
+ssize_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, int stream, ssize_t bytes);
+ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, int stream, ssize_t frames);
+ssize_t snd_pcm_bytes_to_samples(snd_pcm_t *pcm, int stream, ssize_t bytes);
+ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int stream, ssize_t samples);
+
/* misc */
int snd_pcm_format_physical_width(int format); /* in bits */
int snd_pcm_build_linear_format(int width, int unsignd, int big_endian);
ssize_t snd_pcm_format_size(int format, size_t samples);
-ssize_t snd_pcm_format_bytes_per_second(snd_pcm_format_t *format);
u_int8_t snd_pcm_format_silence(int format);
u_int16_t snd_pcm_format_silence_16(int format);
u_int32_t snd_pcm_format_silence_32(int format);
snd_pcm_plugin_t *snd_pcm_plug_first(snd_pcm_t *handle, int stream);
snd_pcm_plugin_t *snd_pcm_plug_last(snd_pcm_t *handle, int stream);
int snd_pcm_plug_direct(snd_pcm_t *pcm, int stream);
-ssize_t snd_pcm_plug_client_frames(snd_pcm_t *handle, int stream, size_t drv_frames);
-ssize_t snd_pcm_plug_slave_frames(snd_pcm_t *handle, int stream, size_t clt_frames);
-ssize_t snd_pcm_plug_client_size(snd_pcm_t *handle, int stream, size_t drv_size);
-ssize_t snd_pcm_plug_slave_size(snd_pcm_t *handle, int stream, size_t clt_size);
-
-/*
- * Plug-In helpers
- */
-
-ssize_t snd_pcm_plugin_src_frames_to_size(snd_pcm_plugin_t *plugin, size_t frames);
-ssize_t snd_pcm_plugin_dst_frames_to_size(snd_pcm_plugin_t *plugin, size_t frames);
-ssize_t snd_pcm_plugin_src_size_to_frames(snd_pcm_plugin_t *plugin, size_t size);
-ssize_t snd_pcm_plugin_dst_size_to_frames(snd_pcm_plugin_t *plugin, size_t size);
+ssize_t snd_pcm_plug_client_size(snd_pcm_t *handle, int stream, size_t drv_frames);
+ssize_t snd_pcm_plug_slave_size(snd_pcm_t *handle, int stream, size_t clt_frames);
/*
* Plug-In constructors
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
assert(str->open);
+ if (str->mmap_status) {
+ if ((err = snd_pcm_munmap_status(pcm, stream)) < 0)
+ ret = err;
+ }
if (str->mmap_control) {
if ((err = snd_pcm_munmap_control(pcm, stream)) < 0)
ret = err;
if ((err = pcm->ops->stream_setup(pcm, setup)) < 0)
return err;
memcpy(&str->setup, setup, sizeof(*setup));
- str->sample_width = snd_pcm_format_physical_width(setup->format.format);
- str->bits_per_frame = str->sample_width * setup->format.channels;
- str->frames_per_frag = setup->frag_size * 8 / str->bits_per_frame;
+ str->bits_per_sample = snd_pcm_format_physical_width(setup->format.format);
+ str->bits_per_frame = str->bits_per_sample * setup->format.channels;
str->valid_setup = 1;
return 0;
}
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
assert(str->open);
- if (str->mmap_control)
- return str->mmap_control->state;
+ if (str->mmap_status)
+ return str->mmap_status->state;
return pcm->ops->stream_state(pcm, stream);
}
-int snd_pcm_stream_byte_io(snd_pcm_t *pcm, int stream, int update)
+int snd_pcm_stream_frame_io(snd_pcm_t *pcm, int stream, int update)
{
snd_pcm_stream_t *str;
assert(pcm);
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
assert(str->valid_setup);
- if (str->mmap_control && !update)
- return str->mmap_control->byte_io;
- return pcm->ops->stream_byte_io(pcm, stream, update);
-}
-
-int snd_pcm_stream_byte_data(snd_pcm_t *pcm, int stream)
-{
- snd_pcm_stream_t *str;
- assert(pcm);
- assert(stream >= 0 && stream <= 1);
- str = &pcm->stream[stream];
- assert(str->valid_setup);
- if (str->mmap_control)
- return str->mmap_control->byte_data;
- return pcm->ops->stream_seek(pcm, stream, 0);
+ if (str->mmap_status && !update)
+ return str->mmap_status->frame_io;
+ return pcm->ops->stream_frame_io(pcm, stream, update);
}
int snd_pcm_stream_prepare(snd_pcm_t *pcm, int stream)
return snd_pcm_stream_pause(pcm, SND_PCM_STREAM_PLAYBACK, enable);
}
-ssize_t snd_pcm_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
+ssize_t snd_pcm_stream_frame_data(snd_pcm_t *pcm, int stream, off_t offset)
{
snd_pcm_stream_t *str;
assert(pcm);
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
assert(str->valid_setup);
- if (str->mmap_control)
- return snd_pcm_mmap_stream_seek(pcm, stream, offset);
- else
- return pcm->ops->stream_seek(pcm, stream, offset);
+ if (str->mmap_control) {
+ if (offset == 0)
+ return str->mmap_control->frame_data;
+ if (str->mmap_status)
+ return snd_pcm_mmap_stream_frame_data(pcm, stream, offset);
+ }
+ return pcm->ops->stream_frame_data(pcm, stream, offset);
}
ssize_t snd_pcm_write(snd_pcm_t *pcm, const void *buffer, size_t size)
str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
assert(str->valid_setup);
assert(size == 0 || buffer);
- assert(size % str->setup.bytes_align == 0);
+ assert(size % str->setup.frames_align == 0);
return pcm->ops->write(pcm, buffer, size);
}
str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
assert(str->valid_setup);
assert(size == 0 || buffer);
- assert(size % str->setup.bytes_align == 0);
+ assert(size % str->setup.frames_align == 0);
return pcm->ops->read(pcm, buffer, size);
}
return pcm->ops->channels_mask(pcm, stream, client_vmask);
}
-ssize_t snd_pcm_bytes_per_second(snd_pcm_t *pcm, int stream)
-{
- snd_pcm_stream_t *str;
- assert(pcm);
- assert(stream >= 0 && stream <= 1);
- str = &pcm->stream[stream];
- assert(str->valid_setup);
- return snd_pcm_format_bytes_per_second(&str->setup.format);
-}
-
typedef struct {
int value;
const char* name;
fprintf(fp, "buffer_size: %d\n", setup->buffer_size);
fprintf(fp, "frag_size: %d\n", setup->frag_size);
fprintf(fp, "frags: %d\n", setup->frags);
- fprintf(fp, "byte_boundary: %d\n", setup->byte_boundary);
+ fprintf(fp, "frame_boundary: %d\n", setup->frame_boundary);
fprintf(fp, "msbits_per_sample: %d\n", setup->msbits_per_sample);
- fprintf(fp, "bytes_min: %d\n", setup->bytes_min);
- fprintf(fp, "bytes_align: %d\n", setup->bytes_align);
- fprintf(fp, "bytes_xrun_max: %d\n", setup->bytes_xrun_max);
+ fprintf(fp, "frames_min: %d\n", setup->frames_min);
+ fprintf(fp, "frames_align: %d\n", setup->frames_align);
+ fprintf(fp, "frames_xrun_max: %d\n", setup->frames_xrun_max);
fprintf(fp, "fill_mode: %s\n", assoc(setup->fill_mode, fills));
- fprintf(fp, "bytes_fill_max: %d\n", setup->bytes_fill_max);
+ fprintf(fp, "frames_fill_max: %d\n", setup->frames_fill_max);
return 0;
}
return -1;
}
+ssize_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, int stream, int bytes)
+{
+ snd_pcm_stream_t *str;
+ assert(pcm);
+ assert(stream >= 0 && stream <= 1);
+ str = &pcm->stream[stream];
+ assert(str->valid_setup);
+ return bytes * 8 / str->bits_per_frame;
+}
+
+ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, int stream, int frames)
+{
+ snd_pcm_stream_t *str;
+ assert(pcm);
+ assert(stream >= 0 && stream <= 1);
+ str = &pcm->stream[stream];
+ assert(str->valid_setup);
+ return frames * str->bits_per_frame / 8;
+}
+
+ssize_t snd_pcm_bytes_to_samples(snd_pcm_t *pcm, int stream, int bytes)
+{
+ snd_pcm_stream_t *str;
+ assert(pcm);
+ assert(stream >= 0 && stream <= 1);
+ str = &pcm->stream[stream];
+ assert(str->valid_setup);
+ return bytes * 8 / str->bits_per_sample;
+}
+
+ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int stream, int samples)
+{
+ snd_pcm_stream_t *str;
+ assert(pcm);
+ assert(stream >= 0 && stream <= 1);
+ str = &pcm->stream[stream];
+ assert(str->valid_setup);
+ return samples * str->bits_per_sample / 8;
+}
*channels = v;
if ((width = snd_pcm_format_physical_width(format->format)) < 0)
return width;
- size = format->channels * frames * width;
+ size = frames * format->channels * width;
assert(size % 8 == 0);
size /= 8;
ptr = (char *)snd_pcm_plug_buf_alloc(plugin->handle, plugin->stream, size);
return 0;
}
-ssize_t snd_pcm_plugin_src_frames_to_size(snd_pcm_plugin_t *plugin, size_t frames)
-{
- ssize_t result;
-
- assert(plugin);
- result = frames * plugin->src_format.channels * plugin->src_width;
- assert(result % 8 == 0);
- return result / 8;
-}
-
-ssize_t snd_pcm_plugin_dst_frames_to_size(snd_pcm_plugin_t *plugin, size_t frames)
-{
- ssize_t result;
-
- assert(plugin);
- result = frames * plugin->dst_format.channels * plugin->dst_width;
- assert(result % 8 == 0);
- return result / 8;
-}
-
-ssize_t snd_pcm_plugin_src_size_to_frames(snd_pcm_plugin_t *plugin, size_t size)
-{
- ssize_t result;
- long tmp;
-
- assert(plugin);
- result = size * 8;
- tmp = plugin->src_format.channels * plugin->src_width;
- assert(result % tmp == 0);
- return result / tmp;
-}
-
-ssize_t snd_pcm_plugin_dst_size_to_frames(snd_pcm_plugin_t *plugin, size_t size)
-{
- ssize_t result;
- long tmp;
-
- assert(plugin);
- result = size * 8;
- tmp = plugin->dst_format.channels * plugin->dst_width;
- assert(result % tmp == 0);
- return result / tmp;
-}
-
-ssize_t snd_pcm_plug_client_frames(snd_pcm_plugin_handle_t *handle, int stream, size_t drv_frames)
+ssize_t snd_pcm_plug_client_size(snd_pcm_plugin_handle_t *handle, int stream, size_t drv_frames)
{
snd_pcm_plugin_t *plugin, *plugin_prev, *plugin_next;
return drv_frames;
}
-ssize_t snd_pcm_plug_slave_frames(snd_pcm_plugin_handle_t *handle, int stream, size_t clt_frames)
+ssize_t snd_pcm_plug_slave_size(snd_pcm_plugin_handle_t *handle, int stream, size_t clt_frames)
{
snd_pcm_plugin_t *plugin, *plugin_prev, *plugin_next;
ssize_t frames;
return frames;
}
-ssize_t snd_pcm_plug_client_size(snd_pcm_plugin_handle_t *handle, int stream, size_t drv_size)
-{
- snd_pcm_plugin_t *plugin;
- ssize_t result = 0;
-
- assert(handle);
- if (drv_size == 0)
- return 0;
- if (stream == SND_PCM_STREAM_PLAYBACK) {
- plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_PLAYBACK);
- if (plugin == NULL)
- return drv_size;
- result = snd_pcm_plugin_dst_size_to_frames(plugin, drv_size);
- if (result < 0)
- return result;
- result = snd_pcm_plug_client_frames(handle, SND_PCM_STREAM_PLAYBACK, result);
- if (result < 0)
- return result;
- plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_PLAYBACK);
- result = snd_pcm_plugin_src_frames_to_size(plugin, result);
- } else if (stream == SND_PCM_STREAM_CAPTURE) {
- plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_CAPTURE);
- if (plugin == NULL)
- return drv_size;
- result = snd_pcm_plugin_src_size_to_frames(plugin, drv_size);
- if (result < 0)
- return result;
- result = snd_pcm_plug_client_frames(handle, SND_PCM_STREAM_CAPTURE, result);
- if (result < 0)
- return result;
- plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_CAPTURE);
- result = snd_pcm_plugin_dst_frames_to_size(plugin, result);
- } else
- assert(0);
- return result;
-}
-
-ssize_t snd_pcm_plug_slave_size(snd_pcm_plugin_handle_t *handle, int stream, size_t clt_size)
-{
- snd_pcm_plugin_t *plugin;
- ssize_t result = 0;
-
- assert(handle);
- if (clt_size == 0)
- return 0;
- if (stream == SND_PCM_STREAM_PLAYBACK) {
- plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_PLAYBACK);
- if (plugin == NULL)
- return clt_size;
- result = snd_pcm_plugin_src_size_to_frames(plugin, clt_size);
- if (result < 0)
- return result;
- result = snd_pcm_plug_slave_frames(handle, SND_PCM_STREAM_PLAYBACK, result);
- if (result < 0)
- return result;
- plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_PLAYBACK);
- result = snd_pcm_plugin_dst_frames_to_size(plugin, result);
- } else if (stream == SND_PCM_STREAM_CAPTURE) {
- plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_CAPTURE);
- if (plugin == NULL)
- return clt_size;
- result = snd_pcm_plugin_dst_size_to_frames(plugin, clt_size);
- if (result < 0)
- return result;
- result = snd_pcm_plug_slave_frames(handle, SND_PCM_STREAM_CAPTURE, result);
- if (result < 0)
- return result;
- plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_CAPTURE);
- result = snd_pcm_plugin_src_frames_to_size(plugin, result);
- } else
- assert(0);
- return result;
-}
-
-
unsigned int snd_pcm_plug_formats(unsigned int formats)
{
int linfmts = (SND_PCM_FMT_U8 | SND_PCM_FMT_S8 |
*channels = v;
if ((width = snd_pcm_format_physical_width(format->format)) < 0)
return width;
- assert(count * 8 % width == 0);
nchannels = format->channels;
assert(format->interleave || format->channels == 1);
for (channel = 0; channel < nchannels; channel++, v++) {
return width;
nchannels = format->channels;
if (format->interleave) {
- assert(count == 1 && vector->iov_base &&
- vector->iov_len * 8 % width == 0);
+ assert(count == 1 && vector->iov_base);
for (channel = 0; channel < nchannels; channel++, v++) {
v->enabled = 1;
size_t len;
assert(count == nchannels);
len = vector->iov_len;
- assert(len * 8 % width == 0);
for (channel = 0; channel < nchannels; channel++, v++, vector++) {
assert(vector->iov_len == len);
v->enabled = (vector->iov_base != NULL);
v->area.first = 0;
v->area.step = width;
}
- return len * nchannels;
+ return len;
}
}
{
snd_pcm_plugin_t *plugin, *next;
snd_pcm_plugin_channel_t *dst_channels;
- ssize_t frames;
int err;
+ ssize_t frames = size;
if ((err = snd_pcm_plug_playback_disable_useless_channels(handle, src_channels)) < 0)
return err;
plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_PLAYBACK);
- frames = snd_pcm_plugin_src_size_to_frames(plugin, size);
- if (frames < 0)
- return frames;
while (plugin && frames > 0) {
if ((next = plugin->next) != NULL) {
ssize_t frames1 = frames;
plugin = next;
}
snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_PLAYBACK, src_channels->aptr);
- frames = snd_pcm_plug_client_frames(handle, SND_PCM_STREAM_PLAYBACK, frames);
- if (frames < 0)
- return frames;
- return snd_pcm_plugin_src_frames_to_size(snd_pcm_plug_first(handle, SND_PCM_STREAM_PLAYBACK), frames);
+ return snd_pcm_plug_client_size(handle, SND_PCM_STREAM_PLAYBACK, frames);
}
ssize_t snd_pcm_plug_read_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plugin_channel_t *dst_channels_final, size_t size)
{
snd_pcm_plugin_t *plugin, *next;
snd_pcm_plugin_channel_t *src_channels, *dst_channels;
- ssize_t frames;
+ ssize_t frames = size;
int err;
plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_CAPTURE);
- frames = snd_pcm_plugin_dst_size_to_frames(plugin, size);
- if (frames < 0)
- return frames;
- frames = snd_pcm_plug_slave_frames(handle, SND_PCM_STREAM_CAPTURE, frames);
+ frames = snd_pcm_plug_slave_size(handle, SND_PCM_STREAM_CAPTURE, frames);
if (frames < 0)
return frames;
src_channels = dst_channels;
}
snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_CAPTURE, src_channels->aptr);
- return snd_pcm_plugin_dst_frames_to_size(snd_pcm_plug_last(handle, SND_PCM_STREAM_CAPTURE), frames);
+ return frames;
}
int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offset,
return status.state;
}
-static ssize_t snd_pcm_hw_stream_byte_io(snd_pcm_t *pcm, int stream, int update UNUSED)
+static ssize_t snd_pcm_hw_stream_frame_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);
+ ssize_t pos = ioctl(fd, SND_PCM_IOCTL_STREAM_FRAME_IO);
if (pos < 0)
return -errno;
return pos;
return 0;
}
-static ssize_t snd_pcm_hw_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
+static ssize_t snd_pcm_hw_stream_frame_data(snd_pcm_t *pcm, int stream, off_t offset)
{
+ ssize_t result;
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
int fd = hw->stream[stream].fd;
- return lseek(fd, offset, SEEK_CUR);
+ result = ioctl(fd, SND_PCM_IOCTL_STREAM_FRAME_DATA, offset);
+ if (result < 0)
+ return -errno;
+ return result;
}
static ssize_t snd_pcm_hw_write(snd_pcm_t *pcm, const void *buffer, size_t size)
ssize_t result;
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
int fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
- result = write(fd, buffer, size);
+ snd_xfer_t xfer;
+ xfer.buf = (char*) buffer;
+ xfer.count = size;
+ result = ioctl(fd, SND_PCM_IOCTL_WRITE_FRAMES, &xfer);
if (result < 0)
return -errno;
return result;
ssize_t result;
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
int fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
-#if 0
- result = writev(fd, vector, count);
-#else
- {
- snd_v_args_t args;
- args.vector = vector;
- args.count = count;
- result = ioctl(fd, SND_IOCTL_WRITEV, &args);
- }
-#endif
+ snd_xferv_t xferv;
+ xferv.vector = vector;
+ xferv.count = count;
+ result = ioctl(fd, SND_PCM_IOCTL_WRITEV_FRAMES, &xferv);
if (result < 0)
return -errno;
return result;
ssize_t result;
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
int fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
- result = read(fd, buffer, size);
+ snd_xfer_t xfer;
+ xfer.buf = buffer;
+ xfer.count = size;
+ result = ioctl(fd, SND_PCM_IOCTL_READ_FRAMES, &xfer);
if (result < 0)
return -errno;
return result;
ssize_t result;
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
int fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
-#if 0
- result = readv(fd, vector, count);
-#else
- {
- snd_v_args_t args;
- args.vector = vector;
- args.count = count;
- result = ioctl(fd, SND_IOCTL_READV, &args);
- }
-#endif
+ snd_xferv_t xferv;
+ xferv.vector = vector;
+ xferv.count = count;
+ result = ioctl(fd, SND_PCM_IOCTL_READV_FRAMES, &xferv);
if (result < 0)
return -errno;
return result;
}
-static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control, size_t csize)
+static int snd_pcm_hw_mmap_status(snd_pcm_t *pcm, int stream, snd_pcm_mmap_status_t **status)
{
- void *caddr;
+ void *ptr;
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
- caddr = mmap(NULL, csize, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
- hw->stream[stream].fd, SND_PCM_MMAP_OFFSET_CONTROL);
- if (caddr == MAP_FAILED || caddr == NULL)
+ ptr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ, MAP_FILE|MAP_SHARED,
+ hw->stream[stream].fd, SND_PCM_MMAP_OFFSET_STATUS);
+ if (ptr == MAP_FAILED || ptr == NULL)
return -errno;
- *control = caddr;
+ *status = ptr;
+ return 0;
+}
+
+static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control)
+{
+ void *ptr;
+ snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
+ ptr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
+ hw->stream[stream].fd, SND_PCM_MMAP_OFFSET_CONTROL);
+ if (ptr == MAP_FAILED || ptr == NULL)
+ return -errno;
+ *control = ptr;
return 0;
}
return 0;
}
-static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm UNUSED, int stream UNUSED, snd_pcm_mmap_control_t *control, size_t csize)
+static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm UNUSED, int stream UNUSED, snd_pcm_mmap_status_t *status)
+{
+ if (munmap(status, sizeof(*status)) < 0)
+ return -errno;
+ return 0;
+}
+
+static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm UNUSED, int stream UNUSED, snd_pcm_mmap_control_t *control)
{
- if (munmap(control, csize) < 0)
+ if (munmap(control, sizeof(*control)) < 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_byte_io: snd_pcm_hw_stream_byte_io,
+ stream_frame_io: snd_pcm_hw_stream_frame_io,
stream_state: snd_pcm_hw_stream_state,
stream_prepare: snd_pcm_hw_stream_prepare,
stream_go: snd_pcm_hw_stream_go,
stream_drain: snd_pcm_hw_stream_drain,
stream_flush: snd_pcm_hw_stream_flush,
stream_pause: snd_pcm_hw_stream_pause,
- stream_seek: snd_pcm_hw_stream_seek,
+ stream_frame_data: snd_pcm_hw_stream_frame_data,
write: snd_pcm_hw_write,
writev: snd_pcm_hw_writev,
read: snd_pcm_hw_read,
readv: snd_pcm_hw_readv,
+ mmap_status: snd_pcm_hw_mmap_status,
mmap_control: snd_pcm_hw_mmap_control,
mmap_data: snd_pcm_hw_mmap_data,
+ munmap_status: snd_pcm_hw_munmap_status,
munmap_control: snd_pcm_hw_munmap_control,
munmap_data: snd_pcm_hw_munmap_data,
file_descriptor: snd_pcm_hw_file_descriptor,
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 (*stream_frame_io)(snd_pcm_t *pcm, int stream, int update);
+ ssize_t (*stream_frame_data)(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);
ssize_t (*read)(snd_pcm_t *pcm, void *buffer, size_t size);
ssize_t (*readv)(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
- int (*mmap_control)(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control, size_t csize);
+ int (*mmap_status)(snd_pcm_t *pcm, int stream, snd_pcm_mmap_status_t **status);
+ int (*mmap_control)(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control);
int (*mmap_data)(snd_pcm_t *pcm, int stream, void **buffer, size_t bsize);
- int (*munmap_control)(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t *control, size_t csize);
+ int (*munmap_status)(snd_pcm_t *pcm, int stream, snd_pcm_mmap_status_t *status);
+ int (*munmap_control)(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t *control);
int (*munmap_data)(snd_pcm_t *pcm, int stream, void *buffer, size_t bsize);
int (*file_descriptor)(snd_pcm_t* pcm, int stream);
int (*channels_mask)(snd_pcm_t *pcm, int stream, bitset_t *client_vmask);
int valid_setup;
snd_pcm_stream_setup_t setup;
snd_pcm_channel_area_t *channels;
- size_t sample_width;
+ size_t bits_per_sample;
size_t bits_per_frame;
- size_t frames_per_frag;
+ snd_pcm_mmap_status_t *mmap_status;
snd_pcm_mmap_control_t *mmap_control;
- size_t mmap_control_size;
char *mmap_data;
size_t mmap_data_size;
enum { _INTERLEAVED, _NONINTERLEAVED, _COMPLEX } mmap_type;
#define pdprintf( args... ) { ; }
#endif
-static inline size_t snd_pcm_mmap_playback_bytes_avail(snd_pcm_stream_t *str)
+static inline size_t snd_pcm_mmap_playback_frames_avail(snd_pcm_stream_t *str)
{
- ssize_t bytes_avail = str->mmap_control->byte_io + str->setup.buffer_size - str->mmap_control->byte_data;
- if (bytes_avail < 0)
- bytes_avail += str->setup.byte_boundary;
- return bytes_avail;
+ ssize_t frames_avail;
+ frames_avail = str->mmap_status->frame_io + str->setup.buffer_size - str->mmap_control->frame_data;
+ if (frames_avail < 0)
+ frames_avail += str->setup.frame_boundary;
+ return frames_avail;
}
-static inline size_t snd_pcm_mmap_capture_bytes_avail(snd_pcm_stream_t *str)
+static inline size_t snd_pcm_mmap_capture_frames_avail(snd_pcm_stream_t *str)
{
- ssize_t bytes_avail = str->mmap_control->byte_io - str->mmap_control->byte_data;
- if (bytes_avail < 0)
- bytes_avail += str->setup.byte_boundary;
- return bytes_avail;
+ ssize_t frames_avail;
+ frames_avail = str->mmap_status->frame_io - str->mmap_control->frame_data;
+ if (frames_avail < 0)
+ frames_avail += str->setup.frame_boundary;
+ return frames_avail;
}
}
}
-ssize_t snd_pcm_format_bytes_per_second(snd_pcm_format_t *format)
-{
- return snd_pcm_format_size(format->format, format->channels * format->rate);
-}
-
u_int64_t snd_pcm_format_silence_64(int format)
{
switch (format) {
return (u_int8_t)snd_pcm_format_silence_64(format);
}
-ssize_t snd_pcm_format_set_silence(int format, void *data, size_t count)
+ssize_t snd_pcm_format_set_silence(int format, void *data, size_t samples)
{
- size_t count1;
-
- if (count == 0)
+ if (samples == 0)
return 0;
switch (snd_pcm_format_width(format)) {
- case 4:
+ case 4: {
+ u_int8_t silence = snd_pcm_format_silence_64(format);
+ size_t samples1;
+ if (samples % 2 != 0)
+ return -EINVAL;
+ samples1 = samples / 2;
+ memset(data, silence, samples1);
+ break;
+ }
case 8: {
u_int8_t silence = snd_pcm_format_silence_64(format);
- memset(data, silence, count);
+ memset(data, silence, samples);
break;
}
case 16: {
u_int16_t silence = snd_pcm_format_silence_64(format);
- if (count % 2)
- return -EINVAL;
- count1 = count / 2;
- while (count1-- > 0)
+ while (samples-- > 0)
*((u_int16_t *)data)++ = silence;
break;
}
case 32: {
u_int32_t silence = snd_pcm_format_silence_64(format);
- if (count % 4)
- return -EINVAL;
- count1 = count / 4;
- while (count1-- > 0)
+ while (samples-- > 0)
*((u_int32_t *)data)++ = silence;
break;
}
case 64: {
u_int64_t silence = snd_pcm_format_silence_64(format);
- if (count % 8)
- return -EINVAL;
- count1 = count / 8;
- while (count1-- > 0)
+ while (samples-- > 0)
*((u_int64_t *)data)++ = silence;
}
default:
return -EINVAL;
}
- return count;
+ return samples;
}
static int linear_formats[4*2*2] = {
#include <sys/uio.h>
#include "pcm_local.h"
-static ssize_t snd_pcm_mmap_playback_frames_avail(snd_pcm_t *pcm)
-{
- snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
- ssize_t bytes = snd_pcm_mmap_playback_bytes_avail(str);
- return bytes * 8 / str->bits_per_frame;
-}
-
-static size_t snd_pcm_mmap_capture_frames_avail(snd_pcm_t *pcm)
-{
- snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
- size_t bytes = snd_pcm_mmap_capture_bytes_avail(str);
- return bytes * 8 / str->bits_per_frame;
-}
-
int snd_pcm_frames_avail(snd_pcm_t *pcm, int stream, ssize_t *frames)
{
snd_pcm_stream_t *str;
assert(pcm);
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
- assert(str->mmap_control);
+ assert(str->mmap_status && str->mmap_control);
if (stream == SND_PCM_STREAM_PLAYBACK)
- *frames = snd_pcm_mmap_playback_frames_avail(pcm);
+ *frames = snd_pcm_mmap_playback_frames_avail(str);
else
- *frames = snd_pcm_mmap_capture_frames_avail(pcm);
+ *frames = snd_pcm_mmap_capture_frames_avail(str);
return 0;
}
{
snd_pcm_stream_t *str;
str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
- if (str->mmap_control->state == SND_PCM_STATE_XRUN)
+ if (str->mmap_status->state == SND_PCM_STATE_XRUN)
return -EPIPE;
- return snd_pcm_mmap_playback_bytes_avail(str) >= str->setup.bytes_min;
+ return snd_pcm_mmap_playback_frames_avail(str) >= str->setup.frames_min;
}
static int snd_pcm_mmap_capture_ready(snd_pcm_t *pcm)
snd_pcm_stream_t *str;
int ret = 0;
str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
- if (str->mmap_control->state == SND_PCM_STATE_XRUN) {
+ if (str->mmap_status->state == SND_PCM_STATE_XRUN) {
ret = -EPIPE;
if (str->setup.xrun_mode == SND_PCM_XRUN_DRAIN)
return -EPIPE;
}
- if (snd_pcm_mmap_capture_bytes_avail(str) >= str->setup.bytes_min)
+ if (snd_pcm_mmap_capture_frames_avail(str) >= str->setup.frames_min)
return 1;
return ret;
}
int snd_pcm_mmap_ready(snd_pcm_t *pcm, int stream)
{
snd_pcm_stream_t *str;
- snd_pcm_mmap_control_t *ctrl;
assert(pcm);
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
- ctrl = str->mmap_control;
- assert(ctrl);
- assert(ctrl->state >= SND_PCM_STATE_PREPARED);
+ assert(str->mmap_status && str->mmap_control);
+ assert(str->mmap_status->state >= SND_PCM_STATE_PREPARED);
if (stream == SND_PCM_STREAM_PLAYBACK) {
return snd_pcm_mmap_playback_ready(pcm);
} else {
}
}
-static size_t snd_pcm_mmap_playback_bytes_xfer(snd_pcm_t *pcm, size_t bytes)
+static size_t snd_pcm_mmap_playback_frames_xfer(snd_pcm_t *pcm, size_t frames)
{
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 bytes_avail = snd_pcm_mmap_playback_bytes_avail(str);
- if (bytes_avail < bytes)
- bytes = bytes_avail;
- bytes_cont = str->setup.buffer_size - ctrl->byte_data % str->setup.buffer_size;
- if (bytes_cont < bytes)
- bytes = bytes_cont;
- return bytes;
+ snd_pcm_mmap_control_t *control = str->mmap_control;
+ size_t frames_cont;
+ size_t frames_avail = snd_pcm_mmap_playback_frames_avail(str);
+ if (frames_avail < frames)
+ frames = frames_avail;
+ frames_cont = str->setup.buffer_size - control->frame_data % str->setup.buffer_size;
+ if (frames_cont < frames)
+ frames = frames_cont;
+ return frames;
}
-static size_t snd_pcm_mmap_capture_bytes_xfer(snd_pcm_t *pcm, size_t bytes)
+static size_t snd_pcm_mmap_capture_frames_xfer(snd_pcm_t *pcm, size_t frames)
{
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 bytes_avail = snd_pcm_mmap_capture_bytes_avail(str);
- if (bytes_avail < bytes)
- bytes = bytes_avail;
- bytes_cont = str->setup.buffer_size - ctrl->byte_data % str->setup.buffer_size;
- if (bytes_cont < bytes)
- bytes = bytes_cont;
- return bytes;
-}
-
-static ssize_t snd_pcm_mmap_playback_frames_xfer(snd_pcm_t *pcm, size_t frames)
-{
- 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)
-{
- 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;
+ snd_pcm_mmap_control_t *control = str->mmap_control;
+ size_t frames_cont;
+ size_t frames_avail = snd_pcm_mmap_capture_frames_avail(str);
+ if (frames_avail < frames)
+ frames = frames_avail;
+ frames_cont = str->setup.buffer_size - control->frame_data % str->setup.buffer_size;
+ if (frames_cont < frames)
+ frames = frames_cont;
+ return frames;
}
ssize_t snd_pcm_mmap_frames_xfer(snd_pcm_t *pcm, int stream, size_t frames)
assert(pcm);
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
- assert(str->mmap_control);
+ assert(str->mmap_status && str->mmap_control);
if (stream == SND_PCM_STREAM_PLAYBACK)
return snd_pcm_mmap_playback_frames_xfer(pcm, frames);
else
ssize_t snd_pcm_mmap_frames_offset(snd_pcm_t *pcm, int stream)
{
snd_pcm_stream_t *str;
- snd_pcm_mmap_control_t *ctrl;
assert(pcm);
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
- ctrl = str->mmap_control;
- assert(ctrl);
- return (ctrl->byte_data % str->setup.buffer_size) * 8 / str->bits_per_frame;
-}
-
-int snd_pcm_mmap_stream_state(snd_pcm_t *pcm, int stream)
-{
- snd_pcm_stream_t *str;
- assert(pcm);
- assert(stream >= 0 && stream <= 1);
- str = &pcm->stream[stream];
assert(str->mmap_control);
- return str->mmap_control->state;
+ return str->mmap_control->frame_data % str->setup.buffer_size;
}
-int snd_pcm_mmap_stream_byte_io(snd_pcm_t *pcm, int stream)
+int snd_pcm_mmap_stream_state(snd_pcm_t *pcm, int stream)
{
snd_pcm_stream_t *str;
assert(pcm);
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
- assert(str->mmap_control);
- return str->mmap_control->byte_io;
+ assert(str->mmap_status);
+ return str->mmap_status->state;
}
-int snd_pcm_mmap_stream_byte_data(snd_pcm_t *pcm, int stream)
+int snd_pcm_mmap_stream_frame_io(snd_pcm_t *pcm, int stream)
{
snd_pcm_stream_t *str;
assert(pcm);
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
- assert(str->mmap_control);
- return str->mmap_control->byte_data;
+ assert(str->mmap_status);
+ return str->mmap_status->frame_io;
}
-ssize_t snd_pcm_mmap_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
+ssize_t snd_pcm_mmap_stream_frame_data(snd_pcm_t *pcm, int stream, off_t offset)
{
snd_pcm_stream_t *str;
- ssize_t byte_data;
+ ssize_t frame_data;
assert(pcm);
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
- assert(str->mmap_control);
- byte_data = str->mmap_control->byte_data;
+ assert(str->mmap_status && str->mmap_control);
+ frame_data = str->mmap_control->frame_data;
if (offset == 0)
- return byte_data;
- switch (str->mmap_control->state) {
+ return frame_data;
+ switch (str->mmap_status->state) {
case SND_PCM_STATE_RUNNING:
if (str->setup.mode == SND_PCM_MODE_FRAME)
- snd_pcm_stream_byte_io(pcm, stream, 1);
+ snd_pcm_stream_frame_io(pcm, stream, 1);
break;
case SND_PCM_STATE_PREPARED:
break;
if (offset < -(ssize_t)str->setup.buffer_size)
offset = -(ssize_t)str->setup.buffer_size;
else
- offset -= offset % str->setup.bytes_align;
- byte_data += offset;
- if (byte_data < 0)
- byte_data += str->setup.byte_boundary;
+ offset -= offset % str->setup.frames_align;
+ frame_data += offset;
+ if (frame_data < 0)
+ frame_data += str->setup.frame_boundary;
} else {
- size_t bytes_avail;
+ size_t frames_avail;
if (stream == SND_PCM_STREAM_PLAYBACK)
- bytes_avail = snd_pcm_mmap_playback_bytes_avail(str);
+ frames_avail = snd_pcm_mmap_playback_frames_avail(str);
else
- bytes_avail = snd_pcm_mmap_capture_bytes_avail(str);
- if ((size_t)offset > bytes_avail)
- offset = bytes_avail;
- offset -= offset % str->setup.bytes_align;
- byte_data += offset;
- if ((size_t)byte_data >= str->setup.byte_boundary)
- byte_data -= str->setup.byte_boundary;
+ frames_avail = snd_pcm_mmap_capture_frames_avail(str);
+ if ((size_t)offset > frames_avail)
+ offset = frames_avail;
+ offset -= offset % str->setup.frames_align;
+ frame_data += offset;
+ if ((size_t)frame_data >= str->setup.frame_boundary)
+ frame_data -= str->setup.frame_boundary;
}
- str->mmap_control->byte_data = byte_data;
- return byte_data;
+ str->mmap_control->frame_data = frame_data;
+ return frame_data;
}
ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels, size_t frames)
{
snd_pcm_stream_t *str;
- snd_pcm_mmap_control_t *ctrl;
+ snd_pcm_mmap_status_t *status;
size_t offset = 0;
size_t result = 0;
int err;
str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
- ctrl = str->mmap_control;
- assert(ctrl->state >= SND_PCM_STATE_PREPARED);
+ assert(str->mmap_data && str->mmap_status && str->mmap_control);
+ status = str->mmap_status;
+ assert(status->state >= SND_PCM_STATE_PREPARED);
if (str->setup.mode == SND_PCM_MODE_FRAGMENT) {
- assert(frames % str->frames_per_frag == 0);
+ assert(frames % str->setup.frag_size == 0);
} else {
- if (ctrl->state == SND_PCM_STATE_RUNNING &&
+ if (status->state == SND_PCM_STATE_RUNNING &&
str->mode & SND_PCM_NONBLOCK)
- snd_pcm_stream_byte_io(pcm, SND_PCM_STREAM_PLAYBACK, 1);
+ snd_pcm_stream_frame_io(pcm, SND_PCM_STREAM_PLAYBACK, 1);
}
while (frames > 0) {
ssize_t mmap_offset;
return ready;
if (!ready) {
struct pollfd pfd;
- if (ctrl->state != SND_PCM_STATE_RUNNING)
+ if (status->state != SND_PCM_STATE_RUNNING)
return result > 0 ? result : -EPIPE;
if (str->mode & SND_PCM_NONBLOCK)
return result > 0 ? result : -EAGAIN;
assert(frames1 > 0);
mmap_offset = snd_pcm_mmap_frames_offset(pcm, SND_PCM_STREAM_PLAYBACK);
snd_pcm_areas_copy(channels, offset, str->channels, mmap_offset, str->setup.format.channels, frames1, str->setup.format.format);
- if (ctrl->state == SND_PCM_STATE_XRUN)
+ if (status->state == SND_PCM_STATE_XRUN)
return result > 0 ? result : -EPIPE;
- snd_pcm_stream_seek(pcm, SND_PCM_STREAM_PLAYBACK, frames1 * str->bits_per_frame / 8);
+ snd_pcm_stream_frame_data(pcm, SND_PCM_STREAM_PLAYBACK, frames1);
frames -= frames1;
offset += frames1;
result += frames1;
- if (ctrl->state == SND_PCM_STATE_PREPARED &&
+ if (status->state == SND_PCM_STATE_PREPARED &&
(str->setup.start_mode == SND_PCM_START_DATA ||
(str->setup.start_mode == SND_PCM_START_FULL &&
!snd_pcm_mmap_playback_ready(pcm)))) {
return result;
}
-ssize_t snd_pcm_mmap_write_frames(snd_pcm_t *pcm, const void *buffer, size_t frames)
+ssize_t snd_pcm_mmap_write(snd_pcm_t *pcm, const void *buffer, size_t frames)
{
snd_pcm_stream_t *str;
unsigned int nchannels;
assert(pcm);
str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
- assert(str->mmap_data && str->mmap_control);
+ assert(str->mmap_data && str->mmap_status && str->mmap_control);
assert(frames == 0 || buffer);
nchannels = str->setup.format.channels;
assert(str->setup.format.interleave || nchannels == 1);
unsigned int channel;
for (channel = 0; channel < nchannels; ++channel) {
channels[channel].addr = (char*)buffer;
- channels[channel].first = str->sample_width * channel;
+ channels[channel].first = str->bits_per_sample * channel;
channels[channel].step = str->bits_per_frame;
}
return snd_pcm_mmap_write_areas(pcm, channels, frames);
}
}
-ssize_t snd_pcm_mmap_write(snd_pcm_t *pcm, const void *buffer, size_t bytes)
-{
- snd_pcm_stream_t *str;
- unsigned int nchannels;
- ssize_t frames;
- assert(pcm);
- str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
- assert(str->mmap_data && str->mmap_control);
- assert(bytes == 0 || buffer);
- nchannels = str->setup.format.channels;
- assert(str->setup.format.interleave || nchannels == 1);
- frames = bytes * 8 / str->bits_per_frame;
- frames = snd_pcm_mmap_write_frames(pcm, buffer, frames);
- if (frames <= 0)
- return frames;
- return frames * str->bits_per_frame / 8;
-}
-
ssize_t snd_pcm_mmap_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long vcount)
{
snd_pcm_stream_t *str;
unsigned int nchannels;
assert(pcm);
str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
- assert(str->mmap_data && str->mmap_control);
+ assert(str->mmap_data && str->mmap_status && str->mmap_control);
assert(vcount == 0 || vector);
nchannels = str->setup.format.channels;
if (str->setup.format.interleave) {
unsigned int b;
for (b = 0; b < vcount; b++) {
ssize_t ret;
- size_t frames = vector[b].iov_len * 8 / str->bits_per_frame;
- ret = snd_pcm_mmap_write_frames(pcm, vector[b].iov_base, frames);
+ size_t frames = vector[b].iov_len;
+ ret = snd_pcm_mmap_write(pcm, vector[b].iov_base, frames);
if (ret < 0) {
if (result <= 0)
return ret;
for (b = 0; b < bcount; b++) {
unsigned int v;
ssize_t ret;
- size_t bytes = 0;
- size_t frames;
- bytes = vector[0].iov_len;
+ size_t frames = vector[0].iov_len;
for (v = 0; v < nchannels; ++v) {
- assert(vector[v].iov_len == bytes);
+ assert(vector[v].iov_len == frames);
channels[v].addr = vector[v].iov_base;
channels[v].first = 0;
- channels[v].step = str->sample_width;
+ channels[v].step = str->bits_per_sample;
}
- frames = bytes * 8 / str->sample_width;
ret = snd_pcm_mmap_write_areas(pcm, channels, frames);
if (ret < 0) {
if (result <= 0)
vector += nchannels;
}
}
- return result * str->bits_per_frame / 8;
+ return result;
}
ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels, size_t frames)
{
snd_pcm_stream_t *str;
- snd_pcm_mmap_control_t *ctrl;
+ snd_pcm_mmap_status_t *status;
size_t offset = 0;
size_t result = 0;
int err;
str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
- ctrl = str->mmap_control;
- assert(ctrl->state >= SND_PCM_STATE_PREPARED);
+ assert(str->mmap_data && str->mmap_status && str->mmap_control);
+ status = str->mmap_status;
+ assert(status->state >= SND_PCM_STATE_PREPARED);
if (str->setup.mode == SND_PCM_MODE_FRAGMENT) {
- assert(frames % str->frames_per_frag == 0);
+ assert(frames % str->setup.frag_size == 0);
} else {
- if (ctrl->state == SND_PCM_STATE_RUNNING &&
+ if (status->state == SND_PCM_STATE_RUNNING &&
str->mode & SND_PCM_NONBLOCK)
- snd_pcm_stream_byte_io(pcm, SND_PCM_STREAM_CAPTURE, 1);
+ snd_pcm_stream_frame_io(pcm, SND_PCM_STREAM_CAPTURE, 1);
}
- if (ctrl->state == SND_PCM_STATE_PREPARED &&
+ if (status->state == SND_PCM_STATE_PREPARED &&
str->setup.start_mode == SND_PCM_START_DATA) {
err = snd_pcm_stream_go(pcm, SND_PCM_STREAM_CAPTURE);
if (err < 0)
return ready;
if (!ready) {
struct pollfd pfd;
- if (ctrl->state != SND_PCM_STATE_RUNNING)
+ if (status->state != SND_PCM_STATE_RUNNING)
return result > 0 ? result : -EPIPE;
if (str->mode & SND_PCM_NONBLOCK)
return result > 0 ? result : -EAGAIN;
assert(frames1 > 0);
mmap_offset = snd_pcm_mmap_frames_offset(pcm, SND_PCM_STREAM_CAPTURE);
snd_pcm_areas_copy(str->channels, mmap_offset, channels, offset, str->setup.format.channels, frames1, str->setup.format.format);
- if (ctrl->state == SND_PCM_STATE_XRUN &&
+ if (status->state == SND_PCM_STATE_XRUN &&
str->setup.xrun_mode == SND_PCM_XRUN_DRAIN)
return result > 0 ? result : -EPIPE;
- snd_pcm_stream_seek(pcm, SND_PCM_STREAM_CAPTURE, frames1 * str->bits_per_frame / 8);
+ snd_pcm_stream_frame_data(pcm, SND_PCM_STREAM_CAPTURE, frames1);
frames -= frames1;
offset += frames1;
result += frames1;
return result;
}
-ssize_t snd_pcm_mmap_read_frames(snd_pcm_t *pcm, const void *buffer, size_t frames)
+ssize_t snd_pcm_mmap_read(snd_pcm_t *pcm, void *buffer, size_t frames)
{
snd_pcm_stream_t *str;
unsigned int nchannels;
assert(pcm);
str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
- assert(str->mmap_data && str->mmap_control);
+ assert(str->mmap_data && str->mmap_status && str->mmap_control);
assert(frames == 0 || buffer);
nchannels = str->setup.format.channels;
assert(str->setup.format.interleave || nchannels == 1);
unsigned int channel;
for (channel = 0; channel < nchannels; ++channel) {
channels[channel].addr = (char*)buffer;
- channels[channel].first = str->sample_width * channel;
+ channels[channel].first = str->bits_per_sample * channel;
channels[channel].step = str->bits_per_frame;
}
return snd_pcm_mmap_read_areas(pcm, channels, frames);
}
}
-ssize_t snd_pcm_mmap_read(snd_pcm_t *pcm, void *buffer, size_t bytes)
-{
- snd_pcm_stream_t *str;
- unsigned int nchannels;
- ssize_t frames;
- assert(pcm);
- str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
- assert(str->mmap_data && str->mmap_control);
- assert(bytes == 0 || buffer);
- nchannels = str->setup.format.channels;
- assert(str->setup.format.interleave || nchannels == 1);
- frames = bytes * 8 / str->bits_per_frame;
- frames = snd_pcm_mmap_read_frames(pcm, buffer, frames);
- if (frames <= 0)
- return frames;
- return frames * str->bits_per_frame / 8;
-}
-
ssize_t snd_pcm_mmap_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long vcount)
{
snd_pcm_stream_t *str;
unsigned int nchannels;
assert(pcm);
str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
- assert(str->mmap_data && str->mmap_control);
+ assert(str->mmap_data && str->mmap_status && str->mmap_control);
assert(vcount == 0 || vector);
nchannels = str->setup.format.channels;
if (str->setup.format.interleave) {
unsigned int b;
for (b = 0; b < vcount; b++) {
ssize_t ret;
- size_t frames = vector[b].iov_len * 8 / str->bits_per_frame;
- ret = snd_pcm_mmap_read_frames(pcm, vector[b].iov_base, frames);
+ size_t frames = vector[b].iov_len;
+ ret = snd_pcm_mmap_read(pcm, vector[b].iov_base, frames);
if (ret < 0) {
if (result <= 0)
return ret;
for (b = 0; b < bcount; b++) {
unsigned int v;
ssize_t ret;
- size_t bytes = 0;
- size_t frames;
- bytes = vector[0].iov_len;
+ size_t frames = vector[0].iov_len;
for (v = 0; v < nchannels; ++v) {
- assert(vector[v].iov_len == bytes);
+ assert(vector[v].iov_len == frames);
channels[v].addr = vector[v].iov_base;
channels[v].first = 0;
- channels[v].step = str->sample_width;
+ channels[v].step = str->bits_per_sample;
}
- frames = bytes * 8 / str->sample_width;
ret = snd_pcm_mmap_read_areas(pcm, channels, frames);
if (ret < 0) {
if (result <= 0)
vector += nchannels;
}
}
- return result * str->bits_per_frame / 8;
+ return result;
+}
+
+int snd_pcm_mmap_status(snd_pcm_t *pcm, int stream, snd_pcm_mmap_status_t **status)
+{
+ snd_pcm_stream_t *str;
+ int err;
+ assert(pcm);
+ assert(stream >= 0 && stream <= 1);
+ str = &pcm->stream[stream];
+ assert(str->valid_setup);
+ if (str->mmap_status) {
+ if (status)
+ *status = str->mmap_status;
+ return 0;
+ }
+
+ if ((err = pcm->ops->mmap_status(pcm, stream, &str->mmap_status)) < 0)
+ return err;
+ if (status)
+ *status = str->mmap_status;
+ return 0;
}
int snd_pcm_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control)
{
snd_pcm_stream_t *str;
- size_t csize;
int err;
assert(pcm);
assert(stream >= 0 && stream <= 1);
*control = str->mmap_control;
return 0;
}
- csize = sizeof(snd_pcm_mmap_control_t);
- if ((err = pcm->ops->mmap_control(pcm, stream, &str->mmap_control, csize)) < 0)
+ if ((err = pcm->ops->mmap_control(pcm, stream, &str->mmap_control)) < 0)
return err;
if (control)
*control = str->mmap_control;
- str->mmap_control_size = csize;
return 0;
}
if (areas)
areas[channel] = s.area;
*ap = s.area;
- if (ap->step != str->sample_width || ap->first != 0)
+ if (ap->step != str->bits_per_sample || ap->first != 0)
noninterleaved = 0;
if (ap->addr != a[0].addr ||
ap->step != str->bits_per_frame ||
- ap->first != channel * str->sample_width)
+ ap->first != channel * str->bits_per_sample)
interleaved = 0;
}
if (noninterleaved)
return 0;
}
-int snd_pcm_mmap(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control, void **data)
+int snd_pcm_mmap(snd_pcm_t *pcm, int stream, snd_pcm_mmap_status_t **status, snd_pcm_mmap_control_t **control, void **data)
{
int err;
- err = snd_pcm_mmap_control(pcm, stream, control);
+ err = snd_pcm_mmap_status(pcm, stream, status);
if (err < 0)
return err;
+ err = snd_pcm_mmap_control(pcm, stream, control);
+ if (err < 0) {
+ snd_pcm_munmap_status(pcm, stream);
+ return err;
+ }
err = snd_pcm_mmap_data(pcm, stream, data);
if (err < 0) {
+ snd_pcm_munmap_status(pcm, stream);
snd_pcm_munmap_control(pcm, stream);
return err;
}
return 0;
}
+int snd_pcm_munmap_status(snd_pcm_t *pcm, int stream)
+{
+ int err;
+ snd_pcm_stream_t *str;
+ assert(pcm);
+ assert(stream >= 0 && stream <= 1);
+ str = &pcm->stream[stream];
+ assert(str->mmap_status);
+ if ((err = pcm->ops->munmap_status(pcm, stream, str->mmap_status)) < 0)
+ return err;
+ str->mmap_status = 0;
+ return 0;
+}
+
int snd_pcm_munmap_control(snd_pcm_t *pcm, int stream)
{
int err;
assert(stream >= 0 && stream <= 1);
str = &pcm->stream[stream];
assert(str->mmap_control);
- if ((err = pcm->ops->munmap_control(pcm, stream, str->mmap_control, str->mmap_control_size)) < 0)
+ if ((err = pcm->ops->munmap_control(pcm, stream, str->mmap_control)) < 0)
return err;
str->mmap_control = 0;
- str->mmap_control_size = 0;
return 0;
}
int snd_pcm_munmap(snd_pcm_t *pcm, int stream)
{
int err;
+ err = snd_pcm_munmap_status(pcm, stream);
+ if (err < 0)
+ return err;
err = snd_pcm_munmap_control(pcm, stream);
if (err < 0)
return err;
snd_pcm_stream_info_t slave_info;
snd_pcm_plugin_t *plugin;
snd_pcm_plug_t *plug;
- size_t bits;
- size_t bytes_align;
int err;
int stream = params->stream;
return snd_pcm_stream_params(plug->slave, params);
/* compute right sizes */
- bits = snd_pcm_format_physical_width(params->format.format) * params->format.channels;
- while (bits % 8 != 0)
- bits *= 2;
- bytes_align = bits / 8;
- params1.frag_size -= params1.frag_size % bytes_align;
slave_params.frag_size = snd_pcm_plug_slave_size(pcm, stream, params1.frag_size);
- params1.buffer_size -= params1.buffer_size % bytes_align;
slave_params.buffer_size = snd_pcm_plug_slave_size(pcm, stream, params1.buffer_size);
- params1.bytes_fill_max -= params1.bytes_fill_max % bytes_align;
- slave_params.bytes_fill_max = snd_pcm_plug_slave_size(pcm, stream, params1.bytes_fill_max);
- params1.bytes_min -= params1.bytes_min % bytes_align;
- slave_params.bytes_min = snd_pcm_plug_slave_size(pcm, stream, params1.bytes_min);
- params1.bytes_xrun_max -= params1.bytes_xrun_max % bytes_align;
- slave_params.bytes_xrun_max = snd_pcm_plug_slave_size(pcm, stream, params1.bytes_xrun_max);
- params1.bytes_align -= params1.bytes_align % bytes_align;
- slave_params.bytes_align = snd_pcm_plug_slave_size(pcm, stream, params1.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;
+ slave_params.frames_fill_max = snd_pcm_plug_slave_size(pcm, stream, params1.frames_fill_max);
+ slave_params.frames_min = snd_pcm_plug_slave_size(pcm, stream, params1.frames_min);
+ slave_params.frames_xrun_max = snd_pcm_plug_slave_size(pcm, stream, params1.frames_xrun_max);
+ slave_params.frames_align = snd_pcm_plug_slave_size(pcm, stream, params1.frames_align);
+ if (slave_params.frame_boundary == 0 || slave_params.frame_boundary > INT_MAX)
+ slave_params.frame_boundary = INT_MAX;
+ slave_params.frame_boundary /= params->buffer_size;
+ if (slave_params.frame_boundary > INT_MAX / slave_params.buffer_size)
+ slave_params.frame_boundary = INT_MAX;
else
- slave_params.byte_boundary *= slave_params.buffer_size;
+ slave_params.frame_boundary *= slave_params.buffer_size;
/*
* I/O plugins
return err;
if (snd_pcm_plug_direct(pcm, setup->stream))
return 0;
- setup->byte_boundary /= setup->frag_size;
+ setup->frame_boundary /= setup->frag_size;
setup->frag_size = snd_pcm_plug_client_size(pcm, setup->stream, setup->frag_size);
- setup->byte_boundary *= setup->frag_size;
+ setup->frame_boundary *= setup->frag_size;
setup->buffer_size = setup->frags * setup->frag_size;
- setup->bytes_min = snd_pcm_plug_client_size(pcm, setup->stream, setup->bytes_min);
- setup->bytes_align = snd_pcm_plug_client_size(pcm, setup->stream, setup->bytes_align);
- setup->bytes_xrun_max = snd_pcm_plug_client_size(pcm, setup->stream, setup->bytes_xrun_max);
- setup->bytes_fill_max = snd_pcm_plug_client_size(pcm, setup->stream, setup->bytes_fill_max);
+ setup->frames_min = snd_pcm_plug_client_size(pcm, setup->stream, setup->frames_min);
+ setup->frames_align = snd_pcm_plug_client_size(pcm, setup->stream, setup->frames_align);
+ setup->frames_xrun_max = snd_pcm_plug_client_size(pcm, setup->stream, setup->frames_xrun_max);
+ setup->frames_fill_max = snd_pcm_plug_client_size(pcm, setup->stream, setup->frames_fill_max);
plugstr = &plug->stream[setup->stream];
if (setup->stream == SND_PCM_STREAM_PLAYBACK)
if (snd_pcm_plug_direct(pcm, status->stream))
return 0;
- 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_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);
+ status->frame_io = snd_pcm_plug_client_size(pcm, status->stream, status->frame_io);
+ status->frame_data = snd_pcm_plug_client_size(pcm, status->stream, status->frame_data);
+ status->frames_avail = snd_pcm_plug_client_size(pcm, status->stream, status->frames_avail);
+ status->frames_avail_max = snd_pcm_plug_client_size(pcm, status->stream, status->frames_avail_max);
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)
+static int snd_pcm_plug_stream_frame_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);
+ return snd_pcm_stream_frame_io(plug->slave, stream, update);
}
static int snd_pcm_plug_stream_prepare(snd_pcm_t *pcm, int stream)
return -ENXIO;
}
-static ssize_t snd_pcm_plug_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
+static ssize_t snd_pcm_plug_stream_frame_data(snd_pcm_t *pcm, int stream, off_t offset)
{
ssize_t ret;
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_stream_seek(plug->slave, stream, offset);
+ return snd_pcm_stream_frame_data(plug->slave, stream, offset);
if (offset < 0) {
offset = snd_pcm_plug_slave_size(pcm, stream, -offset);
if (offset < 0)
if (offset < 0)
return offset;
}
- ret = snd_pcm_stream_seek(plug->slave, stream, offset);
+ ret = snd_pcm_stream_frame_data(plug->slave, stream, offset);
if (ret < 0)
return ret;
return snd_pcm_plug_client_size(pcm, stream, ret);
return snd_pcm_plug_read_transfer(pcm, channels, expected);
}
-static int snd_pcm_plug_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control, size_t csize UNUSED)
+static int snd_pcm_plug_mmap_status(snd_pcm_t *pcm, int stream, snd_pcm_mmap_status_t **status)
+{
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+ if (snd_pcm_plug_direct(pcm, stream))
+ return snd_pcm_mmap_status(plug->slave, stream, status);
+ return -EBADFD;
+}
+
+static int snd_pcm_plug_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
if (snd_pcm_plug_direct(pcm, stream))
return -EBADFD;
}
-static int snd_pcm_plug_munmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t *control UNUSED, size_t csize UNUSED)
+static int snd_pcm_plug_munmap_status(snd_pcm_t *pcm, int stream, snd_pcm_mmap_status_t *status UNUSED)
+{
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+ if (snd_pcm_plug_direct(pcm, stream))
+ return snd_pcm_munmap_status(plug->slave, stream);
+ return -EBADFD;
+}
+
+static int snd_pcm_plug_munmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t *control UNUSED)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
if (snd_pcm_plug_direct(pcm, stream))
stream_setup: snd_pcm_plug_stream_setup,
channel_setup: snd_pcm_plug_channel_setup,
stream_status: snd_pcm_plug_stream_status,
- stream_byte_io: snd_pcm_plug_stream_byte_io,
+ stream_frame_io: snd_pcm_plug_stream_frame_io,
stream_state: snd_pcm_plug_stream_state,
stream_prepare: snd_pcm_plug_stream_prepare,
stream_go: snd_pcm_plug_stream_go,
stream_drain: snd_pcm_plug_stream_drain,
stream_flush: snd_pcm_plug_stream_flush,
stream_pause: snd_pcm_plug_stream_pause,
- stream_seek: snd_pcm_plug_stream_seek,
+ stream_frame_data: snd_pcm_plug_stream_frame_data,
write: snd_pcm_plug_write,
writev: snd_pcm_plug_writev,
read: snd_pcm_plug_read,
readv: snd_pcm_plug_readv,
+ mmap_status: snd_pcm_plug_mmap_status,
mmap_control: snd_pcm_plug_mmap_control,
mmap_data: snd_pcm_plug_mmap_data,
+ munmap_status: snd_pcm_plug_munmap_status,
munmap_control: snd_pcm_plug_munmap_control,
munmap_data: snd_pcm_plug_munmap_data,
file_descriptor: snd_pcm_plug_file_descriptor,
size_t frames)
{
io_t *data;
- ssize_t result;
struct iovec *vec;
int count, channel;
vec = (struct iovec *)((char *)data + sizeof(*data));
if (plugin->stream == SND_PCM_STREAM_PLAYBACK) {
assert(src_channels);
- if ((result = snd_pcm_plugin_src_frames_to_size(plugin, frames)) < 0)
- return result;
count = plugin->src_format.channels;
if (plugin->src_format.interleave) {
- result = snd_pcm_write(data->slave, src_channels->area.addr, result);
+ return snd_pcm_write(data->slave, src_channels->area.addr, frames);
} else {
- result /= count;
for (channel = 0; channel < count; channel++) {
if (src_channels[channel].enabled)
vec[channel].iov_base = src_channels[channel].area.addr;
else
vec[channel].iov_base = 0;
- vec[channel].iov_len = result;
+ vec[channel].iov_len = frames;
}
- result = snd_pcm_writev(data->slave, vec, count);
+ return snd_pcm_writev(data->slave, vec, count);
}
- if (result < 0)
- return result;
- return snd_pcm_plugin_src_size_to_frames(plugin, result);
} else if (plugin->stream == SND_PCM_STREAM_CAPTURE) {
assert(dst_channels);
- if ((result = snd_pcm_plugin_dst_frames_to_size(plugin, frames)) < 0)
- return result;
count = plugin->dst_format.channels;
if (plugin->dst_format.interleave) {
- result = snd_pcm_read(data->slave, dst_channels->area.addr, result);
for (channel = 0; channel < count; channel++) {
dst_channels[channel].enabled = src_channels[channel].enabled;
}
+ return snd_pcm_read(data->slave, dst_channels->area.addr, frames);
} else {
- result /= count;
for (channel = 0; channel < count; channel++) {
dst_channels[channel].enabled = src_channels[channel].enabled;
if (dst_channels[channel].enabled)
vec[channel].iov_base = dst_channels[channel].area.addr;
else
vec[channel].iov_base = 0;
- vec[channel].iov_len = result;
+ vec[channel].iov_len = frames;
}
- result = snd_pcm_readv(data->slave, vec, count);
+ return snd_pcm_readv(data->slave, vec, count);
}
- if (result < 0)
- return result;
- return snd_pcm_plugin_dst_size_to_frames(plugin, result);
} else {
assert(0);
}
typedef struct mmap_private_data {
snd_pcm_t *slave;
- snd_pcm_mmap_control_t *control;
void *buffer;
#if 0
char *silence;
snd_pcm_channel_area_t *dv;
snd_pcm_stream_t *stream;
snd_pcm_stream_setup_t *setup;
- snd_pcm_mmap_control_t *ctrl;
size_t pos;
int ready;
unsigned int channel;
assert(plugin && channels);
data = (mmap_t *)plugin->extra_data;
- ctrl = data->control;
stream = &data->slave->stream[plugin->stream];
setup = &stream->setup;
- if (ctrl->state < SND_PCM_STATE_PREPARED)
+ if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) < SND_PCM_STATE_PREPARED)
return -EBADFD;
ready = snd_pcm_mmap_ready(data->slave, plugin->stream);
return ready;
if (!ready) {
struct pollfd pfd;
- if (ctrl->state != SND_PCM_STATE_RUNNING)
+ if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) != SND_PCM_STATE_RUNNING)
return -EPIPE;
if (stream->mode & SND_PCM_NONBLOCK)
return -EAGAIN;
return -EPIPE;
assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
}
- pos = ctrl->byte_data % setup->buffer_size;
- assert(pos % setup->bytes_align == 0);
- pos = (pos * 8) / stream->bits_per_frame;
+ pos = snd_pcm_mmap_frames_offset(data->slave, plugin->stream);
+ assert(pos % setup->frames_align == 0);
sv = plugin->src_channels;
dv = stream->channels;
snd_pcm_channel_area_t *sv;
snd_pcm_stream_t *stream;
snd_pcm_stream_setup_t *setup;
- snd_pcm_mmap_control_t *ctrl;
size_t pos;
int ready;
stream = &data->slave->stream[plugin->stream];
setup = &stream->setup;
- ctrl = data->control;
- if (ctrl->state < SND_PCM_STATE_PREPARED)
+ if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) < SND_PCM_STATE_PREPARED)
return -EBADFD;
- if (ctrl->state == SND_PCM_STATE_PREPARED &&
+ if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) == SND_PCM_STATE_PREPARED &&
stream->setup.start_mode == SND_PCM_START_DATA) {
err = snd_pcm_stream_go(data->slave, plugin->stream);
if (err < 0)
return ready;
if (!ready) {
struct pollfd pfd;
- if (ctrl->state != SND_PCM_STATE_RUNNING)
+ if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) != SND_PCM_STATE_RUNNING)
return -EPIPE;
if (stream->mode & SND_PCM_NONBLOCK)
return -EAGAIN;
return -EPIPE;
assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
}
- pos = ctrl->byte_data % setup->buffer_size;
- assert(pos % setup->bytes_align == 0);
- pos = (pos * 8) / stream->bits_per_frame;
+ pos = snd_pcm_mmap_frames_offset(data->slave, plugin->stream);
+ assert(pos % setup->frames_align == 0);
sv = stream->channels;
dv = plugin->dst_channels;
{
mmap_t *data;
snd_pcm_stream_setup_t *setup;
- snd_pcm_mmap_control_t *ctrl;
snd_pcm_stream_t *str;
int err;
assert(plugin && plugin->prev);
assert(src_channels);
data = (mmap_t *)plugin->extra_data;
- ctrl = data->control;
- assert(ctrl);
str = &data->slave->stream[SND_PCM_STREAM_PLAYBACK];
setup = &str->setup;
}
#endif
- snd_pcm_stream_seek(data->slave, SND_PCM_STREAM_PLAYBACK, frames * str->bits_per_frame / 8);
- if (ctrl->state == SND_PCM_STATE_PREPARED &&
+ snd_pcm_mmap_stream_frame_data(data->slave, SND_PCM_STREAM_PLAYBACK, frames);
+ if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) == SND_PCM_STATE_PREPARED &&
(str->setup.start_mode == SND_PCM_START_DATA ||
(str->setup.start_mode == SND_PCM_START_FULL &&
!snd_pcm_mmap_ready(data->slave, plugin->stream)))) {
size_t frames)
{
mmap_t *data;
- snd_pcm_mmap_control_t *ctrl;
snd_pcm_stream_t *str;
assert(plugin && plugin->next);
data = (mmap_t *)plugin->extra_data;
- ctrl = data->control;
- assert(ctrl);
str = &data->slave->stream[SND_PCM_STREAM_CAPTURE];
/* FIXME: not here the increment */
- snd_pcm_stream_seek(data->slave, SND_PCM_STREAM_CAPTURE, frames * str->bits_per_frame / 8);
+ snd_pcm_mmap_stream_frame_data(data->slave, SND_PCM_STREAM_CAPTURE, frames);
return frames;
}
snd_pcm_stream_setup_t *setup;
int result;
- if (data->control)
+ if (data->buffer) {
snd_pcm_munmap(data->slave, plugin->stream);
- result = snd_pcm_mmap(data->slave, plugin->stream, &data->control, (void **)&data->buffer);
+ data->buffer = 0;
+ }
+ result = snd_pcm_mmap(data->slave, plugin->stream, NULL, NULL, (void **)&data->buffer);
if (result < 0)
return result;
setup = &data->slave->stream[plugin->stream].setup;
if (data->silence)
free(data->silence);
#endif
- if (data->control)
+ if (data->buffer)
snd_pcm_munmap(data->slave, plugin->stream);
}
#ifdef GET_S16_END
while(0) {
-get_s16_xxx1_xx10: sample = (u_int32_t)as_u8(src) << 8; goto GET_S16_END;
-get_s16_xxx1_xx90: sample = (u_int32_t)(as_u8(src) ^ 0x80) << 8; goto GET_S16_END;
+get_s16_xxx1_xx10: sample = (u_int16_t)as_u8(src) << 8; goto GET_S16_END;
+get_s16_xxx1_xx90: sample = (u_int16_t)(as_u8(src) ^ 0x80) << 8; goto GET_S16_END;
get_s16_xx12_xx12: sample = as_u16(src); goto GET_S16_END;
get_s16_xx12_xx92: sample = as_u16(src) ^ 0x8000; goto GET_S16_END;
get_s16_xx12_xx21: sample = bswap_16(as_u16(src)); goto GET_S16_END;