]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Changed ALSA unit from bytes to frames. Splitted mmap control structs. Better midleve...
authorAbramo Bagnara <abramo@alsa-project.org>
Sat, 10 Jun 2000 12:39:51 +0000 (12:39 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Sat, 10 Jun 2000 12:39:51 +0000 (12:39 +0000)
13 files changed:
TODO
acinclude.m4
include/pcm.h
src/pcm/pcm.c
src/pcm/pcm_common.c
src/pcm/pcm_hw.c
src/pcm/pcm_local.h
src/pcm/pcm_misc.c
src/pcm/pcm_mmap.c
src/pcm/pcm_plug.c
src/pcm/plugin/io.c
src/pcm/plugin/mmap.c
src/pcm/plugin/plugin_ops.h

diff --git a/TODO b/TODO
index c57d605153f9877564da24a1367a5a831ec1d3a0..043d4ea2446cc7cbf636c0073612192f4170b60f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,4 +1,3 @@
-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)
index eda0abb3f7940616b965428d90519b3b074f4325..bc6600b3b998ea1ebd1786cade06959a01af425d 100644 (file)
@@ -16,7 +16,7 @@ void main(void)
 #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);
index c91d5c064bfbf54bb985200dde11835770adef47..689cdfd26c185a87055378763e2ea7de0fcb3d8f 100644 (file)
@@ -114,12 +114,10 @@ int snd_pcm_playback_pause(snd_pcm_t *handle, int enable);
 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);
@@ -129,10 +127,12 @@ const char *snd_pcm_get_format_description(int format);
 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);
@@ -150,8 +150,6 @@ ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels
 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,
@@ -163,6 +161,11 @@ int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_channels, size_t src_of
                       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 */
 
@@ -175,7 +178,6 @@ int snd_pcm_format_width(int format);                       /* in bits */
 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);
@@ -270,19 +272,8 @@ int snd_pcm_plug_remove_first(snd_pcm_t *handle, int stream);
 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
index f902a06ffea610af5f77df2fdae9536b3603c22d..a6083a13abf7bf5018f6cfc4ef3dd17e2d04e168 100644 (file)
@@ -68,6 +68,10 @@ int snd_pcm_stream_close(snd_pcm_t *pcm, int stream)
        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;
@@ -167,9 +171,8 @@ int snd_pcm_stream_setup(snd_pcm_t *pcm, snd_pcm_stream_setup_t *setup)
        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;
 }
@@ -209,33 +212,21 @@ int snd_pcm_stream_state(snd_pcm_t *pcm, int stream)
        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)
@@ -333,17 +324,20 @@ int snd_pcm_playback_pause(snd_pcm_t *pcm, int enable)
        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)
@@ -353,7 +347,7 @@ 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);
 }
 
@@ -372,7 +366,7 @@ ssize_t snd_pcm_read(snd_pcm_t *pcm, void *buffer, size_t 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);
 }
 
@@ -400,16 +394,6 @@ int snd_pcm_channels_mask(snd_pcm_t *pcm, int stream, bitset_t *client_vmask)
        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;
@@ -513,13 +497,13 @@ int snd_pcm_dump_setup(snd_pcm_t *pcm, int stream, FILE *fp)
        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;
 }
 
@@ -547,3 +531,42 @@ int snd_pcm_get_format_value(const char* name)
        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;
+}
index 8c3ce79de503812b91d8383da4addb229d21716f..6885f7cd06010379e0cb0b47bc1561009acb7ed0 100644 (file)
@@ -80,7 +80,7 @@ static ssize_t snd_pcm_plugin_side_channels(snd_pcm_plugin_t *plugin,
        *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);
@@ -194,51 +194,7 @@ int snd_pcm_plugin_free(snd_pcm_plugin_t *plugin)
        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;
        
@@ -266,7 +222,7 @@ ssize_t snd_pcm_plug_client_frames(snd_pcm_plugin_handle_t *handle, int stream,
        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;
@@ -302,81 +258,6 @@ ssize_t snd_pcm_plug_slave_frames(snd_pcm_plugin_handle_t *handle, int stream, s
        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 |
@@ -796,7 +677,6 @@ ssize_t snd_pcm_plug_client_channels_buf(snd_pcm_plugin_handle_t *handle,
        *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++) {
@@ -837,8 +717,7 @@ ssize_t snd_pcm_plug_client_channels_iovec(snd_pcm_plugin_handle_t *handle,
                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;
@@ -853,7 +732,6 @@ ssize_t snd_pcm_plug_client_channels_iovec(snd_pcm_plugin_handle_t *handle,
                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);
@@ -863,7 +741,7 @@ ssize_t snd_pcm_plug_client_channels_iovec(snd_pcm_plugin_handle_t *handle,
                        v->area.first = 0;
                        v->area.step = width;
                }
-               return len * nchannels;
+               return len;
        }
 }
 
@@ -1019,16 +897,13 @@ ssize_t snd_pcm_plug_write_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plu
 {
        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;
@@ -1058,24 +933,18 @@ ssize_t snd_pcm_plug_write_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plu
                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;
 
@@ -1119,7 +988,7 @@ ssize_t snd_pcm_plug_read_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plug
                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,
index 97c48547c268cff432ccc73e87a6ee0ed441b782..335f901bf9c3c72b5080df8e9a19e15d4739a36e 100644 (file)
@@ -136,11 +136,11 @@ static ssize_t snd_pcm_hw_stream_state(snd_pcm_t *pcm, int stream)
        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;
@@ -200,11 +200,15 @@ static int snd_pcm_hw_stream_pause(snd_pcm_t *pcm, int stream, int enable)
        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)
@@ -212,7 +216,10 @@ 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;
@@ -223,16 +230,10 @@ static ssize_t snd_pcm_hw_writev(snd_pcm_t *pcm, const struct iovec *vector, uns
        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;
@@ -243,7 +244,10 @@ static ssize_t snd_pcm_hw_read(snd_pcm_t *pcm, 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_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;
@@ -254,30 +258,36 @@ ssize_t snd_pcm_hw_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned lo
        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;
 }
 
@@ -295,9 +305,16 @@ static int snd_pcm_hw_mmap_data(snd_pcm_t *pcm, int stream, void **buffer, size_
        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;
 }
@@ -330,7 +347,7 @@ struct snd_pcm_ops snd_pcm_hw_ops = {
        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,
@@ -338,13 +355,15 @@ struct snd_pcm_ops snd_pcm_hw_ops = {
        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,
index 76cda9fad45151fe56bbe9d3e2344713acc449b1..6c4e62cbe28611ac728059150760ac9f850787bc 100644 (file)
@@ -38,15 +38,17 @@ struct snd_pcm_ops {
        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);
@@ -72,11 +74,10 @@ typedef struct {
        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;
@@ -132,19 +133,21 @@ int conv_index(int src_format, int dst_format);
 #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;
 }
 
index dd3cf6f31de99641cf4b06ba68b56c7542dde689..f2043bc7d0f880d14c11a210017271ea80861f01 100644 (file)
@@ -226,11 +226,6 @@ ssize_t snd_pcm_format_size(int format, size_t samples)
        }
 }
 
-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) {
@@ -314,49 +309,46 @@ u_int8_t snd_pcm_format_silence(int 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] = {
index 4749885dee2018c7b0926ba20ecc9a544de2d820..aa3bf0598d0650f20c117d823752f77a5f4836aa 100644 (file)
 #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;
 }
 
@@ -57,9 +43,9 @@ static int snd_pcm_mmap_playback_ready(snd_pcm_t *pcm)
 {
        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)
@@ -67,12 +53,12 @@ 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;
 }
@@ -80,13 +66,11 @@ static int snd_pcm_mmap_capture_ready(snd_pcm_t *pcm)
 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 {
@@ -94,48 +78,32 @@ int snd_pcm_mmap_ready(snd_pcm_t *pcm, int stream)
        }
 }
 
-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)
@@ -144,7 +112,7 @@ 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
@@ -154,60 +122,48 @@ ssize_t snd_pcm_mmap_frames_xfer(snd_pcm_t *pcm, int stream, size_t frames)
 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;
@@ -218,44 +174,45 @@ ssize_t snd_pcm_mmap_stream_seek(snd_pcm_t *pcm, int stream, off_t offset)
                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;
@@ -265,7 +222,7 @@ ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channel
                        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;
@@ -282,13 +239,13 @@ ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channel
                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)))) {
@@ -300,13 +257,13 @@ ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channel
        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);
@@ -315,31 +272,13 @@ ssize_t snd_pcm_mmap_write_frames(snd_pcm_t *pcm, const void *buffer, size_t fra
                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;
@@ -347,15 +286,15 @@ ssize_t snd_pcm_mmap_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned
        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;
@@ -372,16 +311,13 @@ ssize_t snd_pcm_mmap_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned
                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)
@@ -394,28 +330,29 @@ ssize_t snd_pcm_mmap_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned
                        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)
@@ -429,7 +366,7 @@ ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels
                        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;
@@ -446,10 +383,10 @@ ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels
                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;
@@ -457,13 +394,13 @@ ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels
        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);
@@ -472,31 +409,13 @@ ssize_t snd_pcm_mmap_read_frames(snd_pcm_t *pcm, const void *buffer, size_t fram
                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;
@@ -504,15 +423,15 @@ ssize_t snd_pcm_mmap_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned
        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;
@@ -529,16 +448,13 @@ ssize_t snd_pcm_mmap_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned
                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)
@@ -551,13 +467,33 @@ ssize_t snd_pcm_mmap_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned
                        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);
@@ -568,13 +504,11 @@ int snd_pcm_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **co
                        *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;
 }
 
@@ -601,11 +535,11 @@ int snd_pcm_mmap_get_areas(snd_pcm_t *pcm, int stream, snd_pcm_channel_area_t *a
                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)
@@ -652,20 +586,40 @@ int snd_pcm_mmap_data(snd_pcm_t *pcm, int stream, void **data)
        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;
@@ -674,10 +628,9 @@ int snd_pcm_munmap_control(snd_pcm_t *pcm, int stream)
        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;
 }
 
@@ -700,6 +653,9 @@ int snd_pcm_munmap_data(snd_pcm_t *pcm, int stream)
 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;
index ff60f9c2d1a805d1a9349ad0902dacf2756e6abf..8ff03b3c16c90558b14aa0e08098650bdb8d69ee 100644 (file)
@@ -334,8 +334,6 @@ static int snd_pcm_plug_stream_params(snd_pcm_t *pcm, snd_pcm_stream_params_t *p
        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;
        
@@ -367,29 +365,19 @@ static int snd_pcm_plug_stream_params(snd_pcm_t *pcm, snd_pcm_stream_params_t *p
                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
@@ -436,14 +424,14 @@ static int snd_pcm_plug_stream_setup(snd_pcm_t *pcm, snd_pcm_stream_setup_t *set
                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)
@@ -464,10 +452,10 @@ static int snd_pcm_plug_stream_status(snd_pcm_t *pcm, snd_pcm_stream_status_t *s
        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;       
 }
 
@@ -477,10 +465,10 @@ static int snd_pcm_plug_stream_state(snd_pcm_t *pcm, int stream)
        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)
@@ -559,12 +547,12 @@ static int snd_pcm_plug_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channe
        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)
@@ -575,7 +563,7 @@ static ssize_t snd_pcm_plug_stream_seek(snd_pcm_t *pcm, int stream, off_t offset
                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);
@@ -677,7 +665,15 @@ ssize_t snd_pcm_plug_read(snd_pcm_t *pcm, void *buf, size_t count)
        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))
@@ -693,7 +689,15 @@ static int snd_pcm_plug_mmap_data(snd_pcm_t *pcm, int stream, void **buffer, siz
        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))
@@ -736,7 +740,7 @@ struct snd_pcm_ops snd_pcm_plug_ops = {
        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,
@@ -744,13 +748,15 @@ struct snd_pcm_ops snd_pcm_plug_ops = {
        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,
index afdd5732e1eb83455495812e5f84e3ca2abced19..d7c7e4b8a5d7f4848168c8a70921637c6453b4fd 100644 (file)
@@ -51,7 +51,6 @@ static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
                              size_t frames)
 {
        io_t *data;
-       ssize_t result;
        struct iovec *vec;
        int count, channel;
 
@@ -61,50 +60,38 @@ static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
        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);
        }
index 4db2b6657d1abc0f11db8c11fc082eb5495c7f54..2f46bd9b1af4d7d92b0b1fcafa16b99a341c25d8 100644 (file)
@@ -35,7 +35,6 @@
  
 typedef struct mmap_private_data {
        snd_pcm_t *slave;
-       snd_pcm_mmap_control_t *control;
        void *buffer;
 #if 0
        char *silence;
@@ -52,18 +51,16 @@ static ssize_t mmap_src_channels(snd_pcm_plugin_t *plugin,
        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);
@@ -71,7 +68,7 @@ static ssize_t mmap_src_channels(snd_pcm_plugin_t *plugin,
                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;
@@ -84,9 +81,8 @@ static ssize_t mmap_src_channels(snd_pcm_plugin_t *plugin,
                        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;
@@ -119,7 +115,6 @@ static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
        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;
 
@@ -128,10 +123,9 @@ static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
        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)
@@ -142,7 +136,7 @@ static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
                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;
@@ -155,9 +149,8 @@ static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
                        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;
@@ -182,15 +175,12 @@ static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
 {
        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;
 
@@ -201,8 +191,8 @@ static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
        }
 #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)))) {
@@ -219,17 +209,14 @@ static ssize_t mmap_capture_transfer(snd_pcm_plugin_t *plugin,
                                     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;
 }
@@ -246,9 +233,11 @@ static int mmap_action(snd_pcm_plugin_t *plugin,
                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;
@@ -276,7 +265,7 @@ static void mmap_free(snd_pcm_plugin_t *plugin, void *private_data UNUSED)
        if (data->silence)
                free(data->silence);
 #endif
-       if (data->control)
+       if (data->buffer)
                snd_pcm_munmap(data->slave, plugin->stream);
 }
  
index e97178df2c43730614e518b3b046c52c4af374e4..ed91a2c1b3481a50ed9cdb5cea5651680261d407 100644 (file)
@@ -304,8 +304,8 @@ static void *get_s16_labels[4 * 2 * 2] = {
 
 #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;